Changes to update Tomato RAF.
[tomato.git] / release / src / router / flac / src / share / replaygain_synthesis / replaygain_synthesis.c
blobe5615766d7bc6bb082db8b8f904aaedf0798d432
1 /* replaygain_synthesis - Routines for applying ReplayGain to a signal
2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * This is an aggregation of pieces of code from John Edwards' WaveGain
20 * program. Mostly cosmetic changes were made; otherwise, the dithering
21 * code is almost untouched and the gain processing was converted from
22 * processing a whole file to processing chunks of samples.
24 * The original copyright notices for WaveGain's dither.c and wavegain.c
25 * appear below:
28 * (c) 2002 John Edwards
29 * mostly lifted from work by Frank Klemm
30 * random functions for dithering.
33 * Copyright (C) 2002 John Edwards
34 * Additional code by Magnus Holmgren and Gian-Carlo Pascutto
37 #if HAVE_CONFIG_H
38 # include <config.h>
39 #endif
41 #include <string.h> /* for memset() */
42 #include <math.h>
43 #include "private/fast_float_math_hack.h"
44 #include "replaygain_synthesis.h"
45 #include "FLAC/assert.h"
47 #ifndef FLaC__INLINE
48 #define FLaC__INLINE
49 #endif
51 /* adjust for compilers that can't understand using LL suffix for int64_t literals */
52 #ifdef _MSC_VER
53 #define FLAC__I64L(x) x
54 #else
55 #define FLAC__I64L(x) x##LL
56 #endif
60 * the following is based on parts of dither.c
65 * This is a simple random number generator with good quality for audio purposes.
66 * It consists of two polycounters with opposite rotation direction and different
67 * periods. The periods are coprime, so the total period is the product of both.
69 * -------------------------------------------------------------------------------------------------
70 * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
71 * | -------------------------------------------------------------------------------------------------
72 * | | | | | | |
73 * | +--+--+--+-XOR-+--------+
74 * | |
75 * +--------------------------------------------------------------------------------------+
77 * -------------------------------------------------------------------------------------------------
78 * |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
79 * ------------------------------------------------------------------------------------------------- |
80 * | | | | |
81 * +--+----XOR----+--+ |
82 * | |
83 * +----------------------------------------------------------------------------------------+
86 * The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
87 * which gives a period of 18.410.713.077.675.721.215. The result is the
88 * XORed values of both generators.
91 static unsigned int random_int_(void)
93 static const unsigned char parity_[256] = {
94 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
95 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
96 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
97 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
98 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
99 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
100 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
101 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
103 static unsigned int r1_ = 1;
104 static unsigned int r2_ = 1;
106 unsigned int t1, t2, t3, t4;
108 /* Parity calculation is done via table lookup, this is also available
109 * on CPUs without parity, can be implemented in C and avoid unpredictable
110 * jumps and slow rotate through the carry flag operations.
112 t3 = t1 = r1_; t4 = t2 = r2_;
113 t1 &= 0xF5; t2 >>= 25;
114 t1 = parity_[t1]; t2 &= 0x63;
115 t1 <<= 31; t2 = parity_[t2];
117 return (r1_ = (t3 >> 1) | t1 ) ^ (r2_ = (t4 + t4) | t2 );
120 /* gives a equal distributed random number */
121 /* between -2^31*mult and +2^31*mult */
122 static double random_equi_(double mult)
124 return mult * (int) random_int_();
127 /* gives a triangular distributed random number */
128 /* between -2^32*mult and +2^32*mult */
129 static double random_triangular_(double mult)
131 return mult * ( (double) (int) random_int_() + (double) (int) random_int_() );
135 static const float F44_0 [16 + 32] = {
136 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
137 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
139 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
140 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
142 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
143 (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0
147 static const float F44_1 [16 + 32] = { /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */
148 (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
149 (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
150 (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
151 (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
153 (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
154 (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
155 (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
156 (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
158 (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
159 (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
160 (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
161 (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
165 static const float F44_2 [16 + 32] = { /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */
166 (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
167 (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
168 (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
169 (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
171 (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
172 (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
173 (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
174 (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
176 (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
177 (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
178 (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
179 (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
183 static const float F44_3 [16 + 32] = { /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */
184 (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
185 (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
186 (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
187 (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
189 (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
190 (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
191 (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
192 (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099,
194 (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
195 (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
196 (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
197 (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099
201 static double scalar16_(const float* x, const float* y)
203 return
204 x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3] +
205 x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7] +
206 x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11] +
207 x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15];
211 void FLAC__replaygain_synthesis__init_dither_context(DitherContext *d, int bits, int shapingtype)
213 static unsigned char default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67, 0, 0 };
214 static const float* F [] = { F44_0, F44_1, F44_2, F44_3 };
216 int index;
218 if (shapingtype < 0) shapingtype = 0;
219 if (shapingtype > 3) shapingtype = 3;
220 d->ShapingType = (NoiseShaping)shapingtype;
221 index = bits - 11 - shapingtype;
222 if (index < 0) index = 0;
223 if (index > 9) index = 9;
225 memset ( d->ErrorHistory , 0, sizeof (d->ErrorHistory ) );
226 memset ( d->DitherHistory, 0, sizeof (d->DitherHistory) );
228 d->FilterCoeff = F [shapingtype];
229 d->Mask = ((FLAC__uint64)-1) << (32 - bits);
230 d->Add = 0.5 * ((1L << (32 - bits)) - 1);
231 d->Dither = 0.01f*default_dither[index] / (((FLAC__int64)1) << bits);
232 d->LastHistoryIndex = 0;
236 * the following is based on parts of wavegain.c
239 static FLaC__INLINE FLAC__int64 dither_output_(DitherContext *d, FLAC__bool do_dithering, int shapingtype, int i, double Sum, int k)
241 union {
242 double d;
243 FLAC__int64 i;
244 } doubletmp;
245 double Sum2;
246 FLAC__int64 val;
248 #define ROUND64(x) ( doubletmp.d = (x) + d->Add + (FLAC__int64)FLAC__I64L(0x001FFFFD80000000), doubletmp.i - (FLAC__int64)FLAC__I64L(0x433FFFFD80000000) )
250 if(do_dithering) {
251 if(shapingtype == 0) {
252 double tmp = random_equi_(d->Dither);
253 Sum2 = tmp - d->LastRandomNumber [k];
254 d->LastRandomNumber [k] = (int)tmp;
255 Sum2 = Sum += Sum2;
256 val = ROUND64(Sum2) & d->Mask;
258 else {
259 Sum2 = random_triangular_(d->Dither) - scalar16_(d->DitherHistory[k], d->FilterCoeff + i);
260 Sum += d->DitherHistory [k] [(-1-i)&15] = (float)Sum2;
261 Sum2 = Sum + scalar16_(d->ErrorHistory [k], d->FilterCoeff + i);
262 val = ROUND64(Sum2) & d->Mask;
263 d->ErrorHistory [k] [(-1-i)&15] = (float)(Sum - val);
265 return val;
267 else
268 return ROUND64(Sum);
270 #undef ROUND64
273 #if 0
274 float peak = 0.f,
275 new_peak,
276 factor_clip
277 double scale,
282 peak is in the range -32768.0 .. 32767.0
284 /* calculate factors for ReplayGain and ClippingPrevention */
285 *track_gain = GetTitleGain() + settings->man_gain;
286 scale = (float) pow(10., *track_gain * 0.05);
287 if(settings->clip_prev) {
288 factor_clip = (float) (32767./( peak + 1));
289 if(scale < factor_clip)
290 factor_clip = 1.f;
291 else
292 factor_clip /= scale;
293 scale *= factor_clip;
295 new_peak = (float) peak * scale;
297 dB = 20. * log10(scale);
298 *track_gain = (float) dB;
300 const double scale = pow(10., (double)gain * 0.05);
301 #endif
304 size_t FLAC__replaygain_synthesis__apply_gain(FLAC__byte *data_out, FLAC__bool little_endian_data_out, FLAC__bool unsigned_data_out, const FLAC__int32 * const input[], unsigned wide_samples, unsigned channels, const unsigned source_bps, const unsigned target_bps, const double scale, const FLAC__bool hard_limit, FLAC__bool do_dithering, DitherContext *dither_context)
306 static const FLAC__int32 conv_factors_[33] = {
307 -1, /* 0 bits-per-sample (not supported) */
308 -1, /* 1 bits-per-sample (not supported) */
309 -1, /* 2 bits-per-sample (not supported) */
310 -1, /* 3 bits-per-sample (not supported) */
311 268435456, /* 4 bits-per-sample */
312 134217728, /* 5 bits-per-sample */
313 67108864, /* 6 bits-per-sample */
314 33554432, /* 7 bits-per-sample */
315 16777216, /* 8 bits-per-sample */
316 8388608, /* 9 bits-per-sample */
317 4194304, /* 10 bits-per-sample */
318 2097152, /* 11 bits-per-sample */
319 1048576, /* 12 bits-per-sample */
320 524288, /* 13 bits-per-sample */
321 262144, /* 14 bits-per-sample */
322 131072, /* 15 bits-per-sample */
323 65536, /* 16 bits-per-sample */
324 32768, /* 17 bits-per-sample */
325 16384, /* 18 bits-per-sample */
326 8192, /* 19 bits-per-sample */
327 4096, /* 20 bits-per-sample */
328 2048, /* 21 bits-per-sample */
329 1024, /* 22 bits-per-sample */
330 512, /* 23 bits-per-sample */
331 256, /* 24 bits-per-sample */
332 128, /* 25 bits-per-sample */
333 64, /* 26 bits-per-sample */
334 32, /* 27 bits-per-sample */
335 16, /* 28 bits-per-sample */
336 8, /* 29 bits-per-sample */
337 4, /* 30 bits-per-sample */
338 2, /* 31 bits-per-sample */
339 1 /* 32 bits-per-sample */
341 static const FLAC__int64 hard_clip_factors_[33] = {
342 0, /* 0 bits-per-sample (not supported) */
343 0, /* 1 bits-per-sample (not supported) */
344 0, /* 2 bits-per-sample (not supported) */
345 0, /* 3 bits-per-sample (not supported) */
346 -8, /* 4 bits-per-sample */
347 -16, /* 5 bits-per-sample */
348 -32, /* 6 bits-per-sample */
349 -64, /* 7 bits-per-sample */
350 -128, /* 8 bits-per-sample */
351 -256, /* 9 bits-per-sample */
352 -512, /* 10 bits-per-sample */
353 -1024, /* 11 bits-per-sample */
354 -2048, /* 12 bits-per-sample */
355 -4096, /* 13 bits-per-sample */
356 -8192, /* 14 bits-per-sample */
357 -16384, /* 15 bits-per-sample */
358 -32768, /* 16 bits-per-sample */
359 -65536, /* 17 bits-per-sample */
360 -131072, /* 18 bits-per-sample */
361 -262144, /* 19 bits-per-sample */
362 -524288, /* 20 bits-per-sample */
363 -1048576, /* 21 bits-per-sample */
364 -2097152, /* 22 bits-per-sample */
365 -4194304, /* 23 bits-per-sample */
366 -8388608, /* 24 bits-per-sample */
367 -16777216, /* 25 bits-per-sample */
368 -33554432, /* 26 bits-per-sample */
369 -67108864, /* 27 bits-per-sample */
370 -134217728, /* 28 bits-per-sample */
371 -268435456, /* 29 bits-per-sample */
372 -536870912, /* 30 bits-per-sample */
373 -1073741824, /* 31 bits-per-sample */
374 (FLAC__int64)(-1073741824) * 2 /* 32 bits-per-sample */
376 const FLAC__int32 conv_factor = conv_factors_[target_bps];
377 const FLAC__int64 hard_clip_factor = hard_clip_factors_[target_bps];
379 * The integer input coming in has a varying range based on the
380 * source_bps. We want to normalize it to [-1.0, 1.0) so instead
381 * of doing two multiplies on each sample, we just multiple
382 * 'scale' by 1/(2^(source_bps-1))
384 const double multi_scale = scale / (double)(1u << (source_bps-1));
386 FLAC__byte * const start = data_out;
387 unsigned i, channel;
388 const FLAC__int32 *input_;
389 double sample;
390 const unsigned bytes_per_sample = target_bps / 8;
391 const unsigned last_history_index = dither_context->LastHistoryIndex;
392 NoiseShaping noise_shaping = dither_context->ShapingType;
393 FLAC__int64 val64;
394 FLAC__int32 val32;
395 FLAC__int32 uval32;
396 const FLAC__uint32 twiggle = 1u << (target_bps - 1);
398 FLAC__ASSERT(channels > 0 && channels <= FLAC_SHARE__MAX_SUPPORTED_CHANNELS);
399 FLAC__ASSERT(source_bps >= 4);
400 FLAC__ASSERT(target_bps >= 4);
401 FLAC__ASSERT(source_bps <= 32);
402 FLAC__ASSERT(target_bps < 32);
403 FLAC__ASSERT((target_bps & 7) == 0);
405 for(channel = 0; channel < channels; channel++) {
406 const unsigned incr = bytes_per_sample * channels;
407 data_out = start + bytes_per_sample * channel;
408 input_ = input[channel];
409 for(i = 0; i < wide_samples; i++, data_out += incr) {
410 sample = (double)input_[i] * multi_scale;
412 if(hard_limit) {
413 /* hard 6dB limiting */
414 if(sample < -0.5)
415 sample = tanh((sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5;
416 else if(sample > 0.5)
417 sample = tanh((sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5;
419 sample *= 2147483647.f;
421 val64 = dither_output_(dither_context, do_dithering, noise_shaping, (i + last_history_index) % 32, sample, channel) / conv_factor;
423 val32 = (FLAC__int32)val64;
424 if(val64 >= -hard_clip_factor)
425 val32 = (FLAC__int32)(-(hard_clip_factor+1));
426 else if(val64 < hard_clip_factor)
427 val32 = (FLAC__int32)hard_clip_factor;
429 uval32 = (FLAC__uint32)val32;
430 if (unsigned_data_out)
431 uval32 ^= twiggle;
433 if (little_endian_data_out) {
434 switch(target_bps) {
435 case 24:
436 data_out[2] = (FLAC__byte)(uval32 >> 16);
437 /* fall through */
438 case 16:
439 data_out[1] = (FLAC__byte)(uval32 >> 8);
440 /* fall through */
441 case 8:
442 data_out[0] = (FLAC__byte)uval32;
443 break;
446 else {
447 switch(target_bps) {
448 case 24:
449 data_out[0] = (FLAC__byte)(uval32 >> 16);
450 data_out[1] = (FLAC__byte)(uval32 >> 8);
451 data_out[2] = (FLAC__byte)uval32;
452 break;
453 case 16:
454 data_out[0] = (FLAC__byte)(uval32 >> 8);
455 data_out[1] = (FLAC__byte)uval32;
456 break;
457 case 8:
458 data_out[0] = (FLAC__byte)uval32;
459 break;
464 dither_context->LastHistoryIndex = (last_history_index + wide_samples) % 32;
466 return wide_samples * channels * (target_bps/8);