2001-02-08 00:38:41 +00:00
/* libFLAC - Free Lossless Audio Codec library
2009-01-07 07:31:28 +00:00
* Copyright ( C ) 2000 , 2001 , 2002 , 2003 , 2004 , 2005 , 2006 , 2007 , 2008 , 2009 Josh Coalson
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* - Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
2000-12-10 04:09:52 +00:00
*
2003-01-31 23:34:56 +00:00
* - Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* - Neither the name of the Xiph . org Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE FOUNDATION OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL ,
* EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO ,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
2000-12-10 04:09:52 +00:00
*/
2006-05-24 04:41:36 +00:00
# if HAVE_CONFIG_H
# include <config.h>
# endif
2000-12-10 04:09:52 +00:00
# include <math.h>
2012-05-08 19:23:08 +10:00
# include <inttypes.h>
2001-05-31 20:11:02 +00:00
# include "FLAC/assert.h"
2000-12-10 04:09:52 +00:00
# include "FLAC/format.h"
2002-10-04 05:25:54 +00:00
# include "private/bitmath.h"
2000-12-10 04:09:52 +00:00
# include "private/lpc.h"
2012-04-07 19:24:21 -03:00
# include "private/macros.h"
2002-05-17 06:19:28 +00:00
# if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
# include <stdio.h>
# endif
2000-12-10 04:09:52 +00:00
2009-01-07 07:03:17 +00:00
/* OPT: #undef'ing this may improve the speed on some architectures */
# define FLAC__LPC_UNROLLED_FILTER_LOOPS
2004-11-09 01:34:01 +00:00
# ifndef FLAC__INTEGER_ONLY_LIBRARY
2000-12-10 04:09:52 +00:00
# ifndef M_LN2
/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
# define M_LN2 0.69314718055994530942
# endif
2012-04-07 19:24:21 -03:00
# if !defined(HAVE_LROUND)
# if defined(_MSC_VER)
# include <float.h>
# define copysign _copysign
# elif defined(__GNUC__)
# define copysign __builtin_copysign
# endif
Fix building with MSYS and MinGW(-w64); Improve Makefile.lite build system
This is a patch to allow building of the project using MSYS, MinGW, and MinGW-w64 with the following invocation:
make -f Makefile.lite libFLAC libFLAC++ flac metaflac test_libs_common test_libFLAC test_libFLAC++ test_grabbag test_seeking test_streams utils examples
This patch addresses eight points:
1. `uname -p` in MSYS returns "unknown" so we must use `gcc -dumpmachine` to gain information about the target, 32-bit or 64-bit.
2. MinGW-w64 does not ship with a working iconv.h, so we must disable it under this specific compiler.
3. The code requires <inttypes.h> in a handful of C files, but config.mk did not contain -DHAVE_INTTYPES_H, which under the full build process (I assume) is added by autoconf.
4. The compiler complained when lround() in lpc.c was static, so it is no longer static.
5. Additional scattered linking directives (and reordering) (particularly FLAC, grabbag, and replaygain_analysis) were necessary to build some of the components.
6. The Makefile.lite build system benefited from some cleanup, particularly by rigorously defining all entries, factoring redundancy, and establishing dependencies. (Some typos were fixed too.)
7. Shared objects on Windows use .dll, not .so. (Added *.dll, *.dylib, and *.exe to .gitignore.)
8. To allow more freedom using Makefile.lite without configure, I added the variables USE_OGG and USE_ICONV which can toggle these two components in the build process.
ex: make -f Makefile.lite examples USE_OGG=0 USE_ICONV=0
These improvements make use of some use-time Makefile variable expansion.
Signed-off-by: Erik de Castro Lopo <erikd@mega-nerd.com>
2012-12-29 04:22:59 -06:00
inline long int lround ( double x ) {
2012-04-07 19:24:21 -03:00
return ( long ) ( x + copysign ( 0.5 , x ) ) ;
}
//If this fails, we are in the precence of a mid 90's compiler..move along...
# endif
2007-07-11 04:15:18 +00:00
2007-04-04 00:59:28 +00:00
void FLAC__lpc_window_data ( const FLAC__int32 in [ ] , const FLAC__real window [ ] , FLAC__real out [ ] , unsigned data_len )
2006-04-25 06:38:43 +00:00
{
unsigned i ;
for ( i = 0 ; i < data_len ; i + + )
out [ i ] = in [ i ] * window [ i ] ;
}
2001-06-23 03:03:24 +00:00
void FLAC__lpc_compute_autocorrelation ( const FLAC__real data [ ] , unsigned data_len , unsigned lag , FLAC__real autoc [ ] )
2000-12-10 04:09:52 +00:00
{
2001-05-10 19:29:41 +00:00
/* a readable, but slower, version */
#if 0
2001-06-23 03:03:24 +00:00
FLAC__real d ;
2000-12-10 04:09:52 +00:00
unsigned i ;
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( lag > 0 ) ;
FLAC__ASSERT ( lag < = data_len ) ;
2000-12-10 04:09:52 +00:00
2006-04-28 00:11:31 +00:00
/*
* Technically we should subtract the mean first like so :
* for ( i = 0 ; i < data_len ; i + + )
* data [ i ] - = mean ;
* but it appears not to make enough of a difference to matter , and
* most signals are already closely centered around zero
*/
2000-12-10 04:09:52 +00:00
while ( lag - - ) {
for ( i = lag , d = 0.0 ; i < data_len ; i + + )
d + = data [ i ] * data [ i - lag ] ;
autoc [ lag ] = d ;
}
2001-05-10 19:29:41 +00:00
# endif
/*
* this version tends to run faster because of better data locality
* ( ' data_len ' is usually much larger than ' lag ' )
*/
2001-06-23 03:03:24 +00:00
FLAC__real d ;
2001-05-10 19:29:41 +00:00
unsigned sample , coeff ;
const unsigned limit = data_len - lag ;
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( lag > 0 ) ;
FLAC__ASSERT ( lag < = data_len ) ;
2001-05-10 19:29:41 +00:00
for ( coeff = 0 ; coeff < lag ; coeff + + )
autoc [ coeff ] = 0.0 ;
2001-05-16 19:23:35 +00:00
for ( sample = 0 ; sample < = limit ; sample + + ) {
2001-05-10 19:29:41 +00:00
d = data [ sample ] ;
for ( coeff = 0 ; coeff < lag ; coeff + + )
autoc [ coeff ] + = d * data [ sample + coeff ] ;
}
2001-05-16 19:23:35 +00:00
for ( ; sample < data_len ; sample + + ) {
2001-05-10 19:29:41 +00:00
d = data [ sample ] ;
for ( coeff = 0 ; coeff < data_len - sample ; coeff + + )
autoc [ coeff ] + = d * data [ sample + coeff ] ;
}
2000-12-10 04:09:52 +00:00
}
2006-11-27 16:27:41 +00:00
void FLAC__lpc_compute_lp_coefficients ( const FLAC__real autoc [ ] , unsigned * max_order , FLAC__real lp_coeff [ ] [ FLAC__MAX_LPC_ORDER ] , FLAC__double error [ ] )
2000-12-10 04:09:52 +00:00
{
unsigned i , j ;
2012-02-01 19:58:09 +11:00
FLAC__double r , err , lpc [ FLAC__MAX_LPC_ORDER ] ;
2000-12-10 04:09:52 +00:00
2006-11-27 16:27:41 +00:00
FLAC__ASSERT ( 0 ! = max_order ) ;
FLAC__ASSERT ( 0 < * max_order ) ;
FLAC__ASSERT ( * max_order < = FLAC__MAX_LPC_ORDER ) ;
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( autoc [ 0 ] ! = 0.0 ) ;
2000-12-10 04:09:52 +00:00
err = autoc [ 0 ] ;
2006-11-27 16:27:41 +00:00
for ( i = 0 ; i < * max_order ; i + + ) {
2000-12-10 04:09:52 +00:00
/* Sum up this iteration's reflection coefficient. */
2001-05-24 19:27:08 +00:00
r = - autoc [ i + 1 ] ;
2000-12-10 04:09:52 +00:00
for ( j = 0 ; j < i ; j + + )
r - = lpc [ j ] * autoc [ i - j ] ;
2012-10-12 22:02:49 +11:00
r / = err ;
2000-12-10 04:09:52 +00:00
/* Update LPC coefficients and total error. */
lpc [ i ] = r ;
for ( j = 0 ; j < ( i > > 1 ) ; j + + ) {
2004-10-20 00:21:50 +00:00
FLAC__double tmp = lpc [ j ] ;
2000-12-10 04:09:52 +00:00
lpc [ j ] + = r * lpc [ i - 1 - j ] ;
lpc [ i - 1 - j ] + = r * tmp ;
}
if ( i & 1 )
lpc [ j ] + = lpc [ j ] * r ;
err * = ( 1.0 - r * r ) ;
/* save this order */
for ( j = 0 ; j < = i ; j + + )
2001-07-03 04:37:18 +00:00
lp_coeff [ i ] [ j ] = ( FLAC__real ) ( - lpc [ j ] ) ; /* negate FIR filter coeff to get predictor coeff */
2004-10-20 00:21:50 +00:00
error [ i ] = err ;
2006-11-27 16:27:41 +00:00
2007-01-28 17:37:55 +00:00
/* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */
2006-11-27 16:27:41 +00:00
if ( err = = 0.0 ) {
* max_order = i + 1 ;
return ;
}
2000-12-10 04:09:52 +00:00
}
}
2002-10-04 05:25:54 +00:00
int FLAC__lpc_quantize_coefficients ( const FLAC__real lp_coeff [ ] , unsigned order , unsigned precision , FLAC__int32 qlp_coeff [ ] , int * shift )
2000-12-10 04:09:52 +00:00
{
unsigned i ;
2007-02-02 06:14:41 +00:00
FLAC__double cmax ;
2001-07-03 04:10:21 +00:00
FLAC__int32 qmax , qmin ;
2001-02-28 23:56:03 +00:00
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( precision > 0 ) ;
FLAC__ASSERT ( precision > = FLAC__MIN_QLP_COEFF_PRECISION ) ;
2001-02-28 23:56:03 +00:00
/* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */
precision - - ;
2001-07-03 04:10:21 +00:00
qmax = 1 < < precision ;
qmin = - qmax ;
qmax - - ;
2001-02-28 23:56:03 +00:00
2007-02-02 06:14:41 +00:00
/* calc cmax = max( |lp_coeff[i]| ) */
cmax = 0.0 ;
2001-02-28 23:56:03 +00:00
for ( i = 0 ; i < order ; i + + ) {
2007-02-02 06:14:41 +00:00
const FLAC__double d = fabs ( lp_coeff [ i ] ) ;
2001-02-28 23:56:03 +00:00
if ( d > cmax )
cmax = d ;
}
2007-02-02 06:14:41 +00:00
2001-07-18 23:47:19 +00:00
if ( cmax < = 0.0 ) {
2001-03-01 19:14:05 +00:00
/* => coefficients are all 0, which means our constant-detect didn't work */
2001-02-28 23:56:03 +00:00
return 2 ;
}
else {
2007-02-02 06:14:41 +00:00
const int max_shiftlimit = ( 1 < < ( FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN - 1 ) ) - 1 ;
const int min_shiftlimit = - max_shiftlimit - 1 ;
2001-07-19 17:07:13 +00:00
int log2cmax ;
2001-02-28 23:56:03 +00:00
2002-08-27 05:46:11 +00:00
( void ) frexp ( cmax , & log2cmax ) ;
2001-07-19 17:07:13 +00:00
log2cmax - - ;
* shift = ( int ) precision - log2cmax - 1 ;
2001-02-28 23:56:03 +00:00
2007-02-04 04:18:55 +00:00
if ( * shift > max_shiftlimit )
* shift = max_shiftlimit ;
else if ( * shift < min_shiftlimit )
return 1 ;
2001-02-28 23:56:03 +00:00
}
2001-07-06 00:37:57 +00:00
if ( * shift > = 0 ) {
2007-02-02 06:14:41 +00:00
FLAC__double error = 0.0 ;
FLAC__int32 q ;
2001-07-06 00:37:57 +00:00
for ( i = 0 ; i < order ; i + + ) {
2007-02-02 06:14:41 +00:00
error + = lp_coeff [ i ] * ( 1 < < * shift ) ;
2007-02-09 16:12:20 +00:00
q = lround ( error ) ;
2012-04-07 19:24:21 -03:00
2001-07-03 04:10:21 +00:00
# ifdef FLAC__OVERFLOW_DETECT
2007-02-09 16:12:20 +00:00
if ( q > qmax + 1 ) /* we expect q==qmax+1 occasionally due to rounding */
2007-02-02 06:14:41 +00:00
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f \n " , q , qmax , * shift , cmax , precision + 1 , i , lp_coeff [ i ] ) ;
else if ( q < qmin )
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f \n " , q , qmin , * shift , cmax , precision + 1 , i , lp_coeff [ i ] ) ;
2001-07-03 04:10:21 +00:00
# endif
2007-02-02 06:14:41 +00:00
if ( q > qmax )
q = qmax ;
else if ( q < qmin )
q = qmin ;
error - = q ;
qlp_coeff [ i ] = q ;
2001-07-03 04:10:21 +00:00
}
2001-07-06 00:37:57 +00:00
}
2007-02-02 06:14:41 +00:00
/* negative shift is very rare but due to design flaw, negative shift is
* a NOP in the decoder , so it must be handled specially by scaling down
* coeffs
*/
else {
2001-07-06 00:37:57 +00:00
const int nshift = - ( * shift ) ;
2007-02-02 06:14:41 +00:00
FLAC__double error = 0.0 ;
FLAC__int32 q ;
2001-07-12 21:27:40 +00:00
# ifdef DEBUG
2007-02-03 02:53:29 +00:00
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f \n " , * shift , order , cmax ) ;
2001-07-12 21:27:40 +00:00
# endif
2001-07-06 00:37:57 +00:00
for ( i = 0 ; i < order ; i + + ) {
2007-02-02 06:14:41 +00:00
error + = lp_coeff [ i ] / ( 1 < < nshift ) ;
2007-02-09 16:12:20 +00:00
q = lround ( error ) ;
2001-07-03 04:10:21 +00:00
# ifdef FLAC__OVERFLOW_DETECT
2007-02-09 16:12:20 +00:00
if ( q > qmax + 1 ) /* we expect q==qmax+1 occasionally due to rounding */
2007-02-02 06:14:41 +00:00
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: quantizer overflow: q>qmax %d>%d shift=%d cmax=%f precision=%u lpc[%u]=%f \n " , q , qmax , * shift , cmax , precision + 1 , i , lp_coeff [ i ] ) ;
else if ( q < qmin )
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: quantizer overflow: q<qmin %d<%d shift=%d cmax=%f precision=%u lpc[%u]=%f \n " , q , qmin , * shift , cmax , precision + 1 , i , lp_coeff [ i ] ) ;
2001-07-03 04:10:21 +00:00
# endif
2007-02-02 06:14:41 +00:00
if ( q > qmax )
q = qmax ;
else if ( q < qmin )
q = qmin ;
error - = q ;
qlp_coeff [ i ] = q ;
2001-07-03 04:10:21 +00:00
}
2007-02-02 06:14:41 +00:00
* shift = 0 ;
2000-12-10 04:09:52 +00:00
}
2001-07-06 00:37:57 +00:00
2000-12-10 04:09:52 +00:00
return 0 ;
}
2005-01-26 04:04:38 +00:00
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 [ ] )
2007-07-11 04:15:18 +00:00
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__int64 sumo ;
2000-12-10 04:09:52 +00:00
unsigned i , j ;
2001-06-23 03:03:24 +00:00
FLAC__int32 sum ;
const FLAC__int32 * history ;
2000-12-10 04:09:52 +00:00
2001-04-24 22:54:07 +00:00
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
2000-12-10 04:09:52 +00:00
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients: data_len=%d, order=%u, lpq=%d " , data_len , order , lp_quantization ) ;
for ( i = 0 ; i < order ; i + + )
fprintf ( stderr , " , q[%u]=%d " , i , qlp_coeff [ i ] ) ;
fprintf ( stderr , " \n " ) ;
# endif
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( order > 0 ) ;
2000-12-10 04:09:52 +00:00
for ( i = 0 ; i < data_len ; i + + ) {
sumo = 0 ;
sum = 0 ;
history = data ;
for ( j = 0 ; j < order ; j + + ) {
sum + = qlp_coeff [ j ] * ( * ( - - history ) ) ;
2001-06-23 03:03:24 +00:00
sumo + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * history ) ;
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=% " PRId64 " \n " , i , j , qlp_coeff [ j ] , * history , sumo ) ;
2000-12-10 04:09:52 +00:00
}
* ( residual + + ) = * ( data + + ) - ( sum > > lp_quantization ) ;
}
2001-02-08 00:26:45 +00:00
/* Here's a slower but clearer version:
2000-12-10 04:09:52 +00:00
for ( i = 0 ; i < data_len ; i + + ) {
sum = 0 ;
for ( j = 0 ; j < order ; j + + )
2001-02-08 00:26:45 +00:00
sum + = qlp_coeff [ j ] * data [ i - j - 1 ] ;
2000-12-10 04:09:52 +00:00
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
*/
}
2007-03-13 06:33:52 +00:00
# else /* fully unrolled version for normal use */
{
2007-06-14 06:21:44 +00:00
int i ;
2007-03-13 06:33:52 +00:00
FLAC__int32 sum ;
FLAC__ASSERT ( order > 0 ) ;
FLAC__ASSERT ( order < = 32 ) ;
/*
* We do unique versions up to 12 th order since that ' s the subset limit .
* Also they are roughly ordered to match frequency of occurrence to
* minimize branching .
*/
if ( order < = 12 ) {
if ( order > 8 ) {
if ( order > 10 ) {
if ( order = = 12 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 11 ] * data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 11 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 10 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 9 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
}
else if ( order > 4 ) {
if ( order > 6 ) {
if ( order = = 8 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 7 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 6 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 5 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
}
else {
if ( order > 2 ) {
if ( order = = 4 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 3 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 2 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
else { /* order == 1 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + )
2007-03-13 06:33:52 +00:00
residual [ i ] = data [ i ] - ( ( qlp_coeff [ 0 ] * data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
switch ( order ) {
case 32 : sum + = qlp_coeff [ 31 ] * data [ i - 32 ] ;
case 31 : sum + = qlp_coeff [ 30 ] * data [ i - 31 ] ;
case 30 : sum + = qlp_coeff [ 29 ] * data [ i - 30 ] ;
case 29 : sum + = qlp_coeff [ 28 ] * data [ i - 29 ] ;
case 28 : sum + = qlp_coeff [ 27 ] * data [ i - 28 ] ;
case 27 : sum + = qlp_coeff [ 26 ] * data [ i - 27 ] ;
case 26 : sum + = qlp_coeff [ 25 ] * data [ i - 26 ] ;
case 25 : sum + = qlp_coeff [ 24 ] * data [ i - 25 ] ;
case 24 : sum + = qlp_coeff [ 23 ] * data [ i - 24 ] ;
case 23 : sum + = qlp_coeff [ 22 ] * data [ i - 23 ] ;
case 22 : sum + = qlp_coeff [ 21 ] * data [ i - 22 ] ;
case 21 : sum + = qlp_coeff [ 20 ] * data [ i - 21 ] ;
case 20 : sum + = qlp_coeff [ 19 ] * data [ i - 20 ] ;
case 19 : sum + = qlp_coeff [ 18 ] * data [ i - 19 ] ;
case 18 : sum + = qlp_coeff [ 17 ] * data [ i - 18 ] ;
case 17 : sum + = qlp_coeff [ 16 ] * data [ i - 17 ] ;
case 16 : sum + = qlp_coeff [ 15 ] * data [ i - 16 ] ;
case 15 : sum + = qlp_coeff [ 14 ] * data [ i - 15 ] ;
case 14 : sum + = qlp_coeff [ 13 ] * data [ i - 14 ] ;
case 13 : sum + = qlp_coeff [ 12 ] * data [ i - 13 ] ;
sum + = qlp_coeff [ 11 ] * data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
}
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
}
}
# endif
2000-12-10 04:09:52 +00:00
2005-01-26 04:04:38 +00:00
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 [ ] )
2007-07-11 04:15:18 +00:00
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
2002-10-04 05:25:54 +00:00
{
unsigned i , j ;
FLAC__int64 sum ;
const FLAC__int32 * history ;
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients_wide: data_len=%d, order=%u, lpq=%d " , data_len , order , lp_quantization ) ;
for ( i = 0 ; i < order ; i + + )
fprintf ( stderr , " , q[%u]=%d " , i , qlp_coeff [ i ] ) ;
fprintf ( stderr , " \n " ) ;
# endif
FLAC__ASSERT ( order > 0 ) ;
for ( i = 0 ; i < data_len ; i + + ) {
sum = 0 ;
history = data ;
for ( j = 0 ; j < order ; j + + )
sum + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * ( - - history ) ) ;
if ( FLAC__bitmath_silog2_wide ( sum > > lp_quantization ) > 32 ) {
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=% " PRId64 " \n " , i , ( sum > > lp_quantization ) ) ;
2002-10-04 05:25:54 +00:00
break ;
}
if ( FLAC__bitmath_silog2_wide ( ( FLAC__int64 ) ( * data ) - ( sum > > lp_quantization ) ) > 32 ) {
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=% " PRId64 " , residual=% " PRId64 " \n " , i , * data , ( long long ) ( sum > > lp_quantization ) , ( ( FLAC__int64 ) ( * data ) - ( sum > > lp_quantization ) ) ) ;
2002-10-04 05:25:54 +00:00
break ;
}
* ( residual + + ) = * ( data + + ) - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
2007-03-13 06:33:52 +00:00
# else /* fully unrolled version for normal use */
{
2007-09-08 22:28:09 +00:00
int i ;
2007-03-13 06:33:52 +00:00
FLAC__int64 sum ;
FLAC__ASSERT ( order > 0 ) ;
FLAC__ASSERT ( order < = 32 ) ;
/*
* We do unique versions up to 12 th order since that ' s the subset limit .
* Also they are roughly ordered to match frequency of occurrence to
* minimize branching .
*/
if ( order < = 12 ) {
if ( order > 8 ) {
if ( order > 10 ) {
if ( order = = 12 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 11 ] * ( FLAC__int64 ) data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 11 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 10 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 9 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
}
else if ( order > 4 ) {
if ( order > 6 ) {
if ( order = = 8 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 7 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 6 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 5 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
}
else {
if ( order > 2 ) {
if ( order = = 4 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 3 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 2 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 1 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + )
2007-03-13 06:33:52 +00:00
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( ( qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
switch ( order ) {
case 32 : sum + = qlp_coeff [ 31 ] * ( FLAC__int64 ) data [ i - 32 ] ;
case 31 : sum + = qlp_coeff [ 30 ] * ( FLAC__int64 ) data [ i - 31 ] ;
case 30 : sum + = qlp_coeff [ 29 ] * ( FLAC__int64 ) data [ i - 30 ] ;
case 29 : sum + = qlp_coeff [ 28 ] * ( FLAC__int64 ) data [ i - 29 ] ;
case 28 : sum + = qlp_coeff [ 27 ] * ( FLAC__int64 ) data [ i - 28 ] ;
case 27 : sum + = qlp_coeff [ 26 ] * ( FLAC__int64 ) data [ i - 27 ] ;
case 26 : sum + = qlp_coeff [ 25 ] * ( FLAC__int64 ) data [ i - 26 ] ;
case 25 : sum + = qlp_coeff [ 24 ] * ( FLAC__int64 ) data [ i - 25 ] ;
case 24 : sum + = qlp_coeff [ 23 ] * ( FLAC__int64 ) data [ i - 24 ] ;
case 23 : sum + = qlp_coeff [ 22 ] * ( FLAC__int64 ) data [ i - 23 ] ;
case 22 : sum + = qlp_coeff [ 21 ] * ( FLAC__int64 ) data [ i - 22 ] ;
case 21 : sum + = qlp_coeff [ 20 ] * ( FLAC__int64 ) data [ i - 21 ] ;
case 20 : sum + = qlp_coeff [ 19 ] * ( FLAC__int64 ) data [ i - 20 ] ;
case 19 : sum + = qlp_coeff [ 18 ] * ( FLAC__int64 ) data [ i - 19 ] ;
case 18 : sum + = qlp_coeff [ 17 ] * ( FLAC__int64 ) data [ i - 18 ] ;
case 17 : sum + = qlp_coeff [ 16 ] * ( FLAC__int64 ) data [ i - 17 ] ;
case 16 : sum + = qlp_coeff [ 15 ] * ( FLAC__int64 ) data [ i - 16 ] ;
case 15 : sum + = qlp_coeff [ 14 ] * ( FLAC__int64 ) data [ i - 15 ] ;
case 14 : sum + = qlp_coeff [ 13 ] * ( FLAC__int64 ) data [ i - 14 ] ;
case 13 : sum + = qlp_coeff [ 12 ] * ( FLAC__int64 ) data [ i - 13 ] ;
sum + = qlp_coeff [ 11 ] * ( FLAC__int64 ) data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
}
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
# endif
2002-10-04 05:25:54 +00:00
2004-11-09 01:34:01 +00:00
# endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
2001-06-23 03:03:24 +00:00
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 [ ] )
2007-07-11 04:15:18 +00:00
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
2000-12-10 04:09:52 +00:00
{
2001-06-23 03:03:24 +00:00
FLAC__int64 sumo ;
2000-12-10 04:09:52 +00:00
unsigned i , j ;
2001-06-23 03:03:24 +00:00
FLAC__int32 sum ;
2006-11-20 07:19:15 +00:00
const FLAC__int32 * r = residual , * history ;
2000-12-10 04:09:52 +00:00
2001-04-24 22:54:07 +00:00
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
2000-12-10 04:09:52 +00:00
fprintf ( stderr , " FLAC__lpc_restore_signal: data_len=%d, order=%u, lpq=%d " , data_len , order , lp_quantization ) ;
for ( i = 0 ; i < order ; i + + )
fprintf ( stderr , " , q[%u]=%d " , i , qlp_coeff [ i ] ) ;
fprintf ( stderr , " \n " ) ;
# endif
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( order > 0 ) ;
2000-12-10 04:09:52 +00:00
for ( i = 0 ; i < data_len ; i + + ) {
sumo = 0 ;
sum = 0 ;
2001-02-08 00:26:45 +00:00
history = data ;
2000-12-10 04:09:52 +00:00
for ( j = 0 ; j < order ; j + + ) {
sum + = qlp_coeff [ j ] * ( * ( - - history ) ) ;
2001-06-23 03:03:24 +00:00
sumo + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * history ) ;
2001-07-09 18:22:46 +00:00
if ( sumo > 2147483647ll | | sumo < - 2147483648ll )
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=% " PRId64 " \n " , i , j , qlp_coeff [ j ] , * history , sumo ) ;
2000-12-10 04:09:52 +00:00
}
2006-11-20 07:19:15 +00:00
* ( data + + ) = * ( r + + ) + ( sum > > lp_quantization ) ;
2001-02-08 00:26:45 +00:00
}
/* Here's a slower but clearer version:
for ( i = 0 ; i < data_len ; i + + ) {
sum = 0 ;
for ( j = 0 ; j < order ; j + + )
sum + = qlp_coeff [ j ] * data [ i - j - 1 ] ;
2000-12-10 04:09:52 +00:00
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
2001-02-08 00:26:45 +00:00
*/
2000-12-10 04:09:52 +00:00
}
2007-03-13 06:33:52 +00:00
# else /* fully unrolled version for normal use */
{
2007-06-14 06:21:44 +00:00
int i ;
2007-03-13 06:33:52 +00:00
FLAC__int32 sum ;
FLAC__ASSERT ( order > 0 ) ;
FLAC__ASSERT ( order < = 32 ) ;
/*
* We do unique versions up to 12 th order since that ' s the subset limit .
* Also they are roughly ordered to match frequency of occurrence to
* minimize branching .
*/
if ( order < = 12 ) {
if ( order > 8 ) {
if ( order > 10 ) {
if ( order = = 12 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 11 ] * data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 11 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 10 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 9 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
}
else if ( order > 4 ) {
if ( order > 6 ) {
if ( order = = 8 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 7 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 6 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 5 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
}
else {
if ( order > 2 ) {
if ( order = = 4 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 3 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 2 ) {
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
else { /* order == 1 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + )
2007-03-13 06:33:52 +00:00
data [ i ] = residual [ i ] + ( ( qlp_coeff [ 0 ] * data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
2007-06-14 06:21:44 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
switch ( order ) {
case 32 : sum + = qlp_coeff [ 31 ] * data [ i - 32 ] ;
case 31 : sum + = qlp_coeff [ 30 ] * data [ i - 31 ] ;
case 30 : sum + = qlp_coeff [ 29 ] * data [ i - 30 ] ;
case 29 : sum + = qlp_coeff [ 28 ] * data [ i - 29 ] ;
case 28 : sum + = qlp_coeff [ 27 ] * data [ i - 28 ] ;
case 27 : sum + = qlp_coeff [ 26 ] * data [ i - 27 ] ;
case 26 : sum + = qlp_coeff [ 25 ] * data [ i - 26 ] ;
case 25 : sum + = qlp_coeff [ 24 ] * data [ i - 25 ] ;
case 24 : sum + = qlp_coeff [ 23 ] * data [ i - 24 ] ;
case 23 : sum + = qlp_coeff [ 22 ] * data [ i - 23 ] ;
case 22 : sum + = qlp_coeff [ 21 ] * data [ i - 22 ] ;
case 21 : sum + = qlp_coeff [ 20 ] * data [ i - 21 ] ;
case 20 : sum + = qlp_coeff [ 19 ] * data [ i - 20 ] ;
case 19 : sum + = qlp_coeff [ 18 ] * data [ i - 19 ] ;
case 18 : sum + = qlp_coeff [ 17 ] * data [ i - 18 ] ;
case 17 : sum + = qlp_coeff [ 16 ] * data [ i - 17 ] ;
case 16 : sum + = qlp_coeff [ 15 ] * data [ i - 16 ] ;
case 15 : sum + = qlp_coeff [ 14 ] * data [ i - 15 ] ;
case 14 : sum + = qlp_coeff [ 13 ] * data [ i - 14 ] ;
case 13 : sum + = qlp_coeff [ 12 ] * data [ i - 13 ] ;
sum + = qlp_coeff [ 11 ] * data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * data [ i - 1 ] ;
}
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
}
}
# endif
2000-12-10 04:09:52 +00:00
2002-10-04 05:25:54 +00:00
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 [ ] )
2007-07-11 04:15:18 +00:00
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
2002-10-04 05:25:54 +00:00
{
unsigned i , j ;
FLAC__int64 sum ;
2006-11-20 07:19:15 +00:00
const FLAC__int32 * r = residual , * history ;
2002-10-04 05:25:54 +00:00
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
fprintf ( stderr , " FLAC__lpc_restore_signal_wide: data_len=%d, order=%u, lpq=%d " , data_len , order , lp_quantization ) ;
for ( i = 0 ; i < order ; i + + )
fprintf ( stderr , " , q[%u]=%d " , i , qlp_coeff [ i ] ) ;
fprintf ( stderr , " \n " ) ;
# endif
FLAC__ASSERT ( order > 0 ) ;
for ( i = 0 ; i < data_len ; i + + ) {
sum = 0 ;
history = data ;
for ( j = 0 ; j < order ; j + + )
sum + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * ( - - history ) ) ;
if ( FLAC__bitmath_silog2_wide ( sum > > lp_quantization ) > 32 ) {
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=% " PRId64 " \n " , i , ( sum > > lp_quantization ) ) ;
2002-10-04 05:25:54 +00:00
break ;
}
2006-11-20 07:19:15 +00:00
if ( FLAC__bitmath_silog2_wide ( ( FLAC__int64 ) ( * r ) + ( sum > > lp_quantization ) ) > 32 ) {
2012-02-01 21:46:35 +11:00
fprintf ( stderr , " FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=% " PRId64 " , data=% " PRId64 " \n " , i , * r , ( sum > > lp_quantization ) , ( ( FLAC__int64 ) ( * r ) + ( sum > > lp_quantization ) ) ) ;
2002-10-04 05:25:54 +00:00
break ;
}
2006-11-20 07:19:15 +00:00
* ( data + + ) = * ( r + + ) + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
2002-10-04 05:25:54 +00:00
}
}
2007-03-13 06:33:52 +00:00
# else /* fully unrolled version for normal use */
{
2007-09-08 22:28:09 +00:00
int i ;
2007-03-13 06:33:52 +00:00
FLAC__int64 sum ;
FLAC__ASSERT ( order > 0 ) ;
FLAC__ASSERT ( order < = 32 ) ;
/*
* We do unique versions up to 12 th order since that ' s the subset limit .
* Also they are roughly ordered to match frequency of occurrence to
* minimize branching .
*/
if ( order < = 12 ) {
if ( order > 8 ) {
if ( order > 10 ) {
if ( order = = 12 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 11 ] * ( FLAC__int64 ) data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 11 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 10 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 9 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
}
else if ( order > 4 ) {
if ( order > 6 ) {
if ( order = = 8 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 7 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 6 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 5 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
}
else {
if ( order > 2 ) {
if ( order = = 4 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 3 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
else {
if ( order = = 2 ) {
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
else { /* order == 1 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + )
2007-03-13 06:33:52 +00:00
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( ( qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
2007-09-08 22:28:09 +00:00
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
2007-03-13 06:33:52 +00:00
sum = 0 ;
switch ( order ) {
case 32 : sum + = qlp_coeff [ 31 ] * ( FLAC__int64 ) data [ i - 32 ] ;
case 31 : sum + = qlp_coeff [ 30 ] * ( FLAC__int64 ) data [ i - 31 ] ;
case 30 : sum + = qlp_coeff [ 29 ] * ( FLAC__int64 ) data [ i - 30 ] ;
case 29 : sum + = qlp_coeff [ 28 ] * ( FLAC__int64 ) data [ i - 29 ] ;
case 28 : sum + = qlp_coeff [ 27 ] * ( FLAC__int64 ) data [ i - 28 ] ;
case 27 : sum + = qlp_coeff [ 26 ] * ( FLAC__int64 ) data [ i - 27 ] ;
case 26 : sum + = qlp_coeff [ 25 ] * ( FLAC__int64 ) data [ i - 26 ] ;
case 25 : sum + = qlp_coeff [ 24 ] * ( FLAC__int64 ) data [ i - 25 ] ;
case 24 : sum + = qlp_coeff [ 23 ] * ( FLAC__int64 ) data [ i - 24 ] ;
case 23 : sum + = qlp_coeff [ 22 ] * ( FLAC__int64 ) data [ i - 23 ] ;
case 22 : sum + = qlp_coeff [ 21 ] * ( FLAC__int64 ) data [ i - 22 ] ;
case 21 : sum + = qlp_coeff [ 20 ] * ( FLAC__int64 ) data [ i - 21 ] ;
case 20 : sum + = qlp_coeff [ 19 ] * ( FLAC__int64 ) data [ i - 20 ] ;
case 19 : sum + = qlp_coeff [ 18 ] * ( FLAC__int64 ) data [ i - 19 ] ;
case 18 : sum + = qlp_coeff [ 17 ] * ( FLAC__int64 ) data [ i - 18 ] ;
case 17 : sum + = qlp_coeff [ 16 ] * ( FLAC__int64 ) data [ i - 17 ] ;
case 16 : sum + = qlp_coeff [ 15 ] * ( FLAC__int64 ) data [ i - 16 ] ;
case 15 : sum + = qlp_coeff [ 14 ] * ( FLAC__int64 ) data [ i - 15 ] ;
case 14 : sum + = qlp_coeff [ 13 ] * ( FLAC__int64 ) data [ i - 14 ] ;
case 13 : sum + = qlp_coeff [ 12 ] * ( FLAC__int64 ) data [ i - 13 ] ;
sum + = qlp_coeff [ 11 ] * ( FLAC__int64 ) data [ i - 12 ] ;
sum + = qlp_coeff [ 10 ] * ( FLAC__int64 ) data [ i - 11 ] ;
sum + = qlp_coeff [ 9 ] * ( FLAC__int64 ) data [ i - 10 ] ;
sum + = qlp_coeff [ 8 ] * ( FLAC__int64 ) data [ i - 9 ] ;
sum + = qlp_coeff [ 7 ] * ( FLAC__int64 ) data [ i - 8 ] ;
sum + = qlp_coeff [ 6 ] * ( FLAC__int64 ) data [ i - 7 ] ;
sum + = qlp_coeff [ 5 ] * ( FLAC__int64 ) data [ i - 6 ] ;
sum + = qlp_coeff [ 4 ] * ( FLAC__int64 ) data [ i - 5 ] ;
sum + = qlp_coeff [ 3 ] * ( FLAC__int64 ) data [ i - 4 ] ;
sum + = qlp_coeff [ 2 ] * ( FLAC__int64 ) data [ i - 3 ] ;
sum + = qlp_coeff [ 1 ] * ( FLAC__int64 ) data [ i - 2 ] ;
sum + = qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ;
}
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
}
# endif
2002-10-04 05:25:54 +00:00
2004-11-09 01:34:01 +00:00
# ifndef FLAC__INTEGER_ONLY_LIBRARY
2004-10-20 00:21:50 +00:00
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample ( FLAC__double lpc_error , unsigned total_samples )
2000-12-10 04:09:52 +00:00
{
2004-10-20 00:21:50 +00:00
FLAC__double error_scale ;
2000-12-10 04:09:52 +00:00
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( total_samples > 0 ) ;
2000-12-10 04:09:52 +00:00
2004-10-20 00:21:50 +00:00
error_scale = 0.5 * M_LN2 * M_LN2 / ( FLAC__double ) total_samples ;
2000-12-10 04:09:52 +00:00
2002-06-05 05:53:17 +00:00
return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale ( lpc_error , error_scale ) ;
2001-05-24 19:27:08 +00:00
}
2004-10-20 00:21:50 +00:00
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale ( FLAC__double lpc_error , FLAC__double error_scale )
2001-05-24 19:27:08 +00:00
{
if ( lpc_error > 0.0 ) {
2004-10-20 00:21:50 +00:00
FLAC__double bps = ( FLAC__double ) 0.5 * log ( error_scale * lpc_error ) / M_LN2 ;
2001-05-24 19:27:08 +00:00
if ( bps > = 0.0 )
return bps ;
else
return 0.0 ;
}
2004-10-20 00:21:50 +00:00
else if ( lpc_error < 0.0 ) { /* error should not be negative but can happen due to inadequate floating-point resolution */
return 1e32 ;
2001-05-24 19:27:08 +00:00
}
2001-02-08 00:26:45 +00:00
else {
2000-12-10 04:09:52 +00:00
return 0.0 ;
2001-02-08 00:26:45 +00:00
}
2000-12-10 04:09:52 +00:00
}
2006-04-28 00:11:31 +00:00
unsigned FLAC__lpc_compute_best_order ( const FLAC__double lpc_error [ ] , unsigned max_order , unsigned total_samples , unsigned overhead_bits_per_order )
2000-12-10 04:09:52 +00:00
{
2006-04-28 00:11:31 +00:00
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 */
FLAC__double bits , best_bits , error_scale ;
2000-12-10 04:09:52 +00:00
2001-05-31 20:11:02 +00:00
FLAC__ASSERT ( max_order > 0 ) ;
FLAC__ASSERT ( total_samples > 0 ) ;
2001-05-24 19:27:08 +00:00
2004-10-20 00:21:50 +00:00
error_scale = 0.5 * M_LN2 * M_LN2 / ( FLAC__double ) total_samples ;
2000-12-10 04:09:52 +00:00
2006-04-28 00:11:31 +00:00
best_index = 0 ;
best_bits = ( unsigned ) ( - 1 ) ;
2000-12-10 04:09:52 +00:00
2006-04-28 00:11:31 +00:00
for ( index = 0 , order = 1 ; index < max_order ; index + + , order + + ) {
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 ) ;
if ( bits < best_bits ) {
best_index = index ;
best_bits = bits ;
2000-12-10 04:09:52 +00:00
}
}
2006-04-28 00:11:31 +00:00
return best_index + 1 ; /* +1 since index of lpc_error[] is order-1 */
2000-12-10 04:09:52 +00:00
}
2004-11-09 01:34:01 +00:00
# endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */