fix a calcuation bug in FLAC__lpc_compute_best_order()
[platform/upstream/flac.git] / src / libFLAC / lpc.c
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2000,2001,2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <math.h>
33 #include "FLAC/assert.h"
34 #include "FLAC/format.h"
35 #include "private/bitmath.h"
36 #include "private/lpc.h"
37 #if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
38 #include <stdio.h>
39 #endif
40
41 #ifndef FLAC__INTEGER_ONLY_LIBRARY
42
43 #ifndef M_LN2
44 /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
45 #define M_LN2 0.69314718055994530942
46 #endif
47
48 void FLAC__lpc_window_data(const FLAC__real in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
49 {
50         unsigned i;
51         for(i = 0; i < data_len; i++)
52                 out[i] = in[i] * window[i];
53 }
54
55 void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
56 {
57         /* a readable, but slower, version */
58 #if 0
59         FLAC__real d;
60         unsigned i;
61
62         FLAC__ASSERT(lag > 0);
63         FLAC__ASSERT(lag <= data_len);
64
65         /*
66          * Technically we should subtract the mean first like so:
67          *   for(i = 0; i < data_len; i++)
68          *     data[i] -= mean;
69          * but it appears not to make enough of a difference to matter, and
70          * most signals are already closely centered around zero
71          */
72         while(lag--) {
73                 for(i = lag, d = 0.0; i < data_len; i++)
74                         d += data[i] * data[i - lag];
75                 autoc[lag] = d;
76         }
77 #endif
78
79         /*
80          * this version tends to run faster because of better data locality
81          * ('data_len' is usually much larger than 'lag')
82          */
83         FLAC__real d;
84         unsigned sample, coeff;
85         const unsigned limit = data_len - lag;
86
87         FLAC__ASSERT(lag > 0);
88         FLAC__ASSERT(lag <= data_len);
89
90         for(coeff = 0; coeff < lag; coeff++)
91                 autoc[coeff] = 0.0;
92         for(sample = 0; sample <= limit; sample++) {
93                 d = data[sample];
94                 for(coeff = 0; coeff < lag; coeff++)
95                         autoc[coeff] += d * data[sample+coeff];
96         }
97         for(; sample < data_len; sample++) {
98                 d = data[sample];
99                 for(coeff = 0; coeff < data_len - sample; coeff++)
100                         autoc[coeff] += d * data[sample+coeff];
101         }
102 }
103
104 void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[])
105 {
106         unsigned i, j;
107         FLAC__double r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER];
108
109         FLAC__ASSERT(0 < max_order);
110         FLAC__ASSERT(max_order <= FLAC__MAX_LPC_ORDER);
111         FLAC__ASSERT(autoc[0] != 0.0);
112
113         err = autoc[0];
114
115         for(i = 0; i < max_order; i++) {
116                 /* Sum up this iteration's reflection coefficient. */
117                 r = -autoc[i+1];
118                 for(j = 0; j < i; j++)
119                         r -= lpc[j] * autoc[i-j];
120                 ref[i] = (r/=err);
121
122                 /* Update LPC coefficients and total error. */
123                 lpc[i]=r;
124                 for(j = 0; j < (i>>1); j++) {
125                         FLAC__double tmp = lpc[j];
126                         lpc[j] += r * lpc[i-1-j];
127                         lpc[i-1-j] += r * tmp;
128                 }
129                 if(i & 1)
130                         lpc[j] += lpc[j] * r;
131
132                 err *= (1.0 - r * r);
133
134                 /* save this order */
135                 for(j = 0; j <= i; j++)
136                         lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
137                 error[i] = err;
138         }
139 }
140
141 int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift)
142 {
143         unsigned i;
144         FLAC__double d, cmax = -1e32;
145         FLAC__int32 qmax, qmin;
146         const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1;
147         const int min_shiftlimit = -max_shiftlimit - 1;
148
149         FLAC__ASSERT(precision > 0);
150         FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION);
151
152         /* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */
153         precision--;
154         qmax = 1 << precision;
155         qmin = -qmax;
156         qmax--;
157
158         for(i = 0; i < order; i++) {
159                 if(lp_coeff[i] == 0.0)
160                         continue;
161                 d = fabs(lp_coeff[i]);
162                 if(d > cmax)
163                         cmax = d;
164         }
165 redo_it:
166         if(cmax <= 0.0) {
167                 /* => coefficients are all 0, which means our constant-detect didn't work */
168                 return 2;
169         }
170         else {
171                 int log2cmax;
172
173                 (void)frexp(cmax, &log2cmax);
174                 log2cmax--;
175                 *shift = (int)precision - log2cmax - 1;
176
177                 if(*shift < min_shiftlimit || *shift > max_shiftlimit) {
178 #if 0
179                         /*@@@ this does not seem to help at all, but was not extensively tested either: */
180                         if(*shift > max_shiftlimit)
181                                 *shift = max_shiftlimit;
182                         else
183 #endif
184                                 return 1;
185                 }
186         }
187
188         if(*shift >= 0) {
189                 for(i = 0; i < order; i++) {
190                         qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift));
191
192                         /* double-check the result */
193                         if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) {
194 #ifdef FLAC__OVERFLOW_DETECT
195                                 fprintf(stderr,"FLAC__lpc_quantize_coefficients: compensating for overflow, qlp_coeff[%u]=%d, lp_coeff[%u]=%f, cmax=%f, precision=%u, shift=%d, q=%f, f(q)=%f\n", i, qlp_coeff[i], i, lp_coeff[i], cmax, precision, *shift, (FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift), floor((FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift)));
196 #endif
197                                 cmax *= 2.0;
198                                 goto redo_it;
199                         }
200                 }
201         }
202         else { /* (*shift < 0) */
203                 const int nshift = -(*shift);
204 #ifdef DEBUG
205                 fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift = %d\n", *shift);
206 #endif
207                 for(i = 0; i < order; i++) {
208                         qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift));
209
210                         /* double-check the result */
211                         if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) {
212 #ifdef FLAC__OVERFLOW_DETECT
213                                 fprintf(stderr,"FLAC__lpc_quantize_coefficients: compensating for overflow, qlp_coeff[%u]=%d, lp_coeff[%u]=%f, cmax=%f, precision=%u, shift=%d, q=%f, f(q)=%f\n", i, qlp_coeff[i], i, lp_coeff[i], cmax, precision, *shift, (FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift), floor((FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift)));
214 #endif
215                                 cmax *= 2.0;
216                                 goto redo_it;
217                         }
218                 }
219         }
220
221         return 0;
222 }
223
224 void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
225 {
226 #ifdef FLAC__OVERFLOW_DETECT
227         FLAC__int64 sumo;
228 #endif
229         unsigned i, j;
230         FLAC__int32 sum;
231         const FLAC__int32 *history;
232
233 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
234         fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
235         for(i=0;i<order;i++)
236                 fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
237         fprintf(stderr,"\n");
238 #endif
239         FLAC__ASSERT(order > 0);
240
241         for(i = 0; i < data_len; i++) {
242 #ifdef FLAC__OVERFLOW_DETECT
243                 sumo = 0;
244 #endif
245                 sum = 0;
246                 history = data;
247                 for(j = 0; j < order; j++) {
248                         sum += qlp_coeff[j] * (*(--history));
249 #ifdef FLAC__OVERFLOW_DETECT
250                         sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
251 #if defined _MSC_VER
252                         if(sumo > 2147483647I64 || sumo < -2147483648I64)
253                                 fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
254 #else
255                         if(sumo > 2147483647ll || sumo < -2147483648ll)
256                                 fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,sumo);
257 #endif
258 #endif
259                 }
260                 *(residual++) = *(data++) - (sum >> lp_quantization);
261         }
262
263         /* Here's a slower but clearer version:
264         for(i = 0; i < data_len; i++) {
265                 sum = 0;
266                 for(j = 0; j < order; j++)
267                         sum += qlp_coeff[j] * data[i-j-1];
268                 residual[i] = data[i] - (sum >> lp_quantization);
269         }
270         */
271 }
272
273 void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
274 {
275         unsigned i, j;
276         FLAC__int64 sum;
277         const FLAC__int32 *history;
278
279 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
280         fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
281         for(i=0;i<order;i++)
282                 fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
283         fprintf(stderr,"\n");
284 #endif
285         FLAC__ASSERT(order > 0);
286
287         for(i = 0; i < data_len; i++) {
288                 sum = 0;
289                 history = data;
290                 for(j = 0; j < order; j++)
291                         sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
292 #ifdef FLAC__OVERFLOW_DETECT
293                 if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
294                         fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization);
295                         break;
296                 }
297                 if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
298                         fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%lld, residual=%lld\n", i, *data, sum >> lp_quantization, (FLAC__int64)(*data) - (sum >> lp_quantization));
299                         break;
300                 }
301 #endif
302                 *(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization);
303         }
304 }
305
306 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
307
308 void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
309 {
310 #ifdef FLAC__OVERFLOW_DETECT
311         FLAC__int64 sumo;
312 #endif
313         unsigned i, j;
314         FLAC__int32 sum;
315         const FLAC__int32 *history;
316
317 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
318         fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
319         for(i=0;i<order;i++)
320                 fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
321         fprintf(stderr,"\n");
322 #endif
323         FLAC__ASSERT(order > 0);
324
325         for(i = 0; i < data_len; i++) {
326 #ifdef FLAC__OVERFLOW_DETECT
327                 sumo = 0;
328 #endif
329                 sum = 0;
330                 history = data;
331                 for(j = 0; j < order; j++) {
332                         sum += qlp_coeff[j] * (*(--history));
333 #ifdef FLAC__OVERFLOW_DETECT
334                         sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
335 #if defined _MSC_VER
336                         if(sumo > 2147483647I64 || sumo < -2147483648I64)
337                                 fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%I64d\n",i,j,qlp_coeff[j],*history,sumo);
338 #else
339                         if(sumo > 2147483647ll || sumo < -2147483648ll)
340                                 fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%lld\n",i,j,qlp_coeff[j],*history,sumo);
341 #endif
342 #endif
343                 }
344                 *(data++) = *(residual++) + (sum >> lp_quantization);
345         }
346
347         /* Here's a slower but clearer version:
348         for(i = 0; i < data_len; i++) {
349                 sum = 0;
350                 for(j = 0; j < order; j++)
351                         sum += qlp_coeff[j] * data[i-j-1];
352                 data[i] = residual[i] + (sum >> lp_quantization);
353         }
354         */
355 }
356
357 void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
358 {
359         unsigned i, j;
360         FLAC__int64 sum;
361         const FLAC__int32 *history;
362
363 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
364         fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
365         for(i=0;i<order;i++)
366                 fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
367         fprintf(stderr,"\n");
368 #endif
369         FLAC__ASSERT(order > 0);
370
371         for(i = 0; i < data_len; i++) {
372                 sum = 0;
373                 history = data;
374                 for(j = 0; j < order; j++)
375                         sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
376 #ifdef FLAC__OVERFLOW_DETECT
377                 if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
378                         fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization);
379                         break;
380                 }
381                 if(FLAC__bitmath_silog2_wide((FLAC__int64)(*residual) + (sum >> lp_quantization)) > 32) {
382                         fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%lld, data=%lld\n", i, *residual, sum >> lp_quantization, (FLAC__int64)(*residual) + (sum >> lp_quantization));
383                         break;
384                 }
385 #endif
386                 *(data++) = *(residual++) + (FLAC__int32)(sum >> lp_quantization);
387         }
388 }
389
390 #ifndef FLAC__INTEGER_ONLY_LIBRARY
391
392 FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)
393 {
394         FLAC__double error_scale;
395
396         FLAC__ASSERT(total_samples > 0);
397
398         error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
399
400         return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale);
401 }
402
403 FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale)
404 {
405         if(lpc_error > 0.0) {
406                 FLAC__double bps = (FLAC__double)0.5 * log(error_scale * lpc_error) / M_LN2;
407                 if(bps >= 0.0)
408                         return bps;
409                 else
410                         return 0.0;
411         }
412         else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */
413                 return 1e32;
414         }
415         else {
416                 return 0.0;
417         }
418 }
419
420 unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order)
421 {
422         unsigned order, index, best_index; /* 'index' the index into lpc_error; index==order-1 since lpc_error[0] is for order==1, lpc_error[1] is for order==2, etc */
423         FLAC__double bits, best_bits, error_scale;
424
425         FLAC__ASSERT(max_order > 0);
426         FLAC__ASSERT(total_samples > 0);
427
428         error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
429
430         best_index = 0;
431         best_bits = (unsigned)(-1);
432
433         for(index = 0, order = 1; index < max_order; index++, order++) {
434                 bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[index], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * overhead_bits_per_order);
435                 if(bits < best_bits) {
436                         best_index = index;
437                         best_bits = bits;
438                 }
439         }
440
441         return best_index+1; /* +1 since index of lpc_error[] is order-1 */
442 }
443
444 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */