Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 29477
Collapse All | Expand All

(-)xmms-old/Input/mpg123/Makefile.am (-2 / +2 lines)
Lines 6-16 Link Here
6
COMMON_SRC = mpg123.c configure.c fileinfo.c common.c \
6
COMMON_SRC = mpg123.c configure.c fileinfo.c common.c \
7
decode_2to1.c decode_4to1.c \
7
decode_2to1.c decode_4to1.c \
8
layer1.c layer2.c layer3.c \
8
layer1.c layer2.c layer3.c \
9
tabinit.c equalizer.c http.c \
9
tabinit.c equalizer.c http.c voladjust.c \
10
huffman.h mpg123.h l2tables.h getbits.h \
10
huffman.h mpg123.h l2tables.h getbits.h \
11
dxhead.c dxhead.h \
11
dxhead.c dxhead.h \
12
id3.c id3.h id3_frame.c id3_frame_content.c id3_frame_text.c \
12
id3.c id3.h id3_frame.c id3_frame_content.c id3_frame_text.c \
13
id3_frame_url.c id3_header.h id3_tag.c
13
id3_frame_url.c id3_frame_volume.c id3_header.h id3_tag.c
14
14
15
if ARCH_X86
15
if ARCH_X86
16
16
(-)xmms-old/Input/mpg123/configure.c (+88 lines)
Lines 27-32 Link Here
27
static GtkWidget *streaming_proxy_hbox, *streaming_proxy_auth_hbox, *streaming_save_dirbrowser;
27
static GtkWidget *streaming_proxy_hbox, *streaming_proxy_auth_hbox, *streaming_save_dirbrowser;
28
static GtkWidget *streaming_save_hbox, *title_id3_box, *title_tag_desc;
28
static GtkWidget *streaming_save_hbox, *title_id3_box, *title_tag_desc;
29
static GtkWidget *title_override, *title_id3_entry, *title_id3v2_disable;
29
static GtkWidget *title_override, *title_id3_entry, *title_id3v2_disable;
30
static GtkWidget *volume_rva2_enable, *volume_boost_enable, *volume_dither_enable;
31
static GtkWidget *volume_gain_label, *volume_clip_frame;
32
static GtkWidget *volume_limiter_enable, *volume_reducegain_enable;
33
static gchar volume_gaintext[24];
30
34
31
MPG123Config mpg123_cfg;
35
MPG123Config mpg123_cfg;
32
36
Lines 105-110 Link Here
105
	mpg123_cfg.disable_id3v2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_id3v2_disable));
109
	mpg123_cfg.disable_id3v2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_id3v2_disable));
106
	g_free(mpg123_cfg.id3_format);
110
	g_free(mpg123_cfg.id3_format);
107
	mpg123_cfg.id3_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_id3_entry)));
111
	mpg123_cfg.id3_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_id3_entry)));
112
	mpg123_cfg.use_rva2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(volume_rva2_enable));
113
	mpg123_cfg.use_boost = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(volume_boost_enable));
114
	mpg123_cfg.enable_dither = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(volume_dither_enable));
115
	if (GTK_TOGGLE_BUTTON(volume_limiter_enable)->active)
116
		mpg123_cfg.anticlip_mode = 0;
117
	else if (GTK_TOGGLE_BUTTON(volume_reducegain_enable)->active)
118
		mpg123_cfg.anticlip_mode = 1;
119
	mpg123_voladjust_update(NULL);
108
120
109
	filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
121
	filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
110
	cfg = xmms_cfg_open_file(filename);
122
	cfg = xmms_cfg_open_file(filename);
Lines 135-140 Link Here
135
	xmms_cfg_write_boolean(cfg, "MPG123", "disable_id3v2", mpg123_cfg.disable_id3v2);
147
	xmms_cfg_write_boolean(cfg, "MPG123", "disable_id3v2", mpg123_cfg.disable_id3v2);
136
	xmms_cfg_write_string(cfg, "MPG123", "id3_format", mpg123_cfg.id3_format);
148
	xmms_cfg_write_string(cfg, "MPG123", "id3_format", mpg123_cfg.id3_format);
137
	xmms_cfg_write_int(cfg, "MPG123", "detect_by", mpg123_cfg.detect_by);
149
	xmms_cfg_write_int(cfg, "MPG123", "detect_by", mpg123_cfg.detect_by);
150
	xmms_cfg_write_boolean(cfg, "MPG123", "use_rva2", mpg123_cfg.use_rva2);
151
	xmms_cfg_write_boolean(cfg, "MPG123", "use_boost", mpg123_cfg.use_boost);
152
	xmms_cfg_write_boolean(cfg, "MPG123", "enable_dither", mpg123_cfg.enable_dither);
153
	xmms_cfg_write_int(cfg, "MPG123", "anticlip_mode", mpg123_cfg.anticlip_mode);
138
#ifdef USE_SIMD
154
#ifdef USE_SIMD
139
	xmms_cfg_write_int(cfg, "MPG123", "default_synth", mpg123_cfg.default_synth);
155
	xmms_cfg_write_int(cfg, "MPG123", "default_synth", mpg123_cfg.default_synth);
140
#endif
156
#endif
Lines 212-217 Link Here
212
	gtk_widget_set_sensitive(title_tag_desc, override);
228
	gtk_widget_set_sensitive(title_tag_desc, override);
213
}
229
}
214
230
231
static void volume_rva2_cb(GtkWidget * w, gpointer data)
232
{
233
	gboolean rva2_on;
234
	rva2_on = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(volume_rva2_enable));
235
	gtk_widget_set_sensitive(volume_boost_enable, rva2_on);
236
	gtk_widget_set_sensitive(volume_dither_enable, rva2_on);
237
	gtk_widget_set_sensitive(volume_clip_frame, rva2_on);
238
	gtk_widget_set_sensitive(volume_gain_label, rva2_on);
239
}
240
215
static void configure_destroy(GtkWidget * w, gpointer data)
241
static void configure_destroy(GtkWidget * w, gpointer data)
216
{
242
{
217
	if (streaming_save_dirbrowser)
243
	if (streaming_save_dirbrowser)
Lines 230-235 Link Here
230
	GtkWidget *streaming_save_label, *streaming_save_browse;
256
	GtkWidget *streaming_save_label, *streaming_save_browse;
231
	GtkWidget *streaming_cast_frame, *streaming_cast_vbox;
257
	GtkWidget *streaming_cast_frame, *streaming_cast_vbox;
232
	GtkWidget *title_frame, *title_id3_vbox, *title_id3_label;
258
	GtkWidget *title_frame, *title_id3_vbox, *title_id3_label;
259
	GtkWidget *volume_frame, *volume_vbox, *volume_clip_vbox;
233
	GtkWidget *bbox, *ok, *cancel;
260
	GtkWidget *bbox, *ok, *cancel;
234
261
235
	char *temp;
262
	char *temp;
Lines 578-583 Link Here
578
	gtk_box_pack_start(GTK_BOX(title_id3_vbox), title_tag_desc, FALSE, FALSE, 0);
605
	gtk_box_pack_start(GTK_BOX(title_id3_vbox), title_tag_desc, FALSE, FALSE, 0);
579
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title")));
606
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title")));
580
607
608
	/*
609
	 * Volume adjustment config
610
	 */
611
	volume_frame = gtk_frame_new(_("Volume Adjustment:"));
612
	gtk_container_border_width(GTK_CONTAINER(volume_frame), 5);
613
614
	volume_vbox = gtk_vbox_new(FALSE, 10);
615
	gtk_container_border_width(GTK_CONTAINER(volume_vbox), 5);
616
	gtk_container_add(GTK_CONTAINER(volume_frame), volume_vbox);
617
618
	volume_rva2_enable = gtk_check_button_new_with_label(_("Enable ID3 relative volume adjust"));
619
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volume_rva2_enable),
620
				     mpg123_cfg.use_rva2);
621
	gtk_signal_connect(GTK_OBJECT(volume_rva2_enable), "clicked", volume_rva2_cb, NULL);
622
	gtk_box_pack_start(GTK_BOX(volume_vbox), volume_rva2_enable, FALSE, FALSE, 0);
623
624
	volume_boost_enable = gtk_check_button_new_with_label(_("Enable 6dB boost"));
625
	gtk_widget_set_sensitive(volume_boost_enable, mpg123_cfg.use_rva2);
626
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volume_boost_enable),
627
				     mpg123_cfg.use_boost);
628
	gtk_box_pack_start(GTK_BOX(volume_vbox), volume_boost_enable, FALSE, FALSE, 0);
629
630
	volume_dither_enable = gtk_check_button_new_with_label(_("Enable dithering"));
631
	gtk_widget_set_sensitive(volume_dither_enable, mpg123_cfg.use_rva2);
632
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volume_dither_enable),
633
				     mpg123_cfg.enable_dither);
634
	gtk_box_pack_start(GTK_BOX(volume_vbox), volume_dither_enable, FALSE, FALSE, 0);
635
636
	volume_clip_frame = gtk_frame_new(_("Clipping Prevention:"));
637
	gtk_widget_set_sensitive(volume_clip_frame, mpg123_cfg.use_rva2);
638
	gtk_container_border_width(GTK_CONTAINER(volume_clip_frame), 5);
639
640
	volume_clip_vbox = gtk_vbox_new(FALSE, 10);
641
	gtk_container_border_width(GTK_CONTAINER(volume_clip_vbox), 5);
642
	gtk_container_add(GTK_CONTAINER(volume_clip_frame), volume_clip_vbox);
643
644
	volume_limiter_enable = gtk_radio_button_new_with_label(NULL, _("Use limiter"));
645
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volume_limiter_enable),
646
				     mpg123_cfg.anticlip_mode == 0);
647
	gtk_box_pack_start(GTK_BOX(volume_clip_vbox), volume_limiter_enable, FALSE, FALSE, 0);
648
649
	volume_reducegain_enable = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(volume_limiter_enable)), _("Reduce gain"));
650
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(volume_reducegain_enable),
651
				     mpg123_cfg.anticlip_mode == 1);
652
	gtk_box_pack_start(GTK_BOX(volume_clip_vbox), volume_reducegain_enable, FALSE, FALSE, 0);
653
654
	gtk_box_pack_start(GTK_BOX(volume_vbox), volume_clip_frame, FALSE, FALSE, 0);
655
656
	if (fabs(mpg123_current_gain) < 0.0001)
657
		strcpy(volume_gaintext, _("Current gain: none"));
658
	else
659
		g_snprintf(volume_gaintext, 24, _("Current gain: %0.2fdB"),
660
			   mpg123_current_gain);
661
	volume_gain_label = gtk_label_new(volume_gaintext);
662
	gtk_widget_set_sensitive(volume_gain_label, mpg123_cfg.use_rva2);
663
	gtk_box_pack_end(GTK_BOX(volume_vbox), volume_gain_label, FALSE, FALSE, 0);
664
665
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), volume_frame, gtk_label_new(_("Volume")));
666
667
668
581
	bbox = gtk_hbutton_box_new();
669
	bbox = gtk_hbutton_box_new();
582
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
670
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
583
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
671
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
(-)xmms-old/Input/mpg123/id3.h (+37 lines)
Lines 140-145 Link Here
140
140
141
141
142
/*
142
/*
143
 * Structure describing volume adjustment info in an RVA2 frame.
144
 */
145
struct id3_gain {
146
    struct {
147
148
	/* gain in decibels */
149
	float ch_gain;
150
151
	/* We shift peak values to be 32 bits, e.g. a 17-bit peak is
152
	 * left shifted 15 (the low 15 bits are padded with zero).
153
	 * This way, we can always treat the peak as being out of 32
154
	 * bits.  RVA2 peak values can be up to 255 bits, but the high
155
	 * 32 bits should more than suffice for us. */
156
	guint32 ch_peak;
157
158
    } channel[9];
159
};
160
161
/*
162
 * These are both RVA2 channel type numbers, and indexes into the
163
 * channel element of struct id3_gain.
164
 */
165
#define ID3_CHANNEL_OTHER   0x00
166
#define ID3_CHANNEL_MASTER  0x01
167
#define ID3_CHANNEL_FRIGHT  0x02
168
#define ID3_CHANNEL_FLEFT   0x03
169
#define ID3_CHANNEL_BRIGHT  0x04
170
#define ID3_CHANNEL_BLEFT   0x05
171
#define ID3_CHANNEL_FCENTER 0x06
172
#define ID3_CHANNEL_BCENTER 0x07
173
#define ID3_CHANNEL_SUB     0x08
174
175
176
/*
143
 * Text encodings.
177
 * Text encodings.
144
 */
178
 */
145
#define ID3_ENCODING_ISO_8859_1	0x00
179
#define ID3_ENCODING_ISO_8859_1	0x00
Lines 359-364 Link Here
359
char *id3_get_url(struct id3_frame *);
393
char *id3_get_url(struct id3_frame *);
360
char *id3_get_url_desc(struct id3_frame *);
394
char *id3_get_url_desc(struct id3_frame *);
361
395
396
/* From id3_frame_volume.c */
397
int id3_get_rva2_gain(struct id3_frame *frame, struct id3_gain *gn);
398
362
/* From id3_tag.c */
399
/* From id3_tag.c */
363
void id3_init_tag(struct id3_tag *id3);
400
void id3_init_tag(struct id3_tag *id3);
364
int id3_read_tag(struct id3_tag *id3);
401
int id3_read_tag(struct id3_tag *id3);
(-)xmms-old/Input/mpg123/id3_frame_volume.c (+144 lines)
Line 0 Link Here
1
/*********************************************************************
2
 * 
3
 * Filename:      id3_frame_volume.c
4
 * Description:   Code for handling ID3 relative volume adjust frames.
5
 * Author:        Chris Vaill <cvaill@cs.columbia.edu>
6
 * Created at:    Thu Sep 26 23:57:00 2002
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 * 
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 * 
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 * 
22
 ********************************************************************/
23
#include <stdio.h>
24
#include <string.h>
25
26
#include "id3.h"
27
28
29
/* Assume buf points to the beginning of one channel's data in an RVA2
30
 * frame.  Return the encoded gain, in decibels. */
31
static float decode_rva2_gain(const char *buf)
32
{
33
    int gain_fp; /* fixed-point */
34
35
    gain_fp = *(signed char *)(buf + 1) << 8; /* first byte of gain */
36
    gain_fp |= *(unsigned char *)(buf + 2);   /* second byte of gain */
37
38
    return gain_fp / 512.0;
39
}
40
41
42
/* Assume buf points to the beginning of one channel's peak data in an
43
 * RVA2 frame (i.e. the fourth byte in the channel's data).  Return
44
 * the encoded peak, shifted to be a 32-bit value. */
45
static guint32 decode_rva2_peak(const unsigned char *buf)
46
{
47
    unsigned int peakbits = (unsigned int)*buf++;
48
    int shift, peakbytes;
49
    guint32 peak = 0;
50
51
    /* fast path for the common case */
52
    if (peakbits == 16)
53
	return (buf[0] << 24) + (buf[1] << 16);
54
55
    /*
56
     * We only care about the high 32 bits, so we care about the first
57
     * 5 bytes, because unfortunately, sizes that are not whole bytes
58
     * are padded on the msb side.
59
     *
60
     * e.g. a 33 bit peak has its first 7 bits zeroed, followed by 1
61
     * bit and four bytes of peak data.  We take the first four bytes
62
     * and shift left by 7, giving us 25 bits total.  We then take the
63
     * top 7 bits of the fifth byte to get our full 32 bits.
64
     */
65
    peakbytes = (peakbits + 7) >> 3;
66
    if (peakbytes > 4)
67
	peakbytes = 4;
68
    shift = ((8 - (peakbits & 7)) & 7) + (4 - peakbytes) * 8;
69
70
    /* get up to the first 4 bytes of the peak... */
71
    for (; peakbytes; peakbytes--) {
72
	peak <<= 8;
73
	peak += (unsigned int)*buf++;
74
    }
75
76
    /* ...and shift, so the value is out of 32 bits... */
77
    peak <<= shift;
78
79
    /* ...and finally, add part of the fifth byte, if necessary */
80
    if (peakbits > 32)
81
	peak += (unsigned int)*buf >> (8 - shift);
82
83
    return peak;
84
}
85
86
87
/*
88
 * Function id3_get_rva2_gain (frame)
89
 *
90
 *    Get the gain and peak info, that is coded in the RVA2 frame, and
91
 *    return it in the gn struct.  Return 0, or -1 on error.
92
 */
93
int id3_get_rva2_gain(struct id3_frame *frame, struct id3_gain *gn)
94
{
95
    const unsigned char *data;
96
    float gain;
97
    int i, chan, peakbytes;
98
    guint32 peak;
99
100
    /* Type check */
101
    if (frame->fr_desc->fd_id != ID3_RVA2)
102
	return -1;
103
104
    /* Check if frame is compressed */
105
    if (id3_decompress_frame(frame) == -1)
106
	return -1;
107
108
    /* init gains and peaks to 0 */
109
    memset(gn, 0, sizeof(struct id3_gain));
110
111
    data = (char *)frame->fr_data;
112
113
    /* skip past identification string */
114
    for (i = 0; i < frame->fr_size; i++)
115
	if (data[i] == '\0')
116
	    break;
117
    if (i >= frame->fr_size)
118
	return -1; /* ident string not terminated; bad frame data */
119
120
    /* cycle through channel fields */
121
    i++;
122
    while (i + 3 < frame->fr_size) {
123
124
	chan = data[i];
125
126
	/* decode the gain for this channel */
127
	gain = decode_rva2_gain(data + i);
128
	i += 3;
129
130
	/* decode the peak for this channel */
131
	peakbytes = (data[i] + 7) / 8;
132
	if (i + peakbytes >= frame->fr_size)
133
	    break;
134
	peak = decode_rva2_peak(data + i);
135
	i += 1 + peakbytes;
136
137
	if (chan <= 8) {
138
	    gn->channel[chan].ch_gain = gain;
139
	    gn->channel[chan].ch_peak = peak;
140
	}
141
    }
142
143
    return 0;
144
}
(-)xmms-old/Input/mpg123/layer1.c (+3 lines)
Lines 176-182 Link Here
176
			while (mpg123_ip.output->buffer_free() < mpg123_pcm_point && mpg123_info->going && mpg123_info->jump_to_time == -1)
176
			while (mpg123_ip.output->buffer_free() < mpg123_pcm_point && mpg123_info->going && mpg123_info->jump_to_time == -1)
177
				xmms_usleep(10000);
177
				xmms_usleep(10000);
178
			if (mpg123_info->going && mpg123_info->jump_to_time == -1)
178
			if (mpg123_info->going && mpg123_info->jump_to_time == -1)
179
			{
180
				mpg123_voladjust(mpg123_pcm_sample, mpg123_pcm_point);
179
				mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
181
				mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
182
			}
180
		}
183
		}
181
		mpg123_pcm_point = 0;
184
		mpg123_pcm_point = 0;
182
	}
185
	}
(-)xmms-old/Input/mpg123/layer2.c (+3 lines)
Lines 330-336 Link Here
330
		while (mpg123_ip.output->buffer_free() < mpg123_pcm_point && mpg123_info->going && mpg123_info->jump_to_time == -1)
330
		while (mpg123_ip.output->buffer_free() < mpg123_pcm_point && mpg123_info->going && mpg123_info->jump_to_time == -1)
331
			xmms_usleep(10000);
331
			xmms_usleep(10000);
332
		if (mpg123_info->going && mpg123_info->jump_to_time == -1)
332
		if (mpg123_info->going && mpg123_info->jump_to_time == -1)
333
		{
334
			mpg123_voladjust(mpg123_pcm_sample, mpg123_pcm_point);
333
			mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
335
			mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
336
		}
334
		
337
		
335
338
336
	}
339
	}
(-)xmms-old/Input/mpg123/layer3.c (+3 lines)
Lines 1947-1953 Link Here
1947
			       mpg123_info->going && mpg123_info->jump_to_time == -1)
1947
			       mpg123_info->going && mpg123_info->jump_to_time == -1)
1948
				xmms_usleep(10000);
1948
				xmms_usleep(10000);
1949
			if (mpg123_info->going && mpg123_info->jump_to_time == -1)
1949
			if (mpg123_info->going && mpg123_info->jump_to_time == -1)
1950
			{
1951
				mpg123_voladjust(mpg123_pcm_sample, mpg123_pcm_point);
1950
				mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
1952
				mpg123_ip.output->write_audio(mpg123_pcm_sample, mpg123_pcm_point);
1953
			}
1951
		}
1954
		}
1952
		mpg123_pcm_point = 0;
1955
		mpg123_pcm_point = 0;
1953
	}
1956
	}
(-)xmms-old/Input/mpg123/mpg123.c (+6 lines)
Lines 200-205 Link Here
200
	if (!xmms_cfg_read_string(cfg, "MPG123", "id3_format", &mpg123_cfg.id3_format))
200
	if (!xmms_cfg_read_string(cfg, "MPG123", "id3_format", &mpg123_cfg.id3_format))
201
		mpg123_cfg.id3_format = g_strdup("%p - %t");
201
		mpg123_cfg.id3_format = g_strdup("%p - %t");
202
	xmms_cfg_read_int(cfg, "MPG123", "detect_by", &mpg123_cfg.detect_by);
202
	xmms_cfg_read_int(cfg, "MPG123", "detect_by", &mpg123_cfg.detect_by);
203
	xmms_cfg_read_boolean(cfg, "MPG123", "use_rva2", &mpg123_cfg.use_rva2);
204
        xmms_cfg_read_boolean(cfg, "MPG123", "use_boost", &mpg123_cfg.use_boost);
205
	xmms_cfg_read_boolean(cfg, "MPG123", "enable_dither", &mpg123_cfg.enable_dither);
206
	xmms_cfg_read_boolean(cfg, "MPG123", "anticlip_mode", &mpg123_cfg.anticlip_mode);
203
	xmms_cfg_read_int(cfg, "MPG123", "default_synth", &mpg123_cfg.default_synth);
207
	xmms_cfg_read_int(cfg, "MPG123", "default_synth", &mpg123_cfg.default_synth);
204
208
205
	xmms_cfg_free(cfg);
209
	xmms_cfg_free(cfg);
Lines 920-925 Link Here
920
				mpg123_info->num_frames * mpg123_info->tpf * 1000;
924
				mpg123_info->num_frames * mpg123_info->tpf * 1000;
921
			if (!mpg123_title)
925
			if (!mpg123_title)
922
				mpg123_title = get_song_title(NULL,filename);
926
				mpg123_title = get_song_title(NULL,filename);
927
			mpg123_voladjust_update(filename);
923
		}
928
		}
924
		else
929
		else
925
		{
930
		{
Lines 1076-1081 Link Here
1076
	g_free(mpg123_pcm_sample);
1081
	g_free(mpg123_pcm_sample);
1077
	mpg123_filename = NULL;
1082
	mpg123_filename = NULL;
1078
	g_free(filename);
1083
	g_free(filename);
1084
	mpg123_voladjust_cleanup();
1079
	pthread_exit(NULL);
1085
	pthread_exit(NULL);
1080
}
1086
}
1081
1087
(-)xmms-old/Input/mpg123/mpg123.h (+7 lines)
Lines 157-162 Link Here
157
	gchar *id3_format;
157
	gchar *id3_format;
158
	gboolean title_override, disable_id3v2;
158
	gboolean title_override, disable_id3v2;
159
	int detect_by;
159
	int detect_by;
160
	gboolean use_rva2, use_boost, enable_dither;
161
	gint anticlip_mode;
160
	int default_synth;
162
	int default_synth;
161
}
163
}
162
MPG123Config;
164
MPG123Config;
Lines 300-305 Link Here
300
gchar *mpg123_format_song_title(struct id3tag_t *tag, gchar *filename);
302
gchar *mpg123_format_song_title(struct id3tag_t *tag, gchar *filename);
301
double mpg123_relative_pos(void);
303
double mpg123_relative_pos(void);
302
304
305
extern float mpg123_current_gain;
306
void mpg123_voladjust_cleanup(void);
307
void mpg123_voladjust_update(char *filename);
308
void mpg123_voladjust(void *ptr, int length);
309
303
310
304
311
305
extern unsigned char *mpg123_conv16to8;
312
extern unsigned char *mpg123_conv16to8;
(-)xmms-old/Input/mpg123/voladjust.c (+356 lines)
Line 0 Link Here
1
#include "mpg123.h"
2
#include <string.h>
3
#include <stdlib.h>
4
5
6
#define ROUND(x) ((int)floor((x) + 0.5))
7
8
extern gchar *mpg123_filename;
9
10
float mpg123_current_gain = 0.0;
11
12
/* lookup table for fast gain adjustments */
13
static gint32 *volume_lut = NULL;
14
static struct id3_gain gain_info;
15
static int adjusting = FALSE;
16
17
/* track details of the lookup table, so we only rebuild if we need to */
18
static struct {
19
	AFormat lut_fmt;
20
	float   lut_gain;
21
	int     lut_limit;
22
	int     lut_boost;
23
} lut_data;
24
25
/*
26
 * A buffer of 8192 random numbers makes the period of the noise about
27
 * 85 ms, or 11.7 Hz, for 48 kHz stereo.  This should be low enough to
28
 * be unrecognizable except as noise.
29
 */
30
#define NOISEBUF_SZ 8192
31
static char *noisebuf;
32
static int noisebufi = 0;
33
34
/*
35
 * Returns 8 random bits, ie a number from -128 to +127.
36
 * Used for dithering.
37
 */
38
static int
39
rand8(void)
40
{
41
  int retval = (int)noisebuf[noisebufi];
42
  noisebufi = (noisebufi + 1) % NOISEBUF_SZ;
43
  return retval;
44
}
45
46
47
/*
48
 * Limiter function:
49
 *
50
 *        / tanh((x + lev) / (1-lev)) * (1-lev) - lev        (for x < -lev)
51
 *        |
52
 *   x' = | x                                                (for |x| <= lev)
53
 *        |
54
 *        \ tanh((x - lev) / (1-lev)) * (1-lev) + lev        (for x > lev)
55
 *
56
 * With limiter level = 0, this is equivalent to a tanh() function;
57
 * with limiter level = 1, this is equivalent to clipping.
58
 */
59
#define lmtr_lvl 0.5
60
static double
61
limiter(double x)
62
{
63
	double xp;
64
65
	if (x < -lmtr_lvl)
66
		xp = tanh((x + lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) - lmtr_lvl;
67
	else if (x <= lmtr_lvl)
68
		xp = x;
69
	else
70
		xp = tanh((x - lmtr_lvl) / (1-lmtr_lvl)) * (1-lmtr_lvl) + lmtr_lvl;
71
72
	return xp;
73
}
74
75
76
void mpg123_voladjust_cleanup(void)
77
{
78
	adjusting = FALSE;
79
	if (noisebuf)
80
		g_free(noisebuf);
81
	noisebuf = NULL;
82
	if (volume_lut)
83
		g_free(volume_lut - 0x8000);
84
	volume_lut = NULL;
85
	return;
86
}
87
88
89
static void update_dither(void)
90
{
91
	int i;
92
93
	if (mpg123_cfg.use_rva2 && mpg123_cfg.enable_dither)
94
	{
95
		/* fill the noise buffer, which we will cycle through
96
		   when dithering */
97
		if (noisebuf == NULL) {
98
			noisebuf = g_malloc(NOISEBUF_SZ);
99
			for (i = 0; i < (NOISEBUF_SZ / sizeof(int)); i++)
100
				((int *)noisebuf)[i] = rand();
101
			noisebufi = 0;
102
			/* Note: noise shaping on the dithering noise
103
			   is not implemented, but this would be the
104
			   place to do it */
105
		}
106
	}
107
	else
108
	{
109
		if (noisebuf)
110
			g_free(noisebuf);
111
		noisebuf = NULL;
112
	}
113
}
114
115
116
static int gain_from_id3_tag(char *filename, struct id3_gain *gn)
117
{
118
	FILE *file;
119
	struct id3_tag *id3d;
120
	struct id3_frame *id3frm;
121
122
	file = fopen(filename, "rb");
123
	if (file == NULL)
124
		goto err_out;
125
126
	id3d = id3_open_fp(file, 0);
127
	if (id3d == NULL)
128
		goto err_closefile;
129
130
	id3frm = id3_get_frame(id3d, ID3_RVA2, 1);
131
	if (id3frm == NULL)
132
		goto err_closeid3;
133
134
	if (id3_get_rva2_gain(id3frm, gn) == -1)
135
		goto err_closeid3;
136
137
	id3_close(id3d);
138
	fclose(file);
139
	return 1;
140
141
 err_closeid3:
142
	id3_close(id3d);
143
 err_closefile:
144
	fclose(file);
145
 err_out:
146
	memset(gn, 0, sizeof(struct id3_gain));
147
	return 0;
148
}
149
150
151
void mpg123_voladjust_update(char *filename)
152
{
153
	struct id3_gain newgain;
154
	float gain_db, gain_mult, scale;
155
	int i, use_boost, use_limiter = TRUE, need_update = FALSE;
156
	int samplemin, samplemax, center;
157
	int lut_samplemin, lut_samplemax, lut_center;
158
	AFormat fmt;
159
	guint32 peak;
160
161
	if (!mpg123_cfg.use_rva2)
162
	{
163
		mpg123_voladjust_cleanup();
164
		return;
165
	}
166
167
	update_dither();
168
169
	if (filename == NULL)
170
		filename = mpg123_filename;
171
172
	if (filename == NULL)
173
		return;
174
175
	if (!gain_from_id3_tag(filename, &newgain))
176
	{
177
		adjusting = FALSE;
178
		mpg123_current_gain = 0.0;
179
		memset(&gain_info, 0, sizeof(struct id3_gain));
180
		return;
181
	}
182
183
	fmt = mpg123_cfg.resolution == 16 ? FMT_S16_NE : FMT_U8;
184
	peak = newgain.channel[ID3_CHANNEL_MASTER].ch_peak;
185
	gain_db = newgain.channel[ID3_CHANNEL_MASTER].ch_gain;
186
187
	if (volume_lut == NULL)
188
	{
189
		/* the lookup table is 256k, but is deallocated if
190
		   volume adjustment is disabled */
191
		volume_lut = g_malloc(0x40000);
192
		/* move the pointer to the center of the allocated
193
		   region, so that we can use negative indices */
194
		volume_lut += 0x8000;
195
		need_update = TRUE;
196
	}
197
198
	gain_mult = pow(10, gain_db / 20.0);
199
	use_boost = mpg123_cfg.use_boost;
200
	if (use_boost)
201
		gain_mult *= 2;
202
203
	if (peak)
204
	{
205
		/*
206
		 * Figure out if the peak, multiplied by the gain,
207
		 * would clip.
208
		 *
209
		 * Some trickery here: we don't want to multiply our
210
		 * 32-bit peak by the gain, since it may overflow.
211
		 * Instead, we round it off to 24 bits. We then
212
		 * compare with 0xFFFF80, instead of 0xFFFFFF, to
213
		 * leave room for dithering.
214
		 */
215
		peak = ((peak >> 7) + 1) >> 1;
216
		if (peak * gain_mult <= 0xFFFF80)
217
			use_limiter = FALSE;
218
219
		if (use_limiter && mpg123_cfg.anticlip_mode == 1)
220
		{
221
			/* Reduce gain until the peak won't clip. */
222
			gain_mult = 0xFFFF80 / (float)peak;
223
			use_limiter = FALSE;
224
		}
225
	}
226
227
	if (!need_update
228
	    && lut_data.lut_fmt == fmt
229
	    && lut_data.lut_limit == use_limiter
230
	    && lut_data.lut_boost == use_boost
231
	    && fabs(lut_data.lut_gain - gain_db) < 0.0001)
232
	{
233
		/* the existing lookup table we have will work, no
234
		   need to build a new one */
235
		adjusting = TRUE;
236
		return;
237
	}
238
239
	/* We store 8 extra bits of precision in the table, for use in
240
	 * dithering. We can make this happen by simply multiplying
241
	 * the gain by 256. */
242
	gain_mult *= 256.0;
243
244
	if (fmt == FMT_U8)
245
	{
246
		samplemax = 0xFF;
247
		samplemin = 0;
248
		lut_samplemax = 0xFFFF;
249
		lut_samplemin = 0;
250
	}
251
	else
252
	{ /* fmt == FMT_S16_NE */
253
		samplemax = 0x7FFF;
254
		samplemin = ~samplemax;
255
		lut_samplemax = 0x7FFFFF;
256
		lut_samplemin = ~lut_samplemax;
257
	}
258
259
	/* leave space for dither, which ranges from -128 to +127 */
260
	lut_samplemax -= 127;
261
	lut_samplemin += 128;
262
263
	center = (samplemax + samplemin + 1) >> 1;
264
	lut_center = (lut_samplemax + lut_samplemin + 1) >> 1;
265
266
	/*
267
	 * Build the lookup table
268
	 */
269
	if (use_limiter)
270
	{
271
		/* apply gain, and use limiter to avoid clipping */
272
		scale = lut_center - lut_samplemin;
273
		for (i = samplemin; i < 0; i++)
274
			volume_lut[i] = lut_center + ROUND(scale * limiter((i-center) * gain_mult / scale));
275
		scale = lut_samplemax - lut_center;
276
		for (; i <= samplemax; i++)
277
			volume_lut[i] = lut_center + ROUND(scale * limiter((i-center) * gain_mult / scale));
278
	}
279
	else
280
	{
281
		/* just apply gain if it wouldn't clip anyway */
282
		for (i = samplemin; i <= samplemax; i++)
283
			volume_lut[i] = lut_center + ROUND((i-center) * gain_mult);
284
	}
285
286
	lut_data.lut_fmt = fmt;
287
	lut_data.lut_gain = gain_db;
288
	lut_data.lut_limit = use_limiter;
289
	lut_data.lut_boost = use_boost;
290
	mpg123_current_gain = gain_db;
291
	adjusting = TRUE;
292
293
	return;
294
}
295
296
297
void mpg123_voladjust(void *ptr, int length)
298
{
299
	AFormat fmt;
300
	int i;
301
	long sample;
302
	gint16 *ptr16 = NULL;
303
	guint8 *ptru8 = NULL;
304
305
	if (!adjusting || !mpg123_cfg.use_rva2 || volume_lut == NULL)
306
		return;
307
308
	fmt = mpg123_cfg.resolution == 16 ? FMT_S16_NE : FMT_U8;
309
310
	if (fmt == FMT_U8)
311
	{
312
		ptru8 = (guint8 *)ptr;
313
		if (mpg123_cfg.enable_dither)
314
		{
315
			for (i = 0; i < length; i++)
316
			{
317
				sample = volume_lut[*ptru8];
318
				sample += rand8();
319
				sample >>= 8;
320
				*ptru8 = sample;
321
				ptru8++;
322
			}
323
		}
324
		else
325
		{
326
			for (i = 0; i < length; i++)
327
			{
328
				*ptru8 = volume_lut[*ptru8] >> 8;
329
				ptru8++;
330
			}
331
		}
332
	}
333
	else
334
	{ /* fmt == FMT_S16_NE */
335
		ptr16 = (gint16 *)ptr;
336
		if (mpg123_cfg.enable_dither)
337
		{
338
			for (i = 0; i < length; i += 2)
339
			{
340
				sample = volume_lut[*ptr16];
341
				sample += rand8();
342
				sample >>= 8;
343
				*ptr16 = sample;
344
				ptr16++;
345
			}
346
		}
347
		else
348
		{
349
			for (i = 0; i < length; i += 2)
350
			{
351
				*ptr16 = volume_lut[*ptr16] >> 8;
352
				ptr16++;
353
			}
354
		}
355
	}
356
}

Return to bug 29477