comparison src/madplug/decoder.c @ 2341:59addab003d7

- reworked replaygain to use individual pre-gain for the files with RG info and the rest. - default pre-gain have been changed to +6dB for with RG, +0dB for the rest. - new clipping prevention feature using track peak information has been implemented. - reworked preferences dialog. widgets have been categorized by function and all changes will take effect immediately. and also, cancel button can reverts all changes have been done in the current session. - some keys in preferences have been changed.
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Thu, 31 Jan 2008 15:22:15 +0900
parents 47d7a45b26a0
children f40f4ae3d5eb
comparison
equal deleted inserted replaced
2340:47d7a45b26a0 2341:59addab003d7
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22 /* #define AUD_DEBUG 1 */
23
22 #include <math.h> 24 #include <math.h>
23 #include <assert.h> 25 #include <assert.h>
24 #include <pthread.h> 26 #include <pthread.h>
25 #include <signal.h> 27 #include <signal.h>
26 28
40 * Scale PCM data 42 * Scale PCM data
41 */ 43 */
42 static inline signed int 44 static inline signed int
43 scale(mad_fixed_t sample, struct mad_info_t *file_info) 45 scale(mad_fixed_t sample, struct mad_info_t *file_info)
44 { 46 {
45 /* replayGain by SamKR */
46 gdouble scale = -1; 47 gdouble scale = -1;
47 if (audmad_config.replaygain.enable) { 48 static int i = 0;
49
50 if (audmad_config->replaygain.enable) {
48 if (file_info->has_replaygain) { 51 if (file_info->has_replaygain) {
49 scale = file_info->replaygain_track_scale; 52 // apply track gain if it is available and track mode is specified
50 if (file_info->replaygain_album_scale != -1 53 if(file_info->replaygain_track_scale != -1) {
51 && (scale == -1 || !audmad_config.replaygain.track_mode)) 54 scale = file_info->replaygain_track_scale;
52 { 55 }
56 // apply album gain if available
57 if(!audmad_config->replaygain.track_mode &&
58 file_info->replaygain_album_scale != -1) {
53 scale = file_info->replaygain_album_scale; 59 scale = file_info->replaygain_album_scale;
54 } 60 }
55 } 61
56 if (scale == -1) 62 // apply preamp1
57 scale = audmad_config.replaygain.default_scale; 63 scale *= audmad_config->replaygain.preamp1_scale;
58 } 64
59 if (scale == -1) 65 if (audmad_config->replaygain.anti_clip) {
66 if(i%100000 == 0)
67 AUDDBG("track_peak = %f\n", file_info->replaygain_track_peak);
68 if(scale * file_info->replaygain_track_peak >= 1.0)
69 scale = 1.0 / file_info->replaygain_track_peak;
70 }
71 }
72 else {
73 // apply preamp2 for files without RG info
74 scale = audmad_config->replaygain.preamp2_scale;
75 }
76 }
77 else {
60 scale = 1.0; 78 scale = 1.0;
61 if (audmad_config.pregain_scale != 1) 79 }
62 scale = scale * audmad_config.pregain_scale; 80
81 // apply global gain
82 if (audmad_config->replaygain.preamp0_scale != 1)
83 scale = scale * audmad_config->replaygain.preamp0_scale;
84
85 if(i%100000 == 0) {
86 AUDDBG("scale = %f\n", scale);
87 }
63 88
64 /* hard-limit (clipping-prevention) */ 89 /* hard-limit (clipping-prevention) */
65 if (audmad_config.hard_limit) { 90 if (audmad_config->replaygain.hard_limit) {
91
92 if(i%100000 == 0) {
93 AUDDBG("hard_limit\n");
94 }
95
66 /* convert to double before computation, to avoid mad_fixed_t wrapping */ 96 /* convert to double before computation, to avoid mad_fixed_t wrapping */
67 double x = mad_f_todouble(sample) * scale; 97 double x = mad_f_todouble(sample) * scale;
68 static const double k = 0.5; // -6dBFS 98 static const double k = 0.5; // -6dBFS
69 if (x > k) { 99 if (x > k) {
70 x = tanh((x - k) / (1 - k)) * (1 - k) + k; 100 x = tanh((x - k) / (1 - k)) * (1 - k) + k;
71 } 101 }
72 else if (x < -k) { 102 else if (x < -k) {
73 x = tanh((x + k) / (1 - k)) * (1 - k) - k; 103 x = tanh((x + k) / (1 - k)) * (1 - k) - k;
74 } 104 }
75 sample = x * (MAD_F_ONE); 105 sample = x * (MAD_F_ONE);
106
107 if(i%100000 == 0) {
108 AUDDBG("x = %f sample = %d\n", x, sample);
109 }
110
76 } 111 }
77 else 112 else
78 sample *= scale; 113 sample *= scale;
114
115 i++;
79 116
80 int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16; 117 int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16;
81 118
82 /* round */ 119 /* round */
83 /* add half of the bits_to_loose range to round */ 120 /* add half of the bits_to_loose range to round */
86 #ifdef DEBUG_DITHER 123 #ifdef DEBUG_DITHER
87 mad_fixed_t no_dither = sample; 124 mad_fixed_t no_dither = sample;
88 #endif 125 #endif
89 126
90 /* dither one bit of actual output */ 127 /* dither one bit of actual output */
91 if (audmad_config.dither) { 128 if (audmad_config->dither) {
92 int dither = triangular_dither_noise(n_bits_to_loose + 1); 129 int dither = triangular_dither_noise(n_bits_to_loose + 1);
93 sample += dither; 130 sample += dither;
94 } 131 }
95 132
96 /* clip */ 133 /* clip */
164 201
165 /** 202 /**
166 * Decode all headers in the file and fill in stats 203 * Decode all headers in the file and fill in stats
167 * @return FALSE if scan failed. 204 * @return FALSE if scan failed.
168 */ 205 */
169 gboolean scan_file(struct mad_info_t * info, gboolean fast) 206 gboolean
207 scan_file(struct mad_info_t * info, gboolean fast)
170 { 208 {
171 struct mad_stream stream; 209 struct mad_stream stream;
172 struct mad_header header; 210 struct mad_header header;
173 int remainder = 0; 211 int remainder = 0;
174 int data_used = 0; 212 int data_used = 0;
275 info->freq = header.samplerate; 313 info->freq = header.samplerate;
276 info->channels = MAD_NCHANNELS(&header); 314 info->channels = MAD_NCHANNELS(&header);
277 info->mpeg_layer = header.layer; 315 info->mpeg_layer = header.layer;
278 info->mode = header.mode; 316 info->mode = header.mode;
279 317
280 if (audmad_config.use_xing) { 318 if (audmad_config->use_xing) {
281 frame.header = header; 319 frame.header = header;
282 if (mad_frame_decode(&frame, &stream) == -1) { 320 if (mad_frame_decode(&frame, &stream) == -1) {
283 AUDDBG("xing frame decode failed\n"); 321 AUDDBG("xing frame decode failed\n");
284 goto no_xing; 322 goto no_xing;
285 } 323 }
399 437
400 return (info->frames != 0 || info->remote == TRUE); 438 return (info->frames != 0 || info->remote == TRUE);
401 } 439 }
402 440
403 /* sanity check for audio open parameters */ 441 /* sanity check for audio open parameters */
404 static gboolean check_audio_param(struct mad_info_t *info) 442 static gboolean
443 check_audio_param(struct mad_info_t *info)
405 { 444 {
406 if(info->fmt < FMT_U8 || info->fmt > FMT_S16_NE) 445 if(info->fmt < FMT_U8 || info->fmt > FMT_S16_NE)
407 return FALSE; 446 return FALSE;
408 if(info->freq < 0) // not sure about maximum frequency. --yaz 447 if(info->freq < 0) // not sure about maximum frequency. --yaz
409 return FALSE; 448 return FALSE;
411 return FALSE; 450 return FALSE;
412 451
413 return TRUE; 452 return TRUE;
414 } 453 }
415 454
416 gpointer decode_loop(gpointer arg) 455 gpointer
456 decode_loop(gpointer arg)
417 { 457 {
418 unsigned char buffer[BUFFER_SIZE]; 458 unsigned char buffer[BUFFER_SIZE];
419 int len; 459 int len;
420 gboolean seek_skip = FALSE; 460 gboolean seek_skip = FALSE;
421 int remainder = 0; 461 int remainder = 0;
459 } 499 }
460 500
461 /* set mainwin title */ 501 /* set mainwin title */
462 if (info->title) 502 if (info->title)
463 g_free(info->title); 503 g_free(info->title);
464 info->title = aud_tuple_formatter_make_title_string(info->tuple, audmad_config.title_override == TRUE ? 504 info->title = aud_tuple_formatter_make_title_string(info->tuple, audmad_config->title_override == TRUE ?
465 audmad_config.id3_format : aud_get_gentitle_format()); 505 audmad_config->id3_format : aud_get_gentitle_format());
466 506
467 tlen = (gint) mad_timer_count(info->duration, MAD_UNITS_MILLISECONDS), 507 tlen = (gint) mad_timer_count(info->duration, MAD_UNITS_MILLISECONDS),
468 info->playback->set_params(info->playback, info->title, 508 info->playback->set_params(info->playback, info->title,
469 (tlen == 0 || info->size <= 0) ? -1 : tlen, 509 (tlen == 0 || info->size <= 0) ? -1 : tlen,
470 info->bitrate, info->freq, info->channels); 510 info->bitrate, info->freq, info->channels);
579 continue; 619 continue;
580 } 620 }
581 621
582 info->bitrate = frame.header.bitrate; 622 info->bitrate = frame.header.bitrate;
583 623
584 if (!audmad_config.show_avg_vbr_bitrate && info->vbr && (iteration % 40 == 0)) { 624 if (!audmad_config->show_avg_vbr_bitrate && info->vbr && (iteration % 40 == 0)) {
585 625
586 #ifdef DEBUG_INTENSIVELY 626 #ifdef DEBUG_INTENSIVELY
587 AUDDBG("decode vbr tlen = %d\n", tlen); 627 AUDDBG("decode vbr tlen = %d\n", tlen);
588 #endif 628 #endif
589 info->playback->set_params(info->playback, info->title, 629 info->playback->set_params(info->playback, info->title,
616 (guint) MAD_NCHANNELS(&frame.header)); 656 (guint) MAD_NCHANNELS(&frame.header));
617 657
618 info->freq = frame.header.samplerate; 658 info->freq = frame.header.samplerate;
619 info->channels = MAD_NCHANNELS(&frame.header); 659 info->channels = MAD_NCHANNELS(&frame.header);
620 660
621 if(audmad_config.force_reopen_audio && check_audio_param(info)) { 661 if(audmad_config->force_reopen_audio && check_audio_param(info)) {
622 gint current_time = info->playback->output->output_time(); 662 gint current_time = info->playback->output->output_time();
623 663
624 AUDDBG("re-opening audio due to change in audio type\n"); 664 AUDDBG("re-opening audio due to change in audio type\n");
625 665
626 info->playback->output->close_audio(); 666 info->playback->output->close_audio();