vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

lpc.c (14263B)


      1 /* libFLAC - Free Lossless Audio Codec library
      2  * Copyright (C) 2000,2001,2002,2003,2004,2005  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_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
     49 {
     50 	/* a readable, but slower, version */
     51 #if 0
     52 	FLAC__real d;
     53 	unsigned i;
     54 
     55 	FLAC__ASSERT(lag > 0);
     56 	FLAC__ASSERT(lag <= data_len);
     57 
     58 	while(lag--) {
     59 		for(i = lag, d = 0.0; i < data_len; i++)
     60 			d += data[i] * data[i - lag];
     61 		autoc[lag] = d;
     62 	}
     63 #endif
     64 
     65 	/*
     66 	 * this version tends to run faster because of better data locality
     67 	 * ('data_len' is usually much larger than 'lag')
     68 	 */
     69 	FLAC__real d;
     70 	unsigned sample, coeff;
     71 	const unsigned limit = data_len - lag;
     72 
     73 	FLAC__ASSERT(lag > 0);
     74 	FLAC__ASSERT(lag <= data_len);
     75 
     76 	for(coeff = 0; coeff < lag; coeff++)
     77 		autoc[coeff] = 0.0;
     78 	for(sample = 0; sample <= limit; sample++) {
     79 		d = data[sample];
     80 		for(coeff = 0; coeff < lag; coeff++)
     81 			autoc[coeff] += d * data[sample+coeff];
     82 	}
     83 	for(; sample < data_len; sample++) {
     84 		d = data[sample];
     85 		for(coeff = 0; coeff < data_len - sample; coeff++)
     86 			autoc[coeff] += d * data[sample+coeff];
     87 	}
     88 }
     89 
     90 void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[])
     91 {
     92 	unsigned i, j;
     93 	FLAC__double r, err, ref[FLAC__MAX_LPC_ORDER], lpc[FLAC__MAX_LPC_ORDER];
     94 
     95 	FLAC__ASSERT(0 < max_order);
     96 	FLAC__ASSERT(max_order <= FLAC__MAX_LPC_ORDER);
     97 	FLAC__ASSERT(autoc[0] != 0.0);
     98 
     99 	err = autoc[0];
    100 
    101 	for(i = 0; i < max_order; i++) {
    102 		/* Sum up this iteration's reflection coefficient. */
    103 		r = -autoc[i+1];
    104 		for(j = 0; j < i; j++)
    105 			r -= lpc[j] * autoc[i-j];
    106 		ref[i] = (r/=err);
    107 
    108 		/* Update LPC coefficients and total error. */
    109 		lpc[i]=r;
    110 		for(j = 0; j < (i>>1); j++) {
    111 			FLAC__double tmp = lpc[j];
    112 			lpc[j] += r * lpc[i-1-j];
    113 			lpc[i-1-j] += r * tmp;
    114 		}
    115 		if(i & 1)
    116 			lpc[j] += lpc[j] * r;
    117 
    118 		err *= (1.0 - r * r);
    119 
    120 		/* save this order */
    121 		for(j = 0; j <= i; j++)
    122 			lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
    123 		error[i] = err;
    124 	}
    125 }
    126 
    127 int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift)
    128 {
    129 	unsigned i;
    130 	FLAC__double d, cmax = -1e32;
    131 	FLAC__int32 qmax, qmin;
    132 	const int max_shiftlimit = (1 << (FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN-1)) - 1;
    133 	const int min_shiftlimit = -max_shiftlimit - 1;
    134 
    135 	FLAC__ASSERT(precision > 0);
    136 	FLAC__ASSERT(precision >= FLAC__MIN_QLP_COEFF_PRECISION);
    137 
    138 	/* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */
    139 	precision--;
    140 	qmax = 1 << precision;
    141 	qmin = -qmax;
    142 	qmax--;
    143 
    144 	for(i = 0; i < order; i++) {
    145 		if(lp_coeff[i] == 0.0)
    146 			continue;
    147 		d = fabs(lp_coeff[i]);
    148 		if(d > cmax)
    149 			cmax = d;
    150 	}
    151 redo_it:
    152 	if(cmax <= 0.0) {
    153 		/* => coefficients are all 0, which means our constant-detect didn't work */
    154 		return 2;
    155 	}
    156 	else {
    157 		int log2cmax;
    158 
    159 		(void)frexp(cmax, &log2cmax);
    160 		log2cmax--;
    161 		*shift = (int)precision - log2cmax - 1;
    162 
    163 		if(*shift < min_shiftlimit || *shift > max_shiftlimit) {
    164 #if 0
    165 			/*@@@ this does not seem to help at all, but was not extensively tested either: */
    166 			if(*shift > max_shiftlimit)
    167 				*shift = max_shiftlimit;
    168 			else
    169 #endif
    170 				return 1;
    171 		}
    172 	}
    173 
    174 	if(*shift >= 0) {
    175 		for(i = 0; i < order; i++) {
    176 			qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] * (FLAC__double)(1 << *shift));
    177 
    178 			/* double-check the result */
    179 			if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) {
    180 #ifdef FLAC__OVERFLOW_DETECT
    181 				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)));
    182 #endif
    183 				cmax *= 2.0;
    184 				goto redo_it;
    185 			}
    186 		}
    187 	}
    188 	else { /* (*shift < 0) */
    189 		const int nshift = -(*shift);
    190 #ifdef DEBUG
    191 		fprintf(stderr,"FLAC__lpc_quantize_coefficients: negative shift = %d\n", *shift);
    192 #endif
    193 		for(i = 0; i < order; i++) {
    194 			qlp_coeff[i] = (FLAC__int32)floor((FLAC__double)lp_coeff[i] / (FLAC__double)(1 << nshift));
    195 
    196 			/* double-check the result */
    197 			if(qlp_coeff[i] > qmax || qlp_coeff[i] < qmin) {
    198 #ifdef FLAC__OVERFLOW_DETECT
    199 				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)));
    200 #endif
    201 				cmax *= 2.0;
    202 				goto redo_it;
    203 			}
    204 		}
    205 	}
    206 
    207 	return 0;
    208 }
    209 
    210 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[])
    211 {
    212 #ifdef FLAC__OVERFLOW_DETECT
    213 	FLAC__int64 sumo;
    214 #endif
    215 	unsigned i, j;
    216 	FLAC__int32 sum;
    217 	const FLAC__int32 *history;
    218 
    219 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
    220 	fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
    221 	for(i=0;i<order;i++)
    222 		fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
    223 	fprintf(stderr,"\n");
    224 #endif
    225 	FLAC__ASSERT(order > 0);
    226 
    227 	for(i = 0; i < data_len; i++) {
    228 #ifdef FLAC__OVERFLOW_DETECT
    229 		sumo = 0;
    230 #endif
    231 		sum = 0;
    232 		history = data;
    233 		for(j = 0; j < order; j++) {
    234 			sum += qlp_coeff[j] * (*(--history));
    235 #ifdef FLAC__OVERFLOW_DETECT
    236 			sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
    237 #if defined _MSC_VER
    238 			if(sumo > 2147483647I64 || sumo < -2147483648I64)
    239 				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);
    240 #else
    241 			if(sumo > 2147483647ll || sumo < -2147483648ll)
    242 				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);
    243 #endif
    244 #endif
    245 		}
    246 		*(residual++) = *(data++) - (sum >> lp_quantization);
    247 	}
    248 
    249 	/* Here's a slower but clearer version:
    250 	for(i = 0; i < data_len; i++) {
    251 		sum = 0;
    252 		for(j = 0; j < order; j++)
    253 			sum += qlp_coeff[j] * data[i-j-1];
    254 		residual[i] = data[i] - (sum >> lp_quantization);
    255 	}
    256 	*/
    257 }
    258 
    259 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[])
    260 {
    261 	unsigned i, j;
    262 	FLAC__int64 sum;
    263 	const FLAC__int32 *history;
    264 
    265 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
    266 	fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
    267 	for(i=0;i<order;i++)
    268 		fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
    269 	fprintf(stderr,"\n");
    270 #endif
    271 	FLAC__ASSERT(order > 0);
    272 
    273 	for(i = 0; i < data_len; i++) {
    274 		sum = 0;
    275 		history = data;
    276 		for(j = 0; j < order; j++)
    277 			sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
    278 #ifdef FLAC__OVERFLOW_DETECT
    279 		if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
    280 			fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization);
    281 			break;
    282 		}
    283 		if(FLAC__bitmath_silog2_wide((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) {
    284 			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));
    285 			break;
    286 		}
    287 #endif
    288 		*(residual++) = *(data++) - (FLAC__int32)(sum >> lp_quantization);
    289 	}
    290 }
    291 
    292 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
    293 
    294 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[])
    295 {
    296 #ifdef FLAC__OVERFLOW_DETECT
    297 	FLAC__int64 sumo;
    298 #endif
    299 	unsigned i, j;
    300 	FLAC__int32 sum;
    301 	const FLAC__int32 *history;
    302 
    303 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
    304 	fprintf(stderr,"FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
    305 	for(i=0;i<order;i++)
    306 		fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
    307 	fprintf(stderr,"\n");
    308 #endif
    309 	FLAC__ASSERT(order > 0);
    310 
    311 	for(i = 0; i < data_len; i++) {
    312 #ifdef FLAC__OVERFLOW_DETECT
    313 		sumo = 0;
    314 #endif
    315 		sum = 0;
    316 		history = data;
    317 		for(j = 0; j < order; j++) {
    318 			sum += qlp_coeff[j] * (*(--history));
    319 #ifdef FLAC__OVERFLOW_DETECT
    320 			sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history);
    321 #if defined _MSC_VER
    322 			if(sumo > 2147483647I64 || sumo < -2147483648I64)
    323 				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);
    324 #else
    325 			if(sumo > 2147483647ll || sumo < -2147483648ll)
    326 				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);
    327 #endif
    328 #endif
    329 		}
    330 		*(data++) = *(residual++) + (sum >> lp_quantization);
    331 	}
    332 
    333 	/* Here's a slower but clearer version:
    334 	for(i = 0; i < data_len; i++) {
    335 		sum = 0;
    336 		for(j = 0; j < order; j++)
    337 			sum += qlp_coeff[j] * data[i-j-1];
    338 		data[i] = residual[i] + (sum >> lp_quantization);
    339 	}
    340 	*/
    341 }
    342 
    343 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[])
    344 {
    345 	unsigned i, j;
    346 	FLAC__int64 sum;
    347 	const FLAC__int32 *history;
    348 
    349 #ifdef FLAC__OVERFLOW_DETECT_VERBOSE
    350 	fprintf(stderr,"FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d",data_len,order,lp_quantization);
    351 	for(i=0;i<order;i++)
    352 		fprintf(stderr,", q[%u]=%d",i,qlp_coeff[i]);
    353 	fprintf(stderr,"\n");
    354 #endif
    355 	FLAC__ASSERT(order > 0);
    356 
    357 	for(i = 0; i < data_len; i++) {
    358 		sum = 0;
    359 		history = data;
    360 		for(j = 0; j < order; j++)
    361 			sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history));
    362 #ifdef FLAC__OVERFLOW_DETECT
    363 		if(FLAC__bitmath_silog2_wide(sum >> lp_quantization) > 32) {
    364 			fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%lld\n", i, sum >> lp_quantization);
    365 			break;
    366 		}
    367 		if(FLAC__bitmath_silog2_wide((FLAC__int64)(*residual) + (sum >> lp_quantization)) > 32) {
    368 			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));
    369 			break;
    370 		}
    371 #endif
    372 		*(data++) = *(residual++) + (FLAC__int32)(sum >> lp_quantization);
    373 	}
    374 }
    375 
    376 #ifndef FLAC__INTEGER_ONLY_LIBRARY
    377 
    378 FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)
    379 {
    380 	FLAC__double error_scale;
    381 
    382 	FLAC__ASSERT(total_samples > 0);
    383 
    384 	error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
    385 
    386 	return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error, error_scale);
    387 }
    388 
    389 FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale)
    390 {
    391 	if(lpc_error > 0.0) {
    392 		FLAC__double bps = (FLAC__double)0.5 * log(error_scale * lpc_error) / M_LN2;
    393 		if(bps >= 0.0)
    394 			return bps;
    395 		else
    396 			return 0.0;
    397 	}
    398 	else if(lpc_error < 0.0) { /* error should not be negative but can happen due to inadequate floating-point resolution */
    399 		return 1e32;
    400 	}
    401 	else {
    402 		return 0.0;
    403 	}
    404 }
    405 
    406 unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned bits_per_signal_sample)
    407 {
    408 	unsigned order, best_order;
    409 	FLAC__double best_bits, tmp_bits, error_scale;
    410 
    411 	FLAC__ASSERT(max_order > 0);
    412 	FLAC__ASSERT(total_samples > 0);
    413 
    414 	error_scale = 0.5 * M_LN2 * M_LN2 / (FLAC__double)total_samples;
    415 
    416 	best_order = 0;
    417 	best_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[0], error_scale) * (FLAC__double)total_samples;
    418 
    419 	for(order = 1; order < max_order; order++) {
    420 		tmp_bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(lpc_error[order], error_scale) * (FLAC__double)(total_samples - order) + (FLAC__double)(order * bits_per_signal_sample);
    421 		if(tmp_bits < best_bits) {
    422 			best_order = order;
    423 			best_bits = tmp_bits;
    424 		}
    425 	}
    426 
    427 	return best_order+1; /* +1 since index of lpc_error[] is order-1 */
    428 }
    429 
    430 #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */