2017-09-16 22:27:28 -07:00
/* libFLAC - Free Lossless Audio Codec library
* Copyright ( C ) 2000 - 2009 Josh Coalson
* Copyright ( C ) 2011 - 2016 Xiph . Org Foundation
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* - Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* - 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 .
*/
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include <math.h>
2018-04-28 15:14:53 +02:00
# include "include/FLAC/assert.h"
# include "include/FLAC/format.h"
# include "include/share/compat.h"
# include "include/private/bitmath.h"
# include "include/private/lpc.h"
# include "include/private/macros.h"
2017-09-16 22:27:28 -07:00
# if defined DEBUG || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE
# include <stdio.h>
# endif
/* OPT: #undef'ing this may improve the speed on some architectures */
# define FLAC__LPC_UNROLLED_FILTER_LOOPS
# ifndef FLAC__INTEGER_ONLY_LIBRARY
# if defined(_MSC_VER) && (_MSC_VER < 1800)
# include <float.h>
static inline long int lround ( double x ) {
return ( long ) ( x + _copysign ( 0.5 , x ) ) ;
}
# elif !defined(HAVE_LROUND) && defined(__GNUC__)
static inline long int lround ( double x ) {
return ( long ) ( x + __builtin_copysign ( 0.5 , x ) ) ;
}
/* If this fails, we are in the presence of a mid 90's compiler, move along... */
# endif
void FLAC__lpc_window_data ( const FLAC__int32 in [ ] , const FLAC__real window [ ] , FLAC__real out [ ] , unsigned data_len )
{
unsigned i ;
for ( i = 0 ; i < data_len ; i + + )
out [ i ] = in [ i ] * window [ i ] ;
}
void FLAC__lpc_compute_autocorrelation ( const FLAC__real data [ ] , unsigned data_len , unsigned lag , FLAC__real autoc [ ] )
{
/* a readable, but slower, version */
#if 0
FLAC__real d ;
unsigned i ;
FLAC__ASSERT ( lag > 0 ) ;
FLAC__ASSERT ( lag < = data_len ) ;
/*
* 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
*/
while ( lag - - ) {
for ( i = lag , d = 0.0 ; i < data_len ; i + + )
d + = data [ i ] * data [ i - lag ] ;
autoc [ lag ] = d ;
}
# endif
/*
* this version tends to run faster because of better data locality
* ( ' data_len ' is usually much larger than ' lag ' )
*/
FLAC__real d ;
unsigned sample , coeff ;
const unsigned limit = data_len - lag ;
FLAC__ASSERT ( lag > 0 ) ;
FLAC__ASSERT ( lag < = data_len ) ;
for ( coeff = 0 ; coeff < lag ; coeff + + )
autoc [ coeff ] = 0.0 ;
for ( sample = 0 ; sample < = limit ; sample + + ) {
d = data [ sample ] ;
for ( coeff = 0 ; coeff < lag ; coeff + + )
autoc [ coeff ] + = d * data [ sample + coeff ] ;
}
for ( ; sample < data_len ; sample + + ) {
d = data [ sample ] ;
for ( coeff = 0 ; coeff < data_len - sample ; coeff + + )
autoc [ coeff ] + = d * data [ sample + coeff ] ;
}
}
void FLAC__lpc_compute_lp_coefficients ( const FLAC__real autoc [ ] , unsigned * max_order , FLAC__real lp_coeff [ ] [ FLAC__MAX_LPC_ORDER ] , double error [ ] )
{
unsigned i , j ;
double r , err , lpc [ FLAC__MAX_LPC_ORDER ] ;
FLAC__ASSERT ( 0 ! = max_order ) ;
FLAC__ASSERT ( 0 < * max_order ) ;
FLAC__ASSERT ( * max_order < = FLAC__MAX_LPC_ORDER ) ;
FLAC__ASSERT ( autoc [ 0 ] ! = 0.0 ) ;
err = autoc [ 0 ] ;
for ( i = 0 ; i < * max_order ; i + + ) {
/* Sum up this iteration's reflection coefficient. */
r = - autoc [ i + 1 ] ;
for ( j = 0 ; j < i ; j + + )
r - = lpc [ j ] * autoc [ i - j ] ;
r / = err ;
/* Update LPC coefficients and total error. */
lpc [ i ] = r ;
for ( j = 0 ; j < ( i > > 1 ) ; j + + ) {
double tmp = lpc [ j ] ;
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 + + )
lp_coeff [ i ] [ j ] = ( FLAC__real ) ( - lpc [ j ] ) ; /* negate FIR filter coeff to get predictor coeff */
error [ i ] = err ;
/* see SF bug https://sourceforge.net/p/flac/bugs/234/ */
if ( err = = 0.0 ) {
* max_order = i + 1 ;
return ;
}
}
}
int FLAC__lpc_quantize_coefficients ( const FLAC__real lp_coeff [ ] , unsigned order , unsigned precision , FLAC__int32 qlp_coeff [ ] , int * shift )
{
unsigned i ;
double cmax ;
FLAC__int32 qmax , qmin ;
FLAC__ASSERT ( precision > 0 ) ;
FLAC__ASSERT ( precision > = FLAC__MIN_QLP_COEFF_PRECISION ) ;
/* drop one bit for the sign; from here on out we consider only |lp_coeff[i]| */
precision - - ;
qmax = 1 < < precision ;
qmin = - qmax ;
qmax - - ;
/* calc cmax = max( |lp_coeff[i]| ) */
cmax = 0.0 ;
for ( i = 0 ; i < order ; i + + ) {
const double d = fabs ( lp_coeff [ i ] ) ;
if ( d > cmax )
cmax = d ;
}
if ( cmax < = 0.0 ) {
/* => coefficients are all 0, which means our constant-detect didn't work */
return 2 ;
}
else {
const int max_shiftlimit = ( 1 < < ( FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN - 1 ) ) - 1 ;
const int min_shiftlimit = - max_shiftlimit - 1 ;
int log2cmax ;
( void ) frexp ( cmax , & log2cmax ) ;
log2cmax - - ;
* shift = ( int ) precision - log2cmax - 1 ;
if ( * shift > max_shiftlimit )
* shift = max_shiftlimit ;
else if ( * shift < min_shiftlimit )
return 1 ;
}
if ( * shift > = 0 ) {
double error = 0.0 ;
FLAC__int32 q ;
for ( i = 0 ; i < order ; i + + ) {
error + = lp_coeff [ i ] * ( 1 < < * shift ) ;
2018-06-21 07:52:01 +02:00
q = ( FLAC__int32 ) lround ( error ) ;
2017-09-16 22:27:28 -07:00
# ifdef FLAC__OVERFLOW_DETECT
if ( q > qmax + 1 ) /* we expect q==qmax+1 occasionally due to rounding */
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 ] ) ;
# endif
if ( q > qmax )
q = qmax ;
else if ( q < qmin )
q = qmin ;
error - = q ;
qlp_coeff [ i ] = q ;
}
}
/* negative shift is very rare but due to design flaw, negative shift is
* not allowed in the decoder , so it must be handled specially by scaling
* down coeffs
*/
else {
const int nshift = - ( * shift ) ;
double error = 0.0 ;
FLAC__int32 q ;
# ifdef DEBUG
fprintf ( stderr , " FLAC__lpc_quantize_coefficients: negative shift=%d order=%u cmax=%f \n " , * shift , order , cmax ) ;
# endif
for ( i = 0 ; i < order ; i + + ) {
error + = lp_coeff [ i ] / ( 1 < < nshift ) ;
2018-06-21 07:52:01 +02:00
q = ( FLAC__int32 ) lround ( error ) ;
2017-09-16 22:27:28 -07:00
# ifdef FLAC__OVERFLOW_DETECT
if ( q > qmax + 1 ) /* we expect q==qmax+1 occasionally due to rounding */
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 ] ) ;
# endif
if ( q > qmax )
q = qmax ;
else if ( q < qmin )
q = qmin ;
error - = q ;
qlp_coeff [ i ] = q ;
}
* shift = 0 ;
}
return 0 ;
}
# if defined(_MSC_VER)
// silence MSVC warnings about __restrict modifier
# pragma warning ( disable : 4028 )
# endif
void FLAC__lpc_compute_residual_from_qlp_coefficients ( const FLAC__int32 * flac_restrict data , unsigned data_len , const FLAC__int32 * flac_restrict qlp_coeff , unsigned order , int lp_quantization , FLAC__int32 * flac_restrict residual )
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo ;
unsigned i , j ;
FLAC__int32 sum ;
const FLAC__int32 * history ;
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
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
FLAC__ASSERT ( order > 0 ) ;
for ( i = 0 ; i < data_len ; i + + ) {
sumo = 0 ;
sum = 0 ;
history = data ;
for ( j = 0 ; j < order ; j + + ) {
sum + = qlp_coeff [ j ] * ( * ( - - history ) ) ;
sumo + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * history ) ;
if ( sumo > 2147483647ll | | sumo < - 2147483648ll )
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 ) ;
}
* ( residual + + ) = * ( data + + ) - ( sum > > lp_quantization ) ;
}
/* 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 ] ;
residual [ i ] = data [ i ] - ( sum > > lp_quantization ) ;
}
*/
}
# else /* fully unrolled version for normal use */
{
int i ;
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + )
residual [ i ] = data [ i ] - ( ( qlp_coeff [ 0 ] * data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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
void FLAC__lpc_compute_residual_from_qlp_coefficients_wide ( const FLAC__int32 * flac_restrict data , unsigned data_len , const FLAC__int32 * flac_restrict qlp_coeff , unsigned order , int lp_quantization , FLAC__int32 * flac_restrict residual )
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
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 ( sum > > lp_quantization ) > 32 ) {
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=% " PRId64 " \n " , i , ( sum > > lp_quantization ) ) ;
break ;
}
if ( FLAC__bitmath_silog2 ( ( FLAC__int64 ) ( * data ) - ( sum > > lp_quantization ) ) > 32 ) {
fprintf ( stderr , " FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=% " PRId64 " , residual=% " PRId64 " \n " , i , * data , ( int64_t ) ( sum > > lp_quantization ) , ( ( FLAC__int64 ) ( * data ) - ( sum > > lp_quantization ) ) ) ;
break ;
}
* ( residual + + ) = * ( data + + ) - ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
# else /* fully unrolled version for normal use */
{
int i ;
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + )
residual [ i ] = data [ i ] - ( FLAC__int32 ) ( ( qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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
# endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
void FLAC__lpc_restore_signal ( const FLAC__int32 * flac_restrict residual , unsigned data_len , const FLAC__int32 * flac_restrict qlp_coeff , unsigned order , int lp_quantization , FLAC__int32 * flac_restrict data )
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
FLAC__int64 sumo ;
unsigned i , j ;
FLAC__int32 sum ;
const FLAC__int32 * r = residual , * history ;
# ifdef FLAC__OVERFLOW_DETECT_VERBOSE
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
FLAC__ASSERT ( order > 0 ) ;
for ( i = 0 ; i < data_len ; i + + ) {
sumo = 0 ;
sum = 0 ;
history = data ;
for ( j = 0 ; j < order ; j + + ) {
sum + = qlp_coeff [ j ] * ( * ( - - history ) ) ;
sumo + = ( FLAC__int64 ) qlp_coeff [ j ] * ( FLAC__int64 ) ( * history ) ;
if ( sumo > 2147483647ll | | sumo < - 2147483648ll )
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 ) ;
}
* ( data + + ) = * ( r + + ) + ( sum > > lp_quantization ) ;
}
/* 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 ] ;
data [ i ] = residual [ i ] + ( sum > > lp_quantization ) ;
}
*/
}
# else /* fully unrolled version for normal use */
{
int i ;
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + )
data [ i ] = residual [ i ] + ( ( qlp_coeff [ 0 ] * data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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
void FLAC__lpc_restore_signal_wide ( const FLAC__int32 * flac_restrict residual , unsigned data_len , const FLAC__int32 * flac_restrict qlp_coeff , unsigned order , int lp_quantization , FLAC__int32 * flac_restrict data )
# if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{
unsigned i , j ;
FLAC__int64 sum ;
const FLAC__int32 * r = residual , * history ;
# 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 ( sum > > lp_quantization ) > 32 ) {
fprintf ( stderr , " FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=% " PRId64 " \n " , i , ( sum > > lp_quantization ) ) ;
break ;
}
if ( FLAC__bitmath_silog2 ( ( FLAC__int64 ) ( * r ) + ( sum > > lp_quantization ) ) > 32 ) {
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 ) ) ) ;
break ;
}
* ( data + + ) = * ( r + + ) + ( FLAC__int32 ) ( sum > > lp_quantization ) ;
}
}
# else /* fully unrolled version for normal use */
{
int i ;
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 ) {
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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 */
for ( i = 0 ; i < ( int ) data_len ; i + + )
data [ i ] = residual [ i ] + ( FLAC__int32 ) ( ( qlp_coeff [ 0 ] * ( FLAC__int64 ) data [ i - 1 ] ) > > lp_quantization ) ;
}
}
}
}
else { /* order > 12 */
for ( i = 0 ; i < ( int ) data_len ; i + + ) {
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
# if defined(_MSC_VER)
# pragma warning ( default : 4028 )
# endif
# ifndef FLAC__INTEGER_ONLY_LIBRARY
double FLAC__lpc_compute_expected_bits_per_residual_sample ( double lpc_error , unsigned total_samples )
{
double error_scale ;
FLAC__ASSERT ( total_samples > 0 ) ;
error_scale = 0.5 / ( double ) total_samples ;
return FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale ( lpc_error , error_scale ) ;
}
double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale ( double lpc_error , double error_scale )
{
if ( lpc_error > 0.0 ) {
double bps = ( double ) 0.5 * log ( error_scale * lpc_error ) / M_LN2 ;
if ( bps > = 0.0 )
return bps ;
else
return 0.0 ;
}
else if ( lpc_error < 0.0 ) { /* error should not be negative but can happen due to inadequate floating-point resolution */
return 1e32 ;
}
else {
return 0.0 ;
}
}
unsigned FLAC__lpc_compute_best_order ( const double lpc_error [ ] , unsigned max_order , unsigned total_samples , unsigned overhead_bits_per_order )
{
unsigned order , indx , 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 */
double bits , best_bits , error_scale ;
FLAC__ASSERT ( max_order > 0 ) ;
FLAC__ASSERT ( total_samples > 0 ) ;
error_scale = 0.5 / ( double ) total_samples ;
best_index = 0 ;
best_bits = ( unsigned ) ( - 1 ) ;
for ( indx = 0 , order = 1 ; indx < max_order ; indx + + , order + + ) {
bits = FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale ( lpc_error [ indx ] , error_scale ) * ( double ) ( total_samples - order ) + ( double ) ( order * overhead_bits_per_order ) ;
if ( bits < best_bits ) {
best_index = indx ;
best_bits = bits ;
}
}
return best_index + 1 ; /* +1 since indx of lpc_error[] is order-1 */
}
# endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */