replaygain_synthesis.c : Replace float literal with double literal.
[flac.git] / src / share / replaygain_synthesis / replaygain_synthesis.c
1 /* replaygain_synthesis - Routines for applying ReplayGain to a signal
2  * Copyright (C) 2002-2009  Josh Coalson
3  * Copyright (C) 2011-2013  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 #if HAVE_CONFIG_H
39 #  include <config.h>
40 #endif
41
42 #include <string.h> /* for memset() */
43 #include <math.h>
44 #include "private/fast_float_math_hack.h"
45 #include "replaygain_synthesis.h"
46 #include "FLAC/assert.h"
47
48 /* adjust for compilers that can't understand using LL suffix for int64_t literals */
49 #ifdef _MSC_VER
50 #define FLAC__I64L(x) x
51 #else
52 #define FLAC__I64L(x) x##LL
53 #endif
54
55
56 /*
57  * the following is based on parts of dither.c
58  */
59
60
61 /*
62  *  This is a simple random number generator with good quality for audio purposes.
63  *  It consists of two polycounters with opposite rotation direction and different
64  *  periods. The periods are coprime, so the total period is the product of both.
65  *
66  *     -------------------------------------------------------------------------------------------------
67  * +-> |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|
68  * |   -------------------------------------------------------------------------------------------------
69  * |                                                                          |  |  |  |     |        |
70  * |                                                                          +--+--+--+-XOR-+--------+
71  * |                                                                                      |
72  * +--------------------------------------------------------------------------------------+
73  *
74  *     -------------------------------------------------------------------------------------------------
75  *     |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| <-+
76  *     -------------------------------------------------------------------------------------------------   |
77  *       |  |           |  |                                                                               |
78  *       +--+----XOR----+--+                                                                               |
79  *                |                                                                                        |
80  *                +----------------------------------------------------------------------------------------+
81  *
82  *
83  *  The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
84  *  which gives a period of 18.410.713.077.675.721.215. The result is the
85  *  XORed values of both generators.
86  */
87
88 static unsigned int random_int_(void)
89 {
90         static const unsigned char parity_[256] = {
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                 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,
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                 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                 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,
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         };
100         static unsigned int r1_ = 1;
101         static unsigned int r2_ = 1;
102
103         unsigned int t1, t2, t3, t4;
104
105         /* Parity calculation is done via table lookup, this is also available
106          * on CPUs without parity, can be implemented in C and avoid unpredictable
107          * jumps and slow rotate through the carry flag operations.
108          */
109         t3   = t1 = r1_;    t4   = t2 = r2_;
110         t1  &= 0xF5;        t2 >>= 25;
111         t1   = parity_[t1]; t2  &= 0x63;
112         t1 <<= 31;          t2   = parity_[t2];
113
114         return (r1_ = (t3 >> 1) | t1 ) ^ (r2_ = (t4 + t4) | t2 );
115 }
116
117 /* gives a equal distributed random number */
118 /* between -2^31*mult and +2^31*mult */
119 static double random_equi_(double mult)
120 {
121         return mult * (int) random_int_();
122 }
123
124 /* gives a triangular distributed random number */
125 /* between -2^32*mult and +2^32*mult */
126 static double random_triangular_(double mult)
127 {
128         return mult * ( (double) (int) random_int_() + (double) (int) random_int_() );
129 }
130
131
132 static const float  F44_0 [16 + 32] = {
133         (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
134         (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0, (float)0,
135
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,
138
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
141 };
142
143
144 static const float  F44_1 [16 + 32] = {  /* SNR(w) = 4.843163 dB, SNR = -3.192134 dB */
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         (float) 0.85018292704024355931, (float) 0.29089597350995344721, (float)-0.05021866022121039450, (float)-0.23545456294599161833,
156         (float)-0.58362726442227032096, (float)-0.67038978965193036429, (float)-0.38566861572833459221, (float)-0.15218663390367969967,
157         (float)-0.02577543084864530676, (float) 0.14119295297688728127, (float) 0.22398848581628781612, (float) 0.15401727203382084116,
158         (float) 0.05216161232906000929, (float)-0.00282237820999675451, (float)-0.03042794608323867363, (float)-0.03109780942998826024,
159 };
160
161
162 static const float  F44_2 [16 + 32] = {  /* SNR(w) = 10.060213 dB, SNR = -12.766730 dB */
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         (float) 1.78827593892108555290, (float) 0.95508210637394326553, (float)-0.18447626783899924429, (float)-0.44198126506275016437,
174         (float)-0.88404052492547413497, (float)-1.42218907262407452967, (float)-1.02037566838362314995, (float)-0.34861755756425577264,
175         (float)-0.11490230170431934434, (float) 0.12498899339968611803, (float) 0.38065885268563131927, (float) 0.31883491321310506562,
176         (float) 0.10486838686563442765, (float)-0.03105361685110374845, (float)-0.06450524884075370758, (float)-0.02939198261121969816,
177 };
178
179
180 static const float  F44_3 [16 + 32] = {  /* SNR(w) = 15.382598 dB, SNR = -29.402334 dB */
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         (float) 2.89072132015058161445, (float) 2.68932810943698754106, (float) 0.21083359339410251227, (float)-0.98385073324997617515,
192         (float)-1.11047823227097316719, (float)-2.18954076314139673147, (float)-2.36498032881953056225, (float)-0.95484132880101140785,
193         (float)-0.23924057925542965158, (float)-0.13865235703915925642, (float) 0.43587843191057992846, (float) 0.65903257226026665927,
194         (float) 0.24361815372443152787, (float)-0.00235974960154720097, (float) 0.01844166574603346289, (float) 0.01722945988740875099
195 };
196
197
198 static double scalar16_(const float* x, const float* y)
199 {
200         return
201                 x[ 0]*y[ 0] + x[ 1]*y[ 1] + x[ 2]*y[ 2] + x[ 3]*y[ 3] +
202                 x[ 4]*y[ 4] + x[ 5]*y[ 5] + x[ 6]*y[ 6] + x[ 7]*y[ 7] +
203                 x[ 8]*y[ 8] + x[ 9]*y[ 9] + x[10]*y[10] + x[11]*y[11] +
204                 x[12]*y[12] + x[13]*y[13] + x[14]*y[14] + x[15]*y[15];
205 }
206
207
208 void FLAC__replaygain_synthesis__init_dither_context(DitherContext *d, int bits, int shapingtype)
209 {
210         static unsigned char default_dither [] = { 92, 92, 88, 84, 81, 78, 74, 67,  0,  0 };
211         static const float*               F [] = { F44_0, F44_1, F44_2, F44_3 };
212
213         int indx;
214
215         if (shapingtype < 0) shapingtype = 0;
216         if (shapingtype > 3) shapingtype = 3;
217         d->ShapingType = (NoiseShaping)shapingtype;
218         indx = bits - 11 - shapingtype;
219         if (indx < 0) indx = 0;
220         if (indx > 9) indx = 9;
221
222         memset ( d->ErrorHistory , 0, sizeof (d->ErrorHistory ) );
223         memset ( d->DitherHistory, 0, sizeof (d->DitherHistory) );
224
225         d->FilterCoeff = F [shapingtype];
226         d->Mask   = ((FLAC__uint64)-1) << (32 - bits);
227         d->Add    = 0.5     * ((1L << (32 - bits)) - 1);
228         d->Dither = 0.01f*default_dither[indx] / (((FLAC__int64)1) << bits);
229         d->LastHistoryIndex = 0;
230 }
231
232 /*
233  * the following is based on parts of wavegain.c
234  */
235
236 static FLAC__int64 dither_output_(DitherContext *d, FLAC__bool do_dithering, int shapingtype, int i, double Sum, int k)
237 {
238         union {
239                 double d;
240                 FLAC__int64 i;
241         } doubletmp;
242         double Sum2;
243         FLAC__int64 val;
244
245 #define ROUND64(x)   ( doubletmp.d = (x) + d->Add + (FLAC__int64)FLAC__I64L(0x001FFFFD80000000), doubletmp.i - (FLAC__int64)FLAC__I64L(0x433FFFFD80000000) )
246
247         if(do_dithering) {
248                 if(shapingtype == 0) {
249                         double  tmp = random_equi_(d->Dither);
250                         Sum2 = tmp - d->LastRandomNumber [k];
251                         d->LastRandomNumber [k] = (int)tmp;
252                         Sum2 = Sum += Sum2;
253                         val = ROUND64(Sum2) & d->Mask;
254                 }
255                 else {
256                         Sum2 = random_triangular_(d->Dither) - scalar16_(d->DitherHistory[k], d->FilterCoeff + i);
257                         Sum += d->DitherHistory [k] [(-1-i)&15] = (float)Sum2;
258                         Sum2 = Sum + scalar16_(d->ErrorHistory [k], d->FilterCoeff + i);
259                         val = ROUND64(Sum2) & d->Mask;
260                         d->ErrorHistory [k] [(-1-i)&15] = (float)(Sum - val);
261                 }
262                 return val;
263         }
264         else
265                 return ROUND64(Sum);
266
267 #undef ROUND64
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
301 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)
302 {
303         static const FLAC__int32 conv_factors_[33] = {
304                 -1, /* 0 bits-per-sample (not supported) */
305                 -1, /* 1 bits-per-sample (not supported) */
306                 -1, /* 2 bits-per-sample (not supported) */
307                 -1, /* 3 bits-per-sample (not supported) */
308                 268435456, /* 4 bits-per-sample */
309                 134217728, /* 5 bits-per-sample */
310                 67108864, /* 6 bits-per-sample */
311                 33554432, /* 7 bits-per-sample */
312                 16777216, /* 8 bits-per-sample */
313                 8388608, /* 9 bits-per-sample */
314                 4194304, /* 10 bits-per-sample */
315                 2097152, /* 11 bits-per-sample */
316                 1048576, /* 12 bits-per-sample */
317                 524288, /* 13 bits-per-sample */
318                 262144, /* 14 bits-per-sample */
319                 131072, /* 15 bits-per-sample */
320                 65536, /* 16 bits-per-sample */
321                 32768, /* 17 bits-per-sample */
322                 16384, /* 18 bits-per-sample */
323                 8192, /* 19 bits-per-sample */
324                 4096, /* 20 bits-per-sample */
325                 2048, /* 21 bits-per-sample */
326                 1024, /* 22 bits-per-sample */
327                 512, /* 23 bits-per-sample */
328                 256, /* 24 bits-per-sample */
329                 128, /* 25 bits-per-sample */
330                 64, /* 26 bits-per-sample */
331                 32, /* 27 bits-per-sample */
332                 16, /* 28 bits-per-sample */
333                 8, /* 29 bits-per-sample */
334                 4, /* 30 bits-per-sample */
335                 2, /* 31 bits-per-sample */
336                 1 /* 32 bits-per-sample */
337         };
338         static const FLAC__int64 hard_clip_factors_[33] = {
339                 0, /* 0 bits-per-sample (not supported) */
340                 0, /* 1 bits-per-sample (not supported) */
341                 0, /* 2 bits-per-sample (not supported) */
342                 0, /* 3 bits-per-sample (not supported) */
343                 -8, /* 4 bits-per-sample */
344                 -16, /* 5 bits-per-sample */
345                 -32, /* 6 bits-per-sample */
346                 -64, /* 7 bits-per-sample */
347                 -128, /* 8 bits-per-sample */
348                 -256, /* 9 bits-per-sample */
349                 -512, /* 10 bits-per-sample */
350                 -1024, /* 11 bits-per-sample */
351                 -2048, /* 12 bits-per-sample */
352                 -4096, /* 13 bits-per-sample */
353                 -8192, /* 14 bits-per-sample */
354                 -16384, /* 15 bits-per-sample */
355                 -32768, /* 16 bits-per-sample */
356                 -65536, /* 17 bits-per-sample */
357                 -131072, /* 18 bits-per-sample */
358                 -262144, /* 19 bits-per-sample */
359                 -524288, /* 20 bits-per-sample */
360                 -1048576, /* 21 bits-per-sample */
361                 -2097152, /* 22 bits-per-sample */
362                 -4194304, /* 23 bits-per-sample */
363                 -8388608, /* 24 bits-per-sample */
364                 -16777216, /* 25 bits-per-sample */
365                 -33554432, /* 26 bits-per-sample */
366                 -67108864, /* 27 bits-per-sample */
367                 -134217728, /* 28 bits-per-sample */
368                 -268435456, /* 29 bits-per-sample */
369                 -536870912, /* 30 bits-per-sample */
370                 -1073741824, /* 31 bits-per-sample */
371                 (FLAC__int64)(-1073741824) * 2 /* 32 bits-per-sample */
372         };
373         const FLAC__int32 conv_factor = conv_factors_[target_bps];
374         const FLAC__int64 hard_clip_factor = hard_clip_factors_[target_bps];
375         /*
376          * The integer input coming in has a varying range based on the
377          * source_bps.  We want to normalize it to [-1.0, 1.0) so instead
378          * of doing two multiplies on each sample, we just multiple
379          * 'scale' by 1/(2^(source_bps-1))
380          */
381         const double multi_scale = scale / (double)(1u << (source_bps-1));
382
383         FLAC__byte * const start = data_out;
384         unsigned i, channel;
385         const FLAC__int32 *input_;
386         double sample;
387         const unsigned bytes_per_sample = target_bps / 8;
388         const unsigned last_history_index = dither_context->LastHistoryIndex;
389         NoiseShaping noise_shaping = dither_context->ShapingType;
390         FLAC__int64 val64;
391         FLAC__int32 val32;
392         FLAC__int32 uval32;
393         const FLAC__uint32 twiggle = 1u << (target_bps - 1);
394
395         FLAC__ASSERT(channels > 0 && channels <= FLAC_SHARE__MAX_SUPPORTED_CHANNELS);
396         FLAC__ASSERT(source_bps >= 4);
397         FLAC__ASSERT(target_bps >= 4);
398         FLAC__ASSERT(source_bps <= 32);
399         FLAC__ASSERT(target_bps < 32);
400         FLAC__ASSERT((target_bps & 7) == 0);
401
402         for(channel = 0; channel < channels; channel++) {
403                 const unsigned incr = bytes_per_sample * channels;
404                 data_out = start + bytes_per_sample * channel;
405                 input_ = input[channel];
406                 for(i = 0; i < wide_samples; i++, data_out += incr) {
407                         sample = (double)input_[i] * multi_scale;
408
409                         if(hard_limit) {
410                                 /* hard 6dB limiting */
411                                 if(sample < -0.5)
412                                         sample = tanh((sample + 0.5) / (1-0.5)) * (1-0.5) - 0.5;
413                                 else if(sample > 0.5)
414                                         sample = tanh((sample - 0.5) / (1-0.5)) * (1-0.5) + 0.5;
415                         }
416                         sample *= 2147483647.;
417
418                         val64 = dither_output_(dither_context, do_dithering, noise_shaping, (i + last_history_index) % 32, sample, channel) / conv_factor;
419
420                         val32 = (FLAC__int32)val64;
421                         if(val64 >= -hard_clip_factor)
422                                 val32 = (FLAC__int32)(-(hard_clip_factor+1));
423                         else if(val64 < hard_clip_factor)
424                                 val32 = (FLAC__int32)hard_clip_factor;
425
426                         uval32 = (FLAC__uint32)val32;
427                         if (unsigned_data_out)
428                                 uval32 ^= twiggle;
429
430                         if (little_endian_data_out) {
431                                 switch(target_bps) {
432                                         case 24:
433                                                 data_out[2] = (FLAC__byte)(uval32 >> 16);
434                                                 /* fall through */
435                                         case 16:
436                                                 data_out[1] = (FLAC__byte)(uval32 >> 8);
437                                                 /* fall through */
438                                         case 8:
439                                                 data_out[0] = (FLAC__byte)uval32;
440                                                 break;
441                                 }
442                         }
443                         else {
444                                 switch(target_bps) {
445                                         case 24:
446                                                 data_out[0] = (FLAC__byte)(uval32 >> 16);
447                                                 data_out[1] = (FLAC__byte)(uval32 >> 8);
448                                                 data_out[2] = (FLAC__byte)uval32;
449                                                 break;
450                                         case 16:
451                                                 data_out[0] = (FLAC__byte)(uval32 >> 8);
452                                                 data_out[1] = (FLAC__byte)uval32;
453                                                 break;
454                                         case 8:
455                                                 data_out[0] = (FLAC__byte)uval32;
456                                                 break;
457                                 }
458                         }
459                 }
460         }
461         dither_context->LastHistoryIndex = (last_history_index + wide_samples) % 32;
462
463         return wide_samples * channels * (target_bps/8);
464 }