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