comparison src/madplug/decoder.c @ 2344:fd8271f07747

replaced 6db hard limit with experimental adaptive scaler clip prevention.
author Yoshiki Yazawa <yaz@cc.rim.or.jp>
date Sun, 03 Feb 2008 00:05:32 +0900
parents f40f4ae3d5eb
children bd9673d8b7d5
comparison
equal deleted inserted replaced
2342:f40f4ae3d5eb 2344:fd8271f07747
43 */ 43 */
44 static inline signed int 44 static inline signed int
45 scale(mad_fixed_t sample, struct mad_info_t *file_info) 45 scale(mad_fixed_t sample, struct mad_info_t *file_info)
46 { 46 {
47 gdouble scale = -1; 47 gdouble scale = -1;
48 #ifdef AUD_DEBUG 48 static double a_scale = -1;
49 static int i = 0; 49 static int iter = 0;
50 #endif
51 50
52 if (audmad_config->replaygain.enable) { 51 if (audmad_config->replaygain.enable) {
53 if (file_info->has_replaygain) { 52 if (file_info->has_replaygain) {
54 // apply track gain if it is available and track mode is specified 53 // apply track gain if it is available and track mode is specified
55 if(file_info->replaygain_track_scale != -1) { 54 if(file_info->replaygain_track_scale != -1) {
64 // apply preamp1 63 // apply preamp1
65 scale *= audmad_config->replaygain.preamp1_scale; 64 scale *= audmad_config->replaygain.preamp1_scale;
66 65
67 if (audmad_config->replaygain.anti_clip) { 66 if (audmad_config->replaygain.anti_clip) {
68 #ifdef AUD_DEBUG 67 #ifdef AUD_DEBUG
69 if(i%100000 == 0) 68 if(iter % 100000 == 0)
70 AUDDBG("track_peak = %f\n", file_info->replaygain_track_peak); 69 AUDDBG("track_peak = %f\n", file_info->replaygain_track_peak);
71 #endif 70 #endif
72 if(scale * file_info->replaygain_track_peak >= 1.0) 71 if(scale * file_info->replaygain_track_peak >= 1.0)
73 scale = 1.0 / file_info->replaygain_track_peak; 72 scale = 1.0 / file_info->replaygain_track_peak;
74 } 73 }
84 83
85 // apply global gain 84 // apply global gain
86 if (audmad_config->replaygain.preamp0_scale != 1) 85 if (audmad_config->replaygain.preamp0_scale != 1)
87 scale = scale * audmad_config->replaygain.preamp0_scale; 86 scale = scale * audmad_config->replaygain.preamp0_scale;
88 87
89 #ifdef AUD_DEBUG 88 // adaptive scaler clip prevention
90 if(i%100000 == 0) { 89 if (audmad_config->replaygain.adaptive_scaler) {
91 AUDDBG("scale = %f\n", scale); 90 double x;
92 } 91 double a = 0.1;
93 #endif 92 int interval = 10000;
94 93
95 /* hard-limit (clipping-prevention) */ 94 if(a_scale == -1.0)
96 if (audmad_config->replaygain.hard_limit) { 95 a_scale = scale;
97 96
98 #ifdef AUD_DEBUG 97 x = mad_f_todouble(sample) * a_scale;
99 if(i%100000 == 0) { 98
100 AUDDBG("hard_limit\n"); 99 // clippling avoidance
101 } 100 if(x > 1.0) {
102 #endif 101 a_scale = a_scale + a * (1.0 - x);
103 /* convert to double before computation, to avoid mad_fixed_t wrapping */ 102 AUDDBG("down: x = %f a_scale = %f\n", x, a_scale);
104 double x = mad_f_todouble(sample) * scale; 103 }
105 static const double k = 0.5; // -6dBFS 104 // slowly go back to defined scale
106 if (x > k) { 105 else if(iter % interval == 0 && a_scale < scale){
107 x = tanh((x - k) / (1 - k)) * (1 - k) + k; 106 a_scale = a_scale + 1.0e-4;
108 } 107 AUDDBG("up: a_scale = %f\n", a_scale);
109 else if (x < -k) { 108 }
110 x = tanh((x + k) / (1 - k)) * (1 - k) - k; 109
111 } 110 x = mad_f_todouble(sample) * a_scale;
112 sample = x * (MAD_F_ONE); 111 sample = x * (MAD_F_ONE);
113 112 }
114 #ifdef AUD_DEBUG 113 else {
115 if(i%100000 == 0) { 114 a_scale = scale;
116 AUDDBG("x = %f sample = %d\n", x, sample);
117 }
118 #endif
119
120 }
121 else
122 sample *= scale; 115 sample *= scale;
123 116 }
124 #ifdef AUD_DEBUG 117
125 i++; 118 iter++;
126 #endif
127 119
128 int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16; 120 int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16;
129 121
130 /* round */ 122 /* round */
131 /* add half of the bits_to_loose range to round */ 123 /* add half of the bits_to_loose range to round */