mirror of
https://github.com/musix-org/musix-oss
synced 2025-06-17 13:56:01 +00:00
Modules
This commit is contained in:
267
node_modules/node-opus/deps/opus/silk/A2NLSF.c
generated
vendored
Normal file
267
node_modules/node-opus/deps/opus/silk/A2NLSF.c
generated
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
/* Conversion between prediction filter coefficients and NLSFs */
|
||||
/* Requires the order to be an even number */
|
||||
/* A piecewise linear approximation maps LSF <-> cos(LSF) */
|
||||
/* Therefore the result is not accurate NLSFs, but the two */
|
||||
/* functions are accurate inverses of each other */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "tables.h"
|
||||
|
||||
/* Number of binary divisions, when not in low complexity mode */
|
||||
#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
|
||||
#define MAX_ITERATIONS_A2NLSF_FIX 30
|
||||
|
||||
/* Helper function for A2NLSF(..) */
|
||||
/* Transforms polynomials from cos(n*f) to cos(f)^n */
|
||||
static OPUS_INLINE void silk_A2NLSF_trans_poly(
|
||||
opus_int32 *p, /* I/O Polynomial */
|
||||
const opus_int dd /* I Polynomial order (= filter order / 2 ) */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
|
||||
for( k = 2; k <= dd; k++ ) {
|
||||
for( n = dd; n > k; n-- ) {
|
||||
p[ n - 2 ] -= p[ n ];
|
||||
}
|
||||
p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 );
|
||||
}
|
||||
}
|
||||
/* Helper function for A2NLSF(..) */
|
||||
/* Polynomial evaluation */
|
||||
static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */
|
||||
opus_int32 *p, /* I Polynomial, Q16 */
|
||||
const opus_int32 x, /* I Evaluation point, Q12 */
|
||||
const opus_int dd /* I Order */
|
||||
)
|
||||
{
|
||||
opus_int n;
|
||||
opus_int32 x_Q16, y32;
|
||||
|
||||
y32 = p[ dd ]; /* Q16 */
|
||||
x_Q16 = silk_LSHIFT( x, 4 );
|
||||
|
||||
if ( opus_likely( 8 == dd ) )
|
||||
{
|
||||
y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 );
|
||||
y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( n = dd - 1; n >= 0; n-- ) {
|
||||
y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */
|
||||
}
|
||||
}
|
||||
return y32;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_A2NLSF_init(
|
||||
const opus_int32 *a_Q16,
|
||||
opus_int32 *P,
|
||||
opus_int32 *Q,
|
||||
const opus_int dd
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
|
||||
/* Convert filter coefs to even and odd polynomials */
|
||||
P[dd] = silk_LSHIFT( 1, 16 );
|
||||
Q[dd] = silk_LSHIFT( 1, 16 );
|
||||
for( k = 0; k < dd; k++ ) {
|
||||
P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */
|
||||
Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */
|
||||
}
|
||||
|
||||
/* Divide out zeros as we have that for even filter orders, */
|
||||
/* z = 1 is always a root in Q, and */
|
||||
/* z = -1 is always a root in P */
|
||||
for( k = dd; k > 0; k-- ) {
|
||||
P[ k - 1 ] -= P[ k ];
|
||||
Q[ k - 1 ] += Q[ k ];
|
||||
}
|
||||
|
||||
/* Transform polynomials from cos(n*f) to cos(f)^n */
|
||||
silk_A2NLSF_trans_poly( P, dd );
|
||||
silk_A2NLSF_trans_poly( Q, dd );
|
||||
}
|
||||
|
||||
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
|
||||
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
|
||||
void silk_A2NLSF(
|
||||
opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */
|
||||
opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
|
||||
const opus_int d /* I Filter order (must be even) */
|
||||
)
|
||||
{
|
||||
opus_int i, k, m, dd, root_ix, ffrac;
|
||||
opus_int32 xlo, xhi, xmid;
|
||||
opus_int32 ylo, yhi, ymid, thr;
|
||||
opus_int32 nom, den;
|
||||
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
||||
opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
||||
opus_int32 *PQ[ 2 ];
|
||||
opus_int32 *p;
|
||||
|
||||
/* Store pointers to array */
|
||||
PQ[ 0 ] = P;
|
||||
PQ[ 1 ] = Q;
|
||||
|
||||
dd = silk_RSHIFT( d, 1 );
|
||||
|
||||
silk_A2NLSF_init( a_Q16, P, Q, dd );
|
||||
|
||||
/* Find roots, alternating between P and Q */
|
||||
p = P; /* Pointer to polynomial */
|
||||
|
||||
xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
|
||||
ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||
|
||||
if( ylo < 0 ) {
|
||||
/* Set the first NLSF to zero and move on to the next */
|
||||
NLSF[ 0 ] = 0;
|
||||
p = Q; /* Pointer to polynomial */
|
||||
ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||
root_ix = 1; /* Index of current root */
|
||||
} else {
|
||||
root_ix = 0; /* Index of current root */
|
||||
}
|
||||
k = 1; /* Loop counter */
|
||||
i = 0; /* Counter for bandwidth expansions applied */
|
||||
thr = 0;
|
||||
while( 1 ) {
|
||||
/* Evaluate polynomial */
|
||||
xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
|
||||
yhi = silk_A2NLSF_eval_poly( p, xhi, dd );
|
||||
|
||||
/* Detect zero crossing */
|
||||
if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) {
|
||||
if( yhi == 0 ) {
|
||||
/* If the root lies exactly at the end of the current */
|
||||
/* interval, look for the next root in the next interval */
|
||||
thr = 1;
|
||||
} else {
|
||||
thr = 0;
|
||||
}
|
||||
/* Binary division */
|
||||
ffrac = -256;
|
||||
for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
|
||||
/* Evaluate polynomial */
|
||||
xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 );
|
||||
ymid = silk_A2NLSF_eval_poly( p, xmid, dd );
|
||||
|
||||
/* Detect zero crossing */
|
||||
if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
|
||||
/* Reduce frequency */
|
||||
xhi = xmid;
|
||||
yhi = ymid;
|
||||
} else {
|
||||
/* Increase frequency */
|
||||
xlo = xmid;
|
||||
ylo = ymid;
|
||||
ffrac = silk_ADD_RSHIFT( ffrac, 128, m );
|
||||
}
|
||||
}
|
||||
|
||||
/* Interpolate */
|
||||
if( silk_abs( ylo ) < 65536 ) {
|
||||
/* Avoid dividing by zero */
|
||||
den = ylo - yhi;
|
||||
nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 );
|
||||
if( den != 0 ) {
|
||||
ffrac += silk_DIV32( nom, den );
|
||||
}
|
||||
} else {
|
||||
/* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
|
||||
ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
|
||||
}
|
||||
NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX );
|
||||
|
||||
silk_assert( NLSF[ root_ix ] >= 0 );
|
||||
|
||||
root_ix++; /* Next root */
|
||||
if( root_ix >= d ) {
|
||||
/* Found all roots */
|
||||
break;
|
||||
}
|
||||
/* Alternate pointer to polynomial */
|
||||
p = PQ[ root_ix & 1 ];
|
||||
|
||||
/* Evaluate polynomial */
|
||||
xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/
|
||||
ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 );
|
||||
} else {
|
||||
/* Increment loop counter */
|
||||
k++;
|
||||
xlo = xhi;
|
||||
ylo = yhi;
|
||||
thr = 0;
|
||||
|
||||
if( k > LSF_COS_TAB_SZ_FIX ) {
|
||||
i++;
|
||||
if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
|
||||
/* Set NLSFs to white spectrum and exit */
|
||||
NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );
|
||||
for( k = 1; k < d; k++ ) {
|
||||
NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Error: Apply progressively more bandwidth expansion and run again */
|
||||
silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/
|
||||
|
||||
silk_A2NLSF_init( a_Q16, P, Q, dd );
|
||||
p = P; /* Pointer to polynomial */
|
||||
xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
|
||||
ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||
if( ylo < 0 ) {
|
||||
/* Set the first NLSF to zero and move on to the next */
|
||||
NLSF[ 0 ] = 0;
|
||||
p = Q; /* Pointer to polynomial */
|
||||
ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
|
||||
root_ix = 1; /* Index of current root */
|
||||
} else {
|
||||
root_ix = 0; /* Index of current root */
|
||||
}
|
||||
k = 1; /* Reset loop counter */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
134
node_modules/node-opus/deps/opus/silk/API.h
generated
vendored
Normal file
134
node_modules/node-opus/deps/opus/silk/API.h
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_API_H
|
||||
#define SILK_API_H
|
||||
|
||||
#include "control.h"
|
||||
#include "typedef.h"
|
||||
#include "errors.h"
|
||||
#include "entenc.h"
|
||||
#include "entdec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SILK_MAX_FRAMES_PER_PACKET 3
|
||||
|
||||
/* Struct for TOC (Table of Contents) */
|
||||
typedef struct {
|
||||
opus_int VADFlag; /* Voice activity for packet */
|
||||
opus_int VADFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Voice activity for each frame in packet */
|
||||
opus_int inbandFECFlag; /* Flag indicating if packet contains in-band FEC */
|
||||
} silk_TOC_struct;
|
||||
|
||||
/****************************************/
|
||||
/* Encoder functions */
|
||||
/****************************************/
|
||||
|
||||
/***********************************************/
|
||||
/* Get size in bytes of the Silk encoder state */
|
||||
/***********************************************/
|
||||
opus_int silk_Get_Encoder_Size( /* O Returns error code */
|
||||
opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */
|
||||
);
|
||||
|
||||
/*************************/
|
||||
/* Init or reset encoder */
|
||||
/*************************/
|
||||
opus_int silk_InitEncoder( /* O Returns error code */
|
||||
void *encState, /* I/O State */
|
||||
int arch, /* I Run-time architecture */
|
||||
silk_EncControlStruct *encStatus /* O Encoder Status */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Encode frame with Silk */
|
||||
/**************************/
|
||||
/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */
|
||||
/* encControl->payloadSize_ms is set to */
|
||||
opus_int silk_Encode( /* O Returns error code */
|
||||
void *encState, /* I/O State */
|
||||
silk_EncControlStruct *encControl, /* I Control status */
|
||||
const opus_int16 *samplesIn, /* I Speech sample input vector */
|
||||
opus_int nSamplesIn, /* I Number of samples in input vector */
|
||||
ec_enc *psRangeEnc, /* I/O Compressor data structure */
|
||||
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
|
||||
const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */
|
||||
);
|
||||
|
||||
/****************************************/
|
||||
/* Decoder functions */
|
||||
/****************************************/
|
||||
|
||||
/***********************************************/
|
||||
/* Get size in bytes of the Silk decoder state */
|
||||
/***********************************************/
|
||||
opus_int silk_Get_Decoder_Size( /* O Returns error code */
|
||||
opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */
|
||||
);
|
||||
|
||||
/*************************/
|
||||
/* Init or Reset decoder */
|
||||
/*************************/
|
||||
opus_int silk_InitDecoder( /* O Returns error code */
|
||||
void *decState /* I/O State */
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Decode a frame */
|
||||
/******************/
|
||||
opus_int silk_Decode( /* O Returns error code */
|
||||
void* decState, /* I/O State */
|
||||
silk_DecControlStruct* decControl, /* I/O Control Structure */
|
||||
opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
|
||||
opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int16 *samplesOut, /* O Decoded output speech vector */
|
||||
opus_int32 *nSamplesOut, /* O Number of samples decoded */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
#if 0
|
||||
/**************************************/
|
||||
/* Get table of contents for a packet */
|
||||
/**************************************/
|
||||
opus_int silk_get_TOC(
|
||||
const opus_uint8 *payload, /* I Payload data */
|
||||
const opus_int nBytesIn, /* I Number of input bytes */
|
||||
const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */
|
||||
silk_TOC_struct *Silk_TOC /* O Type of content */
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
181
node_modules/node-opus/deps/opus/silk/CNG.c
generated
vendored
Normal file
181
node_modules/node-opus/deps/opus/silk/CNG.c
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/* Generates excitation for CNG LPC synthesis */
|
||||
static OPUS_INLINE void silk_CNG_exc(
|
||||
opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */
|
||||
opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
|
||||
opus_int32 Gain_Q16, /* I Gain to apply */
|
||||
opus_int length, /* I Length */
|
||||
opus_int32 *rand_seed /* I/O Seed to random index generator */
|
||||
)
|
||||
{
|
||||
opus_int32 seed;
|
||||
opus_int i, idx, exc_mask;
|
||||
|
||||
exc_mask = CNG_BUF_MASK_MAX;
|
||||
while( exc_mask > length ) {
|
||||
exc_mask = silk_RSHIFT( exc_mask, 1 );
|
||||
}
|
||||
|
||||
seed = *rand_seed;
|
||||
for( i = 0; i < length; i++ ) {
|
||||
seed = silk_RAND( seed );
|
||||
idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
|
||||
silk_assert( idx >= 0 );
|
||||
silk_assert( idx <= CNG_BUF_MASK_MAX );
|
||||
exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) );
|
||||
}
|
||||
*rand_seed = seed;
|
||||
}
|
||||
|
||||
void silk_CNG_Reset(
|
||||
silk_decoder_state *psDec /* I/O Decoder state */
|
||||
)
|
||||
{
|
||||
opus_int i, NLSF_step_Q15, NLSF_acc_Q15;
|
||||
|
||||
NLSF_step_Q15 = silk_DIV32_16( silk_int16_MAX, psDec->LPC_order + 1 );
|
||||
NLSF_acc_Q15 = 0;
|
||||
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||
NLSF_acc_Q15 += NLSF_step_Q15;
|
||||
psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15;
|
||||
}
|
||||
psDec->sCNG.CNG_smth_Gain_Q16 = 0;
|
||||
psDec->sCNG.rand_seed = 3176576;
|
||||
}
|
||||
|
||||
/* Updates CNG estimate, and applies the CNG when packet was lost */
|
||||
void silk_CNG(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int16 frame[], /* I/O Signal */
|
||||
opus_int length /* I Length of residual */
|
||||
)
|
||||
{
|
||||
opus_int i, subfr;
|
||||
opus_int32 sum_Q6, max_Gain_Q16, gain_Q16;
|
||||
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
||||
silk_CNG_struct *psCNG = &psDec->sCNG;
|
||||
SAVE_STACK;
|
||||
|
||||
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
||||
/* Reset state */
|
||||
silk_CNG_Reset( psDec );
|
||||
|
||||
psCNG->fs_kHz = psDec->fs_kHz;
|
||||
}
|
||||
if( psDec->lossCnt == 0 && psDec->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) {
|
||||
/* Update CNG parameters */
|
||||
|
||||
/* Smoothing of LSF's */
|
||||
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||
psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 );
|
||||
}
|
||||
/* Find the subframe with the highest gain */
|
||||
max_Gain_Q16 = 0;
|
||||
subfr = 0;
|
||||
for( i = 0; i < psDec->nb_subfr; i++ ) {
|
||||
if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) {
|
||||
max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];
|
||||
subfr = i;
|
||||
}
|
||||
}
|
||||
/* Update CNG excitation buffer with excitation from this subframe */
|
||||
silk_memmove( &psCNG->CNG_exc_buf_Q14[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q14, ( psDec->nb_subfr - 1 ) * psDec->subfr_length * sizeof( opus_int32 ) );
|
||||
silk_memcpy( psCNG->CNG_exc_buf_Q14, &psDec->exc_Q14[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( opus_int32 ) );
|
||||
|
||||
/* Smooth gains */
|
||||
for( i = 0; i < psDec->nb_subfr; i++ ) {
|
||||
psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Add CNG when packet is lost or during DTX */
|
||||
if( psDec->lossCnt ) {
|
||||
VARDECL( opus_int32, CNG_sig_Q10 );
|
||||
ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
|
||||
|
||||
/* Generate CNG excitation */
|
||||
gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
|
||||
if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
|
||||
gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
|
||||
} else {
|
||||
gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
|
||||
}
|
||||
silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed );
|
||||
|
||||
/* Convert CNG NLSF to filter representation */
|
||||
silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
|
||||
|
||||
/* Generate CNG signal, by synthesis filtering */
|
||||
silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
for( i = 0; i < length; i++ ) {
|
||||
silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
|
||||
if( psDec->LPC_order == 16 ) {
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
|
||||
sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
|
||||
}
|
||||
|
||||
/* Update states */
|
||||
CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 );
|
||||
|
||||
frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
|
||||
}
|
||||
silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
} else {
|
||||
silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
77
node_modules/node-opus/deps/opus/silk/HP_variable_cutoff.c
generated
vendored
Normal file
77
node_modules/node-opus/deps/opus/silk/HP_variable_cutoff.c
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
#ifdef FIXED_POINT
|
||||
#include "main_FIX.h"
|
||||
#else
|
||||
#include "main_FLP.h"
|
||||
#endif
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
|
||||
void silk_HP_variable_cutoff(
|
||||
silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
|
||||
)
|
||||
{
|
||||
opus_int quality_Q15;
|
||||
opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;
|
||||
silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn;
|
||||
|
||||
/* Adaptive cutoff frequency: estimate low end of pitch frequency range */
|
||||
if( psEncC1->prevSignalType == TYPE_VOICED ) {
|
||||
/* difference, in log domain */
|
||||
pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag );
|
||||
pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 );
|
||||
|
||||
/* adjustment based on quality */
|
||||
quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ];
|
||||
pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ),
|
||||
pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) );
|
||||
|
||||
/* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */
|
||||
delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 );
|
||||
if( delta_freq_Q7 < 0 ) {
|
||||
/* less smoothing for decreasing pitch frequency, to track something close to the minimum */
|
||||
delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 );
|
||||
}
|
||||
|
||||
/* limit delta, to reduce impact of outliers in pitch estimation */
|
||||
delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) );
|
||||
|
||||
/* update smoother */
|
||||
psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15,
|
||||
silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );
|
||||
|
||||
/* limit frequency range */
|
||||
psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15,
|
||||
silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ),
|
||||
silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) );
|
||||
}
|
||||
}
|
188
node_modules/node-opus/deps/opus/silk/Inlines.h
generated
vendored
Normal file
188
node_modules/node-opus/deps/opus/silk/Inlines.h
generated
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
/*! \file silk_Inlines.h
|
||||
* \brief silk_Inlines.h defines OPUS_INLINE signal processing functions.
|
||||
*/
|
||||
|
||||
#ifndef SILK_FIX_INLINES_H
|
||||
#define SILK_FIX_INLINES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* count leading zeros of opus_int64 */
|
||||
static OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in )
|
||||
{
|
||||
opus_int32 in_upper;
|
||||
|
||||
in_upper = (opus_int32)silk_RSHIFT64(in, 32);
|
||||
if (in_upper == 0) {
|
||||
/* Search in the lower 32 bits */
|
||||
return 32 + silk_CLZ32( (opus_int32) in );
|
||||
} else {
|
||||
/* Search in the upper 32 bits */
|
||||
return silk_CLZ32( in_upper );
|
||||
}
|
||||
}
|
||||
|
||||
/* get number of leading zeros and fractional part (the bits right after the leading one */
|
||||
static OPUS_INLINE void silk_CLZ_FRAC(
|
||||
opus_int32 in, /* I input */
|
||||
opus_int32 *lz, /* O number of leading zeros */
|
||||
opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */
|
||||
)
|
||||
{
|
||||
opus_int32 lzeros = silk_CLZ32(in);
|
||||
|
||||
* lz = lzeros;
|
||||
* frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f;
|
||||
}
|
||||
|
||||
/* Approximation of square root */
|
||||
/* Accuracy: < +/- 10% for output values > 15 */
|
||||
/* < +/- 2.5% for output values > 120 */
|
||||
static OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x )
|
||||
{
|
||||
opus_int32 y, lz, frac_Q7;
|
||||
|
||||
if( x <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
silk_CLZ_FRAC(x, &lz, &frac_Q7);
|
||||
|
||||
if( lz & 1 ) {
|
||||
y = 32768;
|
||||
} else {
|
||||
y = 46214; /* 46214 = sqrt(2) * 32768 */
|
||||
}
|
||||
|
||||
/* get scaling right */
|
||||
y >>= silk_RSHIFT(lz, 1);
|
||||
|
||||
/* increment using fractional part of input */
|
||||
y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7));
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/* Divide two int32 values and return result as int32 in a given Q-domain */
|
||||
static OPUS_INLINE opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
|
||||
const opus_int32 a32, /* I numerator (Q0) */
|
||||
const opus_int32 b32, /* I denominator (Q0) */
|
||||
const opus_int Qres /* I Q-domain of result (>= 0) */
|
||||
)
|
||||
{
|
||||
opus_int a_headrm, b_headrm, lshift;
|
||||
opus_int32 b32_inv, a32_nrm, b32_nrm, result;
|
||||
|
||||
silk_assert( b32 != 0 );
|
||||
silk_assert( Qres >= 0 );
|
||||
|
||||
/* Compute number of bits head room and normalize inputs */
|
||||
a_headrm = silk_CLZ32( silk_abs(a32) ) - 1;
|
||||
a32_nrm = silk_LSHIFT(a32, a_headrm); /* Q: a_headrm */
|
||||
b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;
|
||||
b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */
|
||||
|
||||
/* Inverse of b32, with 14 bits of precision */
|
||||
b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
|
||||
|
||||
/* First approximation */
|
||||
result = silk_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
|
||||
|
||||
/* Compute residual by subtracting product of denominator and first approximation */
|
||||
/* It's OK to overflow because the final value of a32_nrm should always be small */
|
||||
a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 )); /* Q: a_headrm */
|
||||
|
||||
/* Refinement */
|
||||
result = silk_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */
|
||||
|
||||
/* Convert to Qres domain */
|
||||
lshift = 29 + a_headrm - b_headrm - Qres;
|
||||
if( lshift < 0 ) {
|
||||
return silk_LSHIFT_SAT32(result, -lshift);
|
||||
} else {
|
||||
if( lshift < 32){
|
||||
return silk_RSHIFT(result, lshift);
|
||||
} else {
|
||||
/* Avoid undefined result */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Invert int32 value and return result as int32 in a given Q-domain */
|
||||
static OPUS_INLINE opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
|
||||
const opus_int32 b32, /* I denominator (Q0) */
|
||||
const opus_int Qres /* I Q-domain of result (> 0) */
|
||||
)
|
||||
{
|
||||
opus_int b_headrm, lshift;
|
||||
opus_int32 b32_inv, b32_nrm, err_Q32, result;
|
||||
|
||||
silk_assert( b32 != 0 );
|
||||
silk_assert( Qres > 0 );
|
||||
|
||||
/* Compute number of bits head room and normalize input */
|
||||
b_headrm = silk_CLZ32( silk_abs(b32) ) - 1;
|
||||
b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */
|
||||
|
||||
/* Inverse of b32, with 14 bits of precision */
|
||||
b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */
|
||||
|
||||
/* First approximation */
|
||||
result = silk_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */
|
||||
|
||||
/* Compute residual by subtracting product of denominator and first approximation from one */
|
||||
err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */
|
||||
|
||||
/* Refinement */
|
||||
result = silk_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */
|
||||
|
||||
/* Convert to Qres domain */
|
||||
lshift = 61 - b_headrm - Qres;
|
||||
if( lshift <= 0 ) {
|
||||
return silk_LSHIFT_SAT32(result, -lshift);
|
||||
} else {
|
||||
if( lshift < 32){
|
||||
return silk_RSHIFT(result, lshift);
|
||||
}else{
|
||||
/* Avoid undefined result */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SILK_FIX_INLINES_H */
|
108
node_modules/node-opus/deps/opus/silk/LPC_analysis_filter.c
generated
vendored
Normal file
108
node_modules/node-opus/deps/opus/silk/LPC_analysis_filter.c
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
#include "celt_lpc.h"
|
||||
|
||||
/*******************************************/
|
||||
/* LPC analysis filter */
|
||||
/* NB! State is kept internally and the */
|
||||
/* filter always starts with zero state */
|
||||
/* first d output samples are set to zero */
|
||||
/*******************************************/
|
||||
|
||||
void silk_LPC_analysis_filter(
|
||||
opus_int16 *out, /* O Output signal */
|
||||
const opus_int16 *in, /* I Input signal */
|
||||
const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
|
||||
const opus_int32 len, /* I Signal length */
|
||||
const opus_int32 d, /* I Filter order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int j;
|
||||
#ifdef FIXED_POINT
|
||||
opus_int16 mem[SILK_MAX_ORDER_LPC];
|
||||
opus_int16 num[SILK_MAX_ORDER_LPC];
|
||||
#else
|
||||
int ix;
|
||||
opus_int32 out32_Q12, out32;
|
||||
const opus_int16 *in_ptr;
|
||||
#endif
|
||||
|
||||
silk_assert( d >= 6 );
|
||||
silk_assert( (d & 1) == 0 );
|
||||
silk_assert( d <= len );
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
silk_assert( d <= SILK_MAX_ORDER_LPC );
|
||||
for ( j = 0; j < d; j++ ) {
|
||||
num[ j ] = -B[ j ];
|
||||
}
|
||||
for (j=0;j<d;j++) {
|
||||
mem[ j ] = in[ d - j - 1 ];
|
||||
}
|
||||
celt_fir( in + d, num, out + d, len - d, d, mem, arch );
|
||||
for ( j = 0; j < d; j++ ) {
|
||||
out[ j ] = 0;
|
||||
}
|
||||
#else
|
||||
(void)arch;
|
||||
for( ix = d; ix < len; ix++ ) {
|
||||
in_ptr = &in[ ix - 1 ];
|
||||
|
||||
out32_Q12 = silk_SMULBB( in_ptr[ 0 ], B[ 0 ] );
|
||||
/* Allowing wrap around so that two wraps can cancel each other. The rare
|
||||
cases where the result wraps around can only be triggered by invalid streams*/
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -1 ], B[ 1 ] );
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -2 ], B[ 2 ] );
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -3 ], B[ 3 ] );
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -4 ], B[ 4 ] );
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -5 ], B[ 5 ] );
|
||||
for( j = 6; j < d; j += 2 ) {
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j ], B[ j ] );
|
||||
out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] );
|
||||
}
|
||||
|
||||
/* Subtract prediction */
|
||||
out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 );
|
||||
|
||||
/* Scale to Q0 */
|
||||
out32 = silk_RSHIFT_ROUND( out32_Q12, 12 );
|
||||
|
||||
/* Saturate output */
|
||||
out[ ix ] = (opus_int16)silk_SAT16( out32 );
|
||||
}
|
||||
|
||||
/* Set first d output samples to zero */
|
||||
silk_memset( out, 0, d * sizeof( opus_int16 ) );
|
||||
#endif
|
||||
}
|
154
node_modules/node-opus/deps/opus/silk/LPC_inv_pred_gain.c
generated
vendored
Normal file
154
node_modules/node-opus/deps/opus/silk/LPC_inv_pred_gain.c
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
#define QA 24
|
||||
#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
|
||||
|
||||
#define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
|
||||
|
||||
/* Compute inverse of LPC prediction gain, and */
|
||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||
static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||
opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
|
||||
const opus_int order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n, mult2Q;
|
||||
opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;
|
||||
opus_int32 *Aold_QA, *Anew_QA;
|
||||
|
||||
Anew_QA = A_QA[ order & 1 ];
|
||||
|
||||
invGain_Q30 = (opus_int32)1 << 30;
|
||||
for( k = order - 1; k > 0; k-- ) {
|
||||
/* Check for stability */
|
||||
if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set RC equal to negated AR coef */
|
||||
rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA );
|
||||
|
||||
/* rc_mult1_Q30 range: [ 1 : 2^30 ] */
|
||||
rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
|
||||
silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
|
||||
|
||||
/* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
|
||||
mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
|
||||
rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
|
||||
|
||||
/* Update inverse gain */
|
||||
/* invGain_Q30 range: [ 0 : 2^30 ] */
|
||||
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||
silk_assert( invGain_Q30 >= 0 );
|
||||
silk_assert( invGain_Q30 <= ( 1 << 30 ) );
|
||||
|
||||
/* Swap pointers */
|
||||
Aold_QA = Anew_QA;
|
||||
Anew_QA = A_QA[ k & 1 ];
|
||||
|
||||
/* Update AR coefficient */
|
||||
for( n = 0; n < k; n++ ) {
|
||||
tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );
|
||||
Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for stability */
|
||||
if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set RC equal to negated AR coef */
|
||||
rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA );
|
||||
|
||||
/* Range: [ 1 : 2^30 ] */
|
||||
rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
|
||||
/* Update inverse gain */
|
||||
/* Range: [ 0 : 2^30 ] */
|
||||
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
|
||||
silk_assert( invGain_Q30 >= 0 );
|
||||
silk_assert( invGain_Q30 <= 1<<30 );
|
||||
|
||||
return invGain_Q30;
|
||||
}
|
||||
|
||||
/* For input in Q12 domain */
|
||||
opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
||||
const opus_int order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 *Anew_QA;
|
||||
opus_int32 DC_resp = 0;
|
||||
|
||||
Anew_QA = Atmp_QA[ order & 1 ];
|
||||
|
||||
/* Increase Q domain of the AR coefficients */
|
||||
for( k = 0; k < order; k++ ) {
|
||||
DC_resp += (opus_int32)A_Q12[ k ];
|
||||
Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
|
||||
}
|
||||
/* If the DC is unstable, we don't even need to do the full calculations */
|
||||
if( DC_resp >= 4096 ) {
|
||||
return 0;
|
||||
}
|
||||
return LPC_inverse_pred_gain_QA( Atmp_QA, order );
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
||||
/* For input in Q24 domain */
|
||||
opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||
const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
|
||||
const opus_int order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 *Anew_QA;
|
||||
|
||||
Anew_QA = Atmp_QA[ order & 1 ];
|
||||
|
||||
/* Increase Q domain of the AR coefficients */
|
||||
for( k = 0; k < order; k++ ) {
|
||||
Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
|
||||
}
|
||||
|
||||
return LPC_inverse_pred_gain_QA( Atmp_QA, order );
|
||||
}
|
||||
#endif
|
135
node_modules/node-opus/deps/opus/silk/LP_variable_cutoff.c
generated
vendored
Normal file
135
node_modules/node-opus/deps/opus/silk/LP_variable_cutoff.c
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/*
|
||||
Elliptic/Cauer filters designed with 0.1 dB passband ripple,
|
||||
80 dB minimum stopband attenuation, and
|
||||
[0.95 : 0.15 : 0.35] normalized cut off frequencies.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/* Helper function, interpolates the filter taps */
|
||||
static OPUS_INLINE void silk_LP_interpolate_filter_taps(
|
||||
opus_int32 B_Q28[ TRANSITION_NB ],
|
||||
opus_int32 A_Q28[ TRANSITION_NA ],
|
||||
const opus_int ind,
|
||||
const opus_int32 fac_Q16
|
||||
)
|
||||
{
|
||||
opus_int nb, na;
|
||||
|
||||
if( ind < TRANSITION_INT_NUM - 1 ) {
|
||||
if( fac_Q16 > 0 ) {
|
||||
if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */
|
||||
/* Piece-wise linear interpolation of B and A */
|
||||
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
|
||||
B_Q28[ nb ] = silk_SMLAWB(
|
||||
silk_Transition_LP_B_Q28[ ind ][ nb ],
|
||||
silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
|
||||
silk_Transition_LP_B_Q28[ ind ][ nb ],
|
||||
fac_Q16 );
|
||||
}
|
||||
for( na = 0; na < TRANSITION_NA; na++ ) {
|
||||
A_Q28[ na ] = silk_SMLAWB(
|
||||
silk_Transition_LP_A_Q28[ ind ][ na ],
|
||||
silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
|
||||
silk_Transition_LP_A_Q28[ ind ][ na ],
|
||||
fac_Q16 );
|
||||
}
|
||||
} else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */
|
||||
silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) );
|
||||
/* Piece-wise linear interpolation of B and A */
|
||||
for( nb = 0; nb < TRANSITION_NB; nb++ ) {
|
||||
B_Q28[ nb ] = silk_SMLAWB(
|
||||
silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
|
||||
silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
|
||||
silk_Transition_LP_B_Q28[ ind ][ nb ],
|
||||
fac_Q16 - ( (opus_int32)1 << 16 ) );
|
||||
}
|
||||
for( na = 0; na < TRANSITION_NA; na++ ) {
|
||||
A_Q28[ na ] = silk_SMLAWB(
|
||||
silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
|
||||
silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
|
||||
silk_Transition_LP_A_Q28[ ind ][ na ],
|
||||
fac_Q16 - ( (opus_int32)1 << 16 ) );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) );
|
||||
silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) );
|
||||
}
|
||||
} else {
|
||||
silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) );
|
||||
silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Low-pass filter with variable cutoff frequency based on */
|
||||
/* piece-wise linear interpolation between elliptic filters */
|
||||
/* Start by setting psEncC->mode <> 0; */
|
||||
/* Deactivate by setting psEncC->mode = 0; */
|
||||
void silk_LP_variable_cutoff(
|
||||
silk_LP_state *psLP, /* I/O LP filter state */
|
||||
opus_int16 *frame, /* I/O Low-pass filtered output signal */
|
||||
const opus_int frame_length /* I Frame length */
|
||||
)
|
||||
{
|
||||
opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
|
||||
opus_int ind = 0;
|
||||
|
||||
silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES );
|
||||
|
||||
/* Run filter if needed */
|
||||
if( psLP->mode != 0 ) {
|
||||
/* Calculate index and interpolation factor for interpolation */
|
||||
#if( TRANSITION_INT_STEPS == 64 )
|
||||
fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 );
|
||||
#else
|
||||
fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES );
|
||||
#endif
|
||||
ind = silk_RSHIFT( fac_Q16, 16 );
|
||||
fac_Q16 -= silk_LSHIFT( ind, 16 );
|
||||
|
||||
silk_assert( ind >= 0 );
|
||||
silk_assert( ind < TRANSITION_INT_NUM );
|
||||
|
||||
/* Interpolate filter coefficients */
|
||||
silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
|
||||
|
||||
/* Update transition frame number for next frame */
|
||||
psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES );
|
||||
|
||||
/* ARMA low-pass filtering */
|
||||
silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
|
||||
silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1);
|
||||
}
|
||||
}
|
718
node_modules/node-opus/deps/opus/silk/MacroCount.h
generated
vendored
Normal file
718
node_modules/node-opus/deps/opus/silk/MacroCount.h
generated
vendored
Normal file
@ -0,0 +1,718 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SIGPROCFIX_API_MACROCOUNT_H
|
||||
#define SIGPROCFIX_API_MACROCOUNT_H
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef silk_MACRO_COUNT
|
||||
#define varDefine opus_int64 ops_count = 0;
|
||||
|
||||
extern opus_int64 ops_count;
|
||||
|
||||
static OPUS_INLINE opus_int64 silk_SaveCount(){
|
||||
return(ops_count);
|
||||
}
|
||||
|
||||
static OPUS_INLINE opus_int64 silk_SaveResetCount(){
|
||||
opus_int64 ret;
|
||||
|
||||
ret = ops_count;
|
||||
ops_count = 0;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static OPUS_INLINE silk_PrintCount(){
|
||||
printf("ops_count = %d \n ", (opus_int32)ops_count);
|
||||
}
|
||||
|
||||
#undef silk_MUL
|
||||
static OPUS_INLINE opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
ops_count += 4;
|
||||
ret = a32 * b32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_MUL_uint
|
||||
static OPUS_INLINE opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){
|
||||
opus_uint32 ret;
|
||||
ops_count += 4;
|
||||
ret = a32 * b32;
|
||||
return ret;
|
||||
}
|
||||
#undef silk_MLA
|
||||
static OPUS_INLINE opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 4;
|
||||
ret = a32 + b32 * c32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_MLA_uint
|
||||
static OPUS_INLINE opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){
|
||||
opus_uint32 ret;
|
||||
ops_count += 4;
|
||||
ret = a32 + b32 * c32;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULWB
|
||||
static OPUS_INLINE opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
ops_count += 5;
|
||||
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||
return ret;
|
||||
}
|
||||
#undef silk_SMLAWB
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 5;
|
||||
ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULWT
|
||||
static OPUS_INLINE opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
ops_count += 4;
|
||||
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
||||
return ret;
|
||||
}
|
||||
#undef silk_SMLAWT
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 4;
|
||||
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULBB
|
||||
static OPUS_INLINE opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32);
|
||||
return ret;
|
||||
}
|
||||
#undef silk_SMLABB
|
||||
static OPUS_INLINE opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULBT
|
||||
static OPUS_INLINE opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){
|
||||
opus_int32 ret;
|
||||
ops_count += 4;
|
||||
ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLABT
|
||||
static OPUS_INLINE opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULTT
|
||||
static OPUS_INLINE opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = (a32 >> 16) * (b32 >> 16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLATT
|
||||
static OPUS_INLINE opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/
|
||||
#undef silk_MLA_ovflw
|
||||
#define silk_MLA_ovflw silk_MLA
|
||||
|
||||
#undef silk_SMLABB_ovflw
|
||||
#define silk_SMLABB_ovflw silk_SMLABB
|
||||
|
||||
#undef silk_SMLABT_ovflw
|
||||
#define silk_SMLABT_ovflw silk_SMLABT
|
||||
|
||||
#undef silk_SMLATT_ovflw
|
||||
#define silk_SMLATT_ovflw silk_SMLATT
|
||||
|
||||
#undef silk_SMLAWB_ovflw
|
||||
#define silk_SMLAWB_ovflw silk_SMLAWB
|
||||
|
||||
#undef silk_SMLAWT_ovflw
|
||||
#define silk_SMLAWT_ovflw silk_SMLAWT
|
||||
|
||||
#undef silk_SMULL
|
||||
static OPUS_INLINE opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){
|
||||
opus_int64 ret;
|
||||
ops_count += 8;
|
||||
ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLAL
|
||||
static OPUS_INLINE opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){
|
||||
opus_int64 ret;
|
||||
ops_count += 8;
|
||||
ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32));
|
||||
return ret;
|
||||
}
|
||||
#undef silk_SMLALBB
|
||||
static OPUS_INLINE opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){
|
||||
opus_int64 ret;
|
||||
ops_count += 4;
|
||||
ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef SigProcFIX_CLZ16
|
||||
static OPUS_INLINE opus_int32 SigProcFIX_CLZ16(opus_int16 in16)
|
||||
{
|
||||
opus_int32 out32 = 0;
|
||||
ops_count += 10;
|
||||
if( in16 == 0 ) {
|
||||
return 16;
|
||||
}
|
||||
/* test nibbles */
|
||||
if( in16 & 0xFF00 ) {
|
||||
if( in16 & 0xF000 ) {
|
||||
in16 >>= 12;
|
||||
} else {
|
||||
out32 += 4;
|
||||
in16 >>= 8;
|
||||
}
|
||||
} else {
|
||||
if( in16 & 0xFFF0 ) {
|
||||
out32 += 8;
|
||||
in16 >>= 4;
|
||||
} else {
|
||||
out32 += 12;
|
||||
}
|
||||
}
|
||||
/* test bits and return */
|
||||
if( in16 & 0xC ) {
|
||||
if( in16 & 0x8 )
|
||||
return out32 + 0;
|
||||
else
|
||||
return out32 + 1;
|
||||
} else {
|
||||
if( in16 & 0xE )
|
||||
return out32 + 2;
|
||||
else
|
||||
return out32 + 3;
|
||||
}
|
||||
}
|
||||
|
||||
#undef SigProcFIX_CLZ32
|
||||
static OPUS_INLINE opus_int32 SigProcFIX_CLZ32(opus_int32 in32)
|
||||
{
|
||||
/* test highest 16 bits and convert to opus_int16 */
|
||||
ops_count += 2;
|
||||
if( in32 & 0xFFFF0000 ) {
|
||||
return SigProcFIX_CLZ16((opus_int16)(in32 >> 16));
|
||||
} else {
|
||||
return SigProcFIX_CLZ16((opus_int16)in32) + 16;
|
||||
}
|
||||
}
|
||||
|
||||
#undef silk_DIV32
|
||||
static OPUS_INLINE opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){
|
||||
ops_count += 64;
|
||||
return a32 / b32;
|
||||
}
|
||||
|
||||
#undef silk_DIV32_16
|
||||
static OPUS_INLINE opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){
|
||||
ops_count += 32;
|
||||
return a32 / b32;
|
||||
}
|
||||
|
||||
#undef silk_SAT8
|
||||
static OPUS_INLINE opus_int8 silk_SAT8(opus_int64 a){
|
||||
opus_int8 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \
|
||||
((a) < silk_int8_MIN ? silk_int8_MIN : (a)));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#undef silk_SAT16
|
||||
static OPUS_INLINE opus_int16 silk_SAT16(opus_int64 a){
|
||||
opus_int16 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \
|
||||
((a) < silk_int16_MIN ? silk_int16_MIN : (a)));
|
||||
return(tmp);
|
||||
}
|
||||
#undef silk_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_SAT32(opus_int64 a){
|
||||
opus_int32 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \
|
||||
((a) < silk_int32_MIN ? silk_int32_MIN : (a)));
|
||||
return(tmp);
|
||||
}
|
||||
#undef silk_POS_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_POS_SAT32(opus_int64 a){
|
||||
opus_int32 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#undef silk_ADD_POS_SAT8
|
||||
static OPUS_INLINE opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){
|
||||
opus_int8 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)));
|
||||
return(tmp);
|
||||
}
|
||||
#undef silk_ADD_POS_SAT16
|
||||
static OPUS_INLINE opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){
|
||||
opus_int16 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#undef silk_ADD_POS_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
|
||||
opus_int32 tmp;
|
||||
ops_count += 1;
|
||||
tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#undef silk_ADD_POS_SAT64
|
||||
static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
|
||||
opus_int64 tmp;
|
||||
ops_count += 1;
|
||||
tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT8
|
||||
static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
|
||||
opus_int8 ret;
|
||||
ops_count += 1;
|
||||
ret = a << shift;
|
||||
return ret;
|
||||
}
|
||||
#undef silk_LSHIFT16
|
||||
static OPUS_INLINE opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){
|
||||
opus_int16 ret;
|
||||
ops_count += 1;
|
||||
ret = a << shift;
|
||||
return ret;
|
||||
}
|
||||
#undef silk_LSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a << shift;
|
||||
return ret;
|
||||
}
|
||||
#undef silk_LSHIFT64
|
||||
static OPUS_INLINE opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){
|
||||
ops_count += 1;
|
||||
return a << shift;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT_ovflw
|
||||
static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){
|
||||
ops_count += 1;
|
||||
return a << shift;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT_uint
|
||||
static OPUS_INLINE opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
||||
opus_uint32 ret;
|
||||
ops_count += 1;
|
||||
ret = a << shift;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT8
|
||||
static OPUS_INLINE opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){
|
||||
ops_count += 1;
|
||||
return a >> shift;
|
||||
}
|
||||
#undef silk_RSHIFT16
|
||||
static OPUS_INLINE opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){
|
||||
ops_count += 1;
|
||||
return a >> shift;
|
||||
}
|
||||
#undef silk_RSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){
|
||||
ops_count += 1;
|
||||
return a >> shift;
|
||||
}
|
||||
#undef silk_RSHIFT64
|
||||
static OPUS_INLINE opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){
|
||||
ops_count += 1;
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_uint
|
||||
static OPUS_INLINE opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
||||
ops_count += 1;
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_ADD_LSHIFT
|
||||
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b << shift);
|
||||
return ret; /* shift >= 0*/
|
||||
}
|
||||
#undef silk_ADD_LSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b << shift);
|
||||
return ret; /* shift >= 0*/
|
||||
}
|
||||
#undef silk_ADD_LSHIFT_uint
|
||||
static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
||||
opus_uint32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b << shift);
|
||||
return ret; /* shift >= 0*/
|
||||
}
|
||||
#undef silk_ADD_RSHIFT
|
||||
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b >> shift);
|
||||
return ret; /* shift > 0*/
|
||||
}
|
||||
#undef silk_ADD_RSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b >> shift);
|
||||
return ret; /* shift > 0*/
|
||||
}
|
||||
#undef silk_ADD_RSHIFT_uint
|
||||
static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
||||
opus_uint32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + (b >> shift);
|
||||
return ret; /* shift > 0*/
|
||||
}
|
||||
#undef silk_SUB_LSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a - (b << shift);
|
||||
return ret; /* shift >= 0*/
|
||||
}
|
||||
#undef silk_SUB_RSHIFT32
|
||||
static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a - (b >> shift);
|
||||
return ret; /* shift > 0*/
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_ROUND
|
||||
static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){
|
||||
opus_int32 ret;
|
||||
ops_count += 3;
|
||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_ROUND64
|
||||
static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){
|
||||
opus_int64 ret;
|
||||
ops_count += 6;
|
||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_abs_int64
|
||||
static OPUS_INLINE opus_int64 silk_abs_int64(opus_int64 a){
|
||||
ops_count += 1;
|
||||
return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/
|
||||
}
|
||||
|
||||
#undef silk_abs_int32
|
||||
static OPUS_INLINE opus_int32 silk_abs_int32(opus_int32 a){
|
||||
ops_count += 1;
|
||||
return silk_abs(a);
|
||||
}
|
||||
|
||||
|
||||
#undef silk_min
|
||||
static silk_min(a, b){
|
||||
ops_count += 1;
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_max
|
||||
static silk_max(a, b){
|
||||
ops_count += 1;
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_sign
|
||||
static silk_sign(a){
|
||||
ops_count += 1;
|
||||
return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ));
|
||||
}
|
||||
|
||||
#undef silk_ADD16
|
||||
static OPUS_INLINE opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){
|
||||
opus_int16 ret;
|
||||
ops_count += 1;
|
||||
ret = a + b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD32
|
||||
static OPUS_INLINE opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a + b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD64
|
||||
static OPUS_INLINE opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){
|
||||
opus_int64 ret;
|
||||
ops_count += 2;
|
||||
ret = a + b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB16
|
||||
static OPUS_INLINE opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){
|
||||
opus_int16 ret;
|
||||
ops_count += 1;
|
||||
ret = a - b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB32
|
||||
static OPUS_INLINE opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){
|
||||
opus_int32 ret;
|
||||
ops_count += 1;
|
||||
ret = a - b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB64
|
||||
static OPUS_INLINE opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){
|
||||
opus_int64 ret;
|
||||
ops_count += 2;
|
||||
ret = a - b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT16
|
||||
static OPUS_INLINE opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||
opus_int16 res;
|
||||
/* Nb will be counted in AKP_add32 and silk_SAT16*/
|
||||
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 res;
|
||||
ops_count += 1;
|
||||
res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
|
||||
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
||||
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT64
|
||||
static OPUS_INLINE opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||
opus_int64 res;
|
||||
ops_count += 1;
|
||||
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
||||
((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \
|
||||
((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT16
|
||||
static OPUS_INLINE opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||
opus_int16 res;
|
||||
silk_assert(0);
|
||||
/* Nb will be counted in sub-macros*/
|
||||
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
||||
opus_int32 res;
|
||||
ops_count += 1;
|
||||
res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
|
||||
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
||||
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT64
|
||||
static OPUS_INLINE opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||
opus_int64 res;
|
||||
ops_count += 1;
|
||||
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
||||
(( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \
|
||||
((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SMULWW
|
||||
static OPUS_INLINE opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){
|
||||
opus_int32 ret;
|
||||
/* Nb will be counted in sub-macros*/
|
||||
ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLAWW
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||
opus_int32 ret;
|
||||
/* Nb will be counted in sub-macros*/
|
||||
ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16));
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_min_int
|
||||
static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
#undef silk_min_16
|
||||
static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_min_32
|
||||
static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_min_64
|
||||
static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
/* silk_min() versions with typecast in the function call */
|
||||
#undef silk_max_int
|
||||
static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_max_16
|
||||
static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
#undef silk_max_32
|
||||
static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
#undef silk_max_64
|
||||
static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
|
||||
{
|
||||
ops_count += 1;
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
|
||||
#undef silk_LIMIT_int
|
||||
static OPUS_INLINE opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2)
|
||||
{
|
||||
opus_int ret;
|
||||
ops_count += 6;
|
||||
|
||||
ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
|
||||
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#undef silk_LIMIT_16
|
||||
static OPUS_INLINE opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2)
|
||||
{
|
||||
opus_int16 ret;
|
||||
ops_count += 6;
|
||||
|
||||
ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
|
||||
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
#undef silk_LIMIT_32
|
||||
static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
|
||||
{
|
||||
opus_int32 ret;
|
||||
ops_count += 6;
|
||||
|
||||
ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
|
||||
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))));
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#else
|
||||
#define varDefine
|
||||
#define silk_SaveCount()
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
952
node_modules/node-opus/deps/opus/silk/MacroDebug.h
generated
vendored
Normal file
952
node_modules/node-opus/deps/opus/silk/MacroDebug.h
generated
vendored
Normal file
@ -0,0 +1,952 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Copyright (C) 2012 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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MACRO_DEBUG_H
|
||||
#define MACRO_DEBUG_H
|
||||
|
||||
/* Redefine macro functions with extensive assertion in DEBUG mode.
|
||||
As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */
|
||||
|
||||
#if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT)
|
||||
|
||||
#undef silk_ADD16
|
||||
#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){
|
||||
opus_int16 ret;
|
||||
|
||||
ret = a + b;
|
||||
if ( ret != silk_ADD_SAT16( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD16(%d, %d) in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD32
|
||||
#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){
|
||||
opus_int32 ret;
|
||||
|
||||
ret = a + b;
|
||||
if ( ret != silk_ADD_SAT32( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD64
|
||||
#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){
|
||||
opus_int64 ret;
|
||||
|
||||
ret = a + b;
|
||||
if ( ret != silk_ADD_SAT64( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB16
|
||||
#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){
|
||||
opus_int16 ret;
|
||||
|
||||
ret = a - b;
|
||||
if ( ret != silk_SUB_SAT16( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB16(%d, %d) in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB32
|
||||
#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){
|
||||
opus_int32 ret;
|
||||
|
||||
ret = a - b;
|
||||
if ( ret != silk_SUB_SAT32( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SUB64
|
||||
#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){
|
||||
opus_int64 ret;
|
||||
|
||||
ret = a - b;
|
||||
if ( ret != silk_SUB_SAT64( a, b ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT16
|
||||
#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) {
|
||||
opus_int16 res;
|
||||
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
||||
if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT32
|
||||
#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
opus_int32 res;
|
||||
res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
||||
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
||||
((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) );
|
||||
if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_ADD_SAT64
|
||||
#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) {
|
||||
opus_int64 res;
|
||||
int fail = 0;
|
||||
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
||||
((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \
|
||||
((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) );
|
||||
if( res != a64 + b64 ) {
|
||||
/* Check that we saturated to the correct extreme value */
|
||||
if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) ||
|
||||
( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) )
|
||||
{
|
||||
fail = 1;
|
||||
}
|
||||
} else {
|
||||
/* Saturation not necessary */
|
||||
fail = res != a64 + b64;
|
||||
}
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT16
|
||||
#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) {
|
||||
opus_int16 res;
|
||||
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
||||
if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT32
|
||||
#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) {
|
||||
opus_int32 res;
|
||||
res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
||||
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
||||
((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) );
|
||||
if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_SUB_SAT64
|
||||
#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) {
|
||||
opus_int64 res;
|
||||
int fail = 0;
|
||||
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
||||
(( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \
|
||||
((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) );
|
||||
if( res != a64 - b64 ) {
|
||||
/* Check that we saturated to the correct extreme value */
|
||||
if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) ||
|
||||
( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ))
|
||||
{
|
||||
fail = 1;
|
||||
}
|
||||
} else {
|
||||
/* Saturation not necessary */
|
||||
fail = res != a64 - b64;
|
||||
}
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#undef silk_MUL
|
||||
#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
opus_int64 ret64;
|
||||
ret = a32 * b32;
|
||||
ret64 = (opus_int64)a32 * (opus_int64)b32;
|
||||
if ( (opus_int64)ret != ret64 )
|
||||
{
|
||||
fprintf (stderr, "silk_MUL(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_MUL_uint
|
||||
#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){
|
||||
opus_uint32 ret;
|
||||
ret = a32 * b32;
|
||||
if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 )
|
||||
{
|
||||
fprintf (stderr, "silk_MUL_uint(%u, %u) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_MLA
|
||||
#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a32 + b32 * c32;
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
||||
{
|
||||
fprintf (stderr, "silk_MLA(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_MLA_uint
|
||||
#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){
|
||||
opus_uint32 ret;
|
||||
ret = a32 + b32 * c32;
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
||||
{
|
||||
fprintf (stderr, "silk_MLA_uint(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULWB
|
||||
#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||
if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 )
|
||||
{
|
||||
fprintf (stderr, "silk_SMULWB(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLAWB
|
||||
#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) );
|
||||
if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULWT
|
||||
#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
||||
if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 )
|
||||
{
|
||||
fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLAWT
|
||||
#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLAWT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULL
|
||||
#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){
|
||||
opus_int64 ret64;
|
||||
int fail = 0;
|
||||
ret64 = a64 * b64;
|
||||
if( b64 != 0 ) {
|
||||
fail = a64 != (ret64 / b64);
|
||||
} else if( a64 != 0 ) {
|
||||
fail = b64 != (ret64 / a64);
|
||||
}
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_SMULL(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret64;
|
||||
}
|
||||
|
||||
/* no checking needed for silk_SMULBB */
|
||||
#undef silk_SMLABB
|
||||
#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLABB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* no checking needed for silk_SMULBT */
|
||||
#undef silk_SMLABT
|
||||
#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLABT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* no checking needed for silk_SMULTT */
|
||||
#undef silk_SMLATT
|
||||
#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
||||
if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLATT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMULWW
|
||||
#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
opus_int32 ret, tmp1, tmp2;
|
||||
opus_int64 ret64;
|
||||
int fail = 0;
|
||||
|
||||
ret = silk_SMULWB( a32, b32 );
|
||||
tmp1 = silk_RSHIFT_ROUND( b32, 16 );
|
||||
tmp2 = silk_MUL( a32, tmp1 );
|
||||
|
||||
fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1;
|
||||
|
||||
tmp1 = ret;
|
||||
ret = silk_ADD32( tmp1, tmp2 );
|
||||
fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 );
|
||||
|
||||
ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 );
|
||||
fail |= (opus_int64)ret != ret64;
|
||||
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_SMLAWW
|
||||
#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||
opus_int32 ret, tmp;
|
||||
|
||||
tmp = silk_SMULWW( b32, c32 );
|
||||
ret = silk_ADD32( a32, tmp );
|
||||
if ( ret != silk_ADD_SAT32( a32, tmp ) )
|
||||
{
|
||||
fprintf (stderr, "silk_SMLAWW(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
|
||||
#undef silk_MLA_ovflw
|
||||
#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32)))
|
||||
#undef silk_SMLABB_ovflw
|
||||
#define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))
|
||||
|
||||
/* no checking needed for silk_SMULL
|
||||
no checking needed for silk_SMLAL
|
||||
no checking needed for silk_SMLALBB
|
||||
no checking needed for SigProcFIX_CLZ16
|
||||
no checking needed for SigProcFIX_CLZ32*/
|
||||
|
||||
#undef silk_DIV32
|
||||
#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
if ( b32 == 0 )
|
||||
{
|
||||
fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a32 / b32;
|
||||
}
|
||||
|
||||
#undef silk_DIV32_16
|
||||
#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||
int fail = 0;
|
||||
fail |= b32 == 0;
|
||||
fail |= b32 > silk_int16_MAX;
|
||||
fail |= b32 < silk_int16_MIN;
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_DIV32_16(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a32 / b32;
|
||||
}
|
||||
|
||||
/* no checking needed for silk_SAT8
|
||||
no checking needed for silk_SAT16
|
||||
no checking needed for silk_SAT32
|
||||
no checking needed for silk_POS_SAT32
|
||||
no checking needed for silk_ADD_POS_SAT8
|
||||
no checking needed for silk_ADD_POS_SAT16
|
||||
no checking needed for silk_ADD_POS_SAT32
|
||||
no checking needed for silk_ADD_POS_SAT64 */
|
||||
|
||||
#undef silk_LSHIFT8
|
||||
#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
||||
opus_int8 ret;
|
||||
int fail = 0;
|
||||
ret = a << shift;
|
||||
fail |= shift < 0;
|
||||
fail |= shift >= 8;
|
||||
fail |= (opus_int64)ret != ((opus_int64)a) << shift;
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT16
|
||||
#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
||||
opus_int16 ret;
|
||||
int fail = 0;
|
||||
ret = a << shift;
|
||||
fail |= shift < 0;
|
||||
fail |= shift >= 16;
|
||||
fail |= (opus_int64)ret != ((opus_int64)a) << shift;
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT32
|
||||
#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
int fail = 0;
|
||||
ret = a << shift;
|
||||
fail |= shift < 0;
|
||||
fail |= shift >= 32;
|
||||
fail |= (opus_int64)ret != ((opus_int64)a) << shift;
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT64
|
||||
#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){
|
||||
opus_int64 ret;
|
||||
int fail = 0;
|
||||
ret = a << shift;
|
||||
fail |= shift < 0;
|
||||
fail |= shift >= 64;
|
||||
fail |= (ret>>shift) != ((opus_int64)a);
|
||||
if ( fail )
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT_ovflw
|
||||
#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a << shift;
|
||||
}
|
||||
|
||||
#undef silk_LSHIFT_uint
|
||||
#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
||||
opus_uint32 ret;
|
||||
ret = a << shift;
|
||||
if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift))
|
||||
{
|
||||
fprintf (stderr, "silk_LSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT8
|
||||
#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift>=8) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT16
|
||||
#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift>=16) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT32
|
||||
#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift>=32) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT64
|
||||
#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift>=64) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_uint
|
||||
#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
||||
if ( (shift < 0) || (shift>32) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return a >> shift;
|
||||
}
|
||||
|
||||
#undef silk_ADD_LSHIFT
|
||||
#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){
|
||||
opus_int16 ret;
|
||||
ret = a + (b << shift);
|
||||
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift >= 0 */
|
||||
}
|
||||
|
||||
#undef silk_ADD_LSHIFT32
|
||||
#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a + (b << shift);
|
||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift >= 0 */
|
||||
}
|
||||
|
||||
#undef silk_ADD_LSHIFT_uint
|
||||
#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
||||
opus_uint32 ret;
|
||||
ret = a + (b << shift);
|
||||
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift >= 0 */
|
||||
}
|
||||
|
||||
#undef silk_ADD_RSHIFT
|
||||
#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){
|
||||
opus_int16 ret;
|
||||
ret = a + (b >> shift);
|
||||
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift > 0 */
|
||||
}
|
||||
|
||||
#undef silk_ADD_RSHIFT32
|
||||
#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a + (b >> shift);
|
||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift > 0 */
|
||||
}
|
||||
|
||||
#undef silk_ADD_RSHIFT_uint
|
||||
#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
||||
opus_uint32 ret;
|
||||
ret = a + (b >> shift);
|
||||
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift > 0 */
|
||||
}
|
||||
|
||||
#undef silk_SUB_LSHIFT32
|
||||
#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a - (b << shift);
|
||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift >= 0 */
|
||||
}
|
||||
|
||||
#undef silk_SUB_RSHIFT32
|
||||
#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = a - (b >> shift);
|
||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) )
|
||||
{
|
||||
fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret; /* shift > 0 */
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_ROUND
|
||||
#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||
opus_int32 ret;
|
||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||
/* the marco definition can't handle a shift of zero */
|
||||
if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef silk_RSHIFT_ROUND64
|
||||
#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){
|
||||
opus_int64 ret;
|
||||
/* the marco definition can't handle a shift of zero */
|
||||
if ( (shift <= 0) || (shift>=64) )
|
||||
{
|
||||
fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* silk_abs is used on floats also, so doesn't work... */
|
||||
/*#undef silk_abs
|
||||
static OPUS_INLINE opus_int32 silk_abs(opus_int32 a){
|
||||
silk_assert(a != 0x80000000);
|
||||
return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN
|
||||
}*/
|
||||
|
||||
#undef silk_abs_int64
|
||||
#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){
|
||||
if ( a == silk_int64_MIN )
|
||||
{
|
||||
fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */
|
||||
}
|
||||
|
||||
#undef silk_abs_int32
|
||||
#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){
|
||||
if ( a == silk_int32_MIN )
|
||||
{
|
||||
fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return silk_abs(a);
|
||||
}
|
||||
|
||||
#undef silk_CHECK_FIT8
|
||||
#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){
|
||||
opus_int8 ret;
|
||||
ret = (opus_int8)a;
|
||||
if ( (opus_int64)ret != a )
|
||||
{
|
||||
fprintf (stderr, "silk_CHECK_FIT8(%lld) in %s: line %d\n", (long long)a, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#undef silk_CHECK_FIT16
|
||||
#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){
|
||||
opus_int16 ret;
|
||||
ret = (opus_int16)a;
|
||||
if ( (opus_int64)ret != a )
|
||||
{
|
||||
fprintf (stderr, "silk_CHECK_FIT16(%lld) in %s: line %d\n", (long long)a, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#undef silk_CHECK_FIT32
|
||||
#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__)
|
||||
static OPUS_INLINE opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){
|
||||
opus_int32 ret;
|
||||
ret = (opus_int32)a;
|
||||
if ( (opus_int64)ret != a )
|
||||
{
|
||||
fprintf (stderr, "silk_CHECK_FIT32(%lld) in %s: line %d\n", (long long)a, file, line);
|
||||
#ifdef FIXED_DEBUG_ASSERT
|
||||
silk_assert( 0 );
|
||||
#endif
|
||||
}
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* no checking for silk_NSHIFT_MUL_32_32
|
||||
no checking for silk_NSHIFT_MUL_16_16
|
||||
no checking needed for silk_min
|
||||
no checking needed for silk_max
|
||||
no checking needed for silk_sign
|
||||
*/
|
||||
|
||||
#endif
|
||||
#endif /* MACRO_DEBUG_H */
|
178
node_modules/node-opus/deps/opus/silk/NLSF2A.c
generated
vendored
Normal file
178
node_modules/node-opus/deps/opus/silk/NLSF2A.c
generated
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/* conversion between prediction filter coefficients and LSFs */
|
||||
/* order should be even */
|
||||
/* a piecewise linear approximation maps LSF <-> cos(LSF) */
|
||||
/* therefore the result is not accurate LSFs, but the two */
|
||||
/* functions are accurate inverses of each other */
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "tables.h"
|
||||
|
||||
#define QA 16
|
||||
|
||||
/* helper function for NLSF2A(..) */
|
||||
static OPUS_INLINE void silk_NLSF2A_find_poly(
|
||||
opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */
|
||||
const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */
|
||||
opus_int dd /* I polynomial order (= 1/2 * filter order) */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 ftmp;
|
||||
|
||||
out[0] = silk_LSHIFT( 1, QA );
|
||||
out[1] = -cLSF[0];
|
||||
for( k = 1; k < dd; k++ ) {
|
||||
ftmp = cLSF[2*k]; /* QA*/
|
||||
out[k+1] = silk_LSHIFT( out[k-1], 1 ) - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[k] ), QA );
|
||||
for( n = k; n > 1; n-- ) {
|
||||
out[n] += out[n-2] - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[n-1] ), QA );
|
||||
}
|
||||
out[1] -= ftmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||
void silk_NLSF2A(
|
||||
opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
|
||||
const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
|
||||
const opus_int d /* I filter order (should be even) */
|
||||
)
|
||||
{
|
||||
/* This ordering was found to maximize quality. It improves numerical accuracy of
|
||||
silk_NLSF2A_find_poly() compared to "standard" ordering. */
|
||||
static const unsigned char ordering16[16] = {
|
||||
0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1
|
||||
};
|
||||
static const unsigned char ordering10[10] = {
|
||||
0, 9, 6, 3, 4, 5, 8, 1, 2, 7
|
||||
};
|
||||
const unsigned char *ordering;
|
||||
opus_int k, i, dd;
|
||||
opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
||||
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
||||
opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 maxabs, absval, idx=0, sc_Q16;
|
||||
|
||||
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
||||
silk_assert( d==10||d==16 );
|
||||
|
||||
/* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
|
||||
ordering = d == 16 ? ordering16 : ordering10;
|
||||
for( k = 0; k < d; k++ ) {
|
||||
silk_assert(NLSF[k] >= 0 );
|
||||
|
||||
/* f_int on a scale 0-127 (rounded down) */
|
||||
f_int = silk_RSHIFT( NLSF[k], 15 - 7 );
|
||||
|
||||
/* f_frac, range: 0..255 */
|
||||
f_frac = NLSF[k] - silk_LSHIFT( f_int, 15 - 7 );
|
||||
|
||||
silk_assert(f_int >= 0);
|
||||
silk_assert(f_int < LSF_COS_TAB_SZ_FIX );
|
||||
|
||||
/* Read start and end value from table */
|
||||
cos_val = silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */
|
||||
delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
|
||||
|
||||
/* Linear interpolation */
|
||||
cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */
|
||||
}
|
||||
|
||||
dd = silk_RSHIFT( d, 1 );
|
||||
|
||||
/* generate even and odd polynomials using convolution */
|
||||
silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd );
|
||||
silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd );
|
||||
|
||||
/* convert even and odd polynomials to opus_int32 Q12 filter coefs */
|
||||
for( k = 0; k < dd; k++ ) {
|
||||
Ptmp = P[ k+1 ] + P[ k ];
|
||||
Qtmp = Q[ k+1 ] - Q[ k ];
|
||||
|
||||
/* the Ptmp and Qtmp values at this stage need to fit in int32 */
|
||||
a32_QA1[ k ] = -Qtmp - Ptmp; /* QA+1 */
|
||||
a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */
|
||||
}
|
||||
|
||||
/* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
|
||||
for( i = 0; i < 10; i++ ) {
|
||||
/* Find maximum absolute value and its index */
|
||||
maxabs = 0;
|
||||
for( k = 0; k < d; k++ ) {
|
||||
absval = silk_abs( a32_QA1[k] );
|
||||
if( absval > maxabs ) {
|
||||
maxabs = absval;
|
||||
idx = k;
|
||||
}
|
||||
}
|
||||
maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||
|
||||
if( maxabs > silk_int16_MAX ) {
|
||||
/* Reduce magnitude of prediction coefficients */
|
||||
maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
|
||||
sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
|
||||
silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
|
||||
silk_bwexpander_32( a32_QA1, d, sc_Q16 );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i == 10 ) {
|
||||
/* Reached the last iteration, clip the coefficients */
|
||||
for( k = 0; k < d; k++ ) {
|
||||
a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */
|
||||
a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
|
||||
}
|
||||
} else {
|
||||
for( k = 0; k < d; k++ ) {
|
||||
a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
||||
if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
|
||||
/* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
|
||||
/* on the unscaled coefficients, convert to Q12 and measure again */
|
||||
silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
|
||||
for( k = 0; k < d; k++ ) {
|
||||
a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
68
node_modules/node-opus/deps/opus/silk/NLSF_VQ.c
generated
vendored
Normal file
68
node_modules/node-opus/deps/opus/silk/NLSF_VQ.c
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
|
||||
void silk_NLSF_VQ(
|
||||
opus_int32 err_Q26[], /* O Quantization errors [K] */
|
||||
const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
|
||||
const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
|
||||
const opus_int K, /* I Number of codebook vectors */
|
||||
const opus_int LPC_order /* I Number of LPCs */
|
||||
)
|
||||
{
|
||||
opus_int i, m;
|
||||
opus_int32 diff_Q15, sum_error_Q30, sum_error_Q26;
|
||||
|
||||
silk_assert( LPC_order <= 16 );
|
||||
silk_assert( ( LPC_order & 1 ) == 0 );
|
||||
|
||||
/* Loop over codebook */
|
||||
for( i = 0; i < K; i++ ) {
|
||||
sum_error_Q26 = 0;
|
||||
for( m = 0; m < LPC_order; m += 2 ) {
|
||||
/* Compute weighted squared quantization error for index m */
|
||||
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
||||
sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );
|
||||
|
||||
/* Compute weighted squared quantization error for index m + 1 */
|
||||
diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
|
||||
sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );
|
||||
|
||||
sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );
|
||||
|
||||
silk_assert( sum_error_Q26 >= 0 );
|
||||
silk_assert( sum_error_Q30 >= 0 );
|
||||
}
|
||||
err_Q26[ i ] = sum_error_Q26;
|
||||
}
|
||||
}
|
80
node_modules/node-opus/deps/opus/silk/NLSF_VQ_weights_laroia.c
generated
vendored
Normal file
80
node_modules/node-opus/deps/opus/silk/NLSF_VQ_weights_laroia.c
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "define.h"
|
||||
#include "SigProc_FIX.h"
|
||||
|
||||
/*
|
||||
R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP
|
||||
Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech,
|
||||
Signal Processing, pp. 641-644, 1991.
|
||||
*/
|
||||
|
||||
/* Laroia low complexity NLSF weights */
|
||||
void silk_NLSF_VQ_weights_laroia(
|
||||
opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */
|
||||
const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */
|
||||
const opus_int D /* I Input vector dimension (even) */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
opus_int32 tmp1_int, tmp2_int;
|
||||
|
||||
silk_assert( D > 0 );
|
||||
silk_assert( ( D & 1 ) == 0 );
|
||||
|
||||
/* First value */
|
||||
tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );
|
||||
tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||
tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );
|
||||
tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int );
|
||||
pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );
|
||||
silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 );
|
||||
|
||||
/* Main loop */
|
||||
for( k = 1; k < D - 1; k += 2 ) {
|
||||
tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );
|
||||
tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||
pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );
|
||||
silk_assert( pNLSFW_Q_OUT[ k ] > 0 );
|
||||
|
||||
tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );
|
||||
tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int );
|
||||
pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );
|
||||
silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 );
|
||||
}
|
||||
|
||||
/* Last value */
|
||||
tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );
|
||||
tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||
pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX );
|
||||
silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 );
|
||||
}
|
101
node_modules/node-opus/deps/opus/silk/NLSF_decode.c
generated
vendored
Normal file
101
node_modules/node-opus/deps/opus/silk/NLSF_decode.c
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Predictive dequantizer for NLSF residuals */
|
||||
static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
|
||||
opus_int16 x_Q10[], /* O Output [ order ] */
|
||||
const opus_int8 indices[], /* I Quantization indices [ order ] */
|
||||
const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
|
||||
const opus_int quant_step_size_Q16, /* I Quantization step size */
|
||||
const opus_int16 order /* I Number of input values */
|
||||
)
|
||||
{
|
||||
opus_int i, out_Q10, pred_Q10;
|
||||
|
||||
out_Q10 = 0;
|
||||
for( i = order-1; i >= 0; i-- ) {
|
||||
pred_Q10 = silk_RSHIFT( silk_SMULBB( out_Q10, (opus_int16)pred_coef_Q8[ i ] ), 8 );
|
||||
out_Q10 = silk_LSHIFT( indices[ i ], 10 );
|
||||
if( out_Q10 > 0 ) {
|
||||
out_Q10 = silk_SUB16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
} else if( out_Q10 < 0 ) {
|
||||
out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
}
|
||||
out_Q10 = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 );
|
||||
x_Q10[ i ] = out_Q10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************/
|
||||
/* NLSF vector decoder */
|
||||
/***********************/
|
||||
void silk_NLSF_decode(
|
||||
opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */
|
||||
opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
||||
const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||
opus_int16 res_Q10[ MAX_LPC_ORDER ];
|
||||
opus_int16 W_tmp_QW[ MAX_LPC_ORDER ];
|
||||
opus_int32 W_tmp_Q9, NLSF_Q15_tmp;
|
||||
const opus_uint8 *pCB_element;
|
||||
|
||||
/* Decode first stage */
|
||||
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
|
||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||
pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
|
||||
}
|
||||
|
||||
/* Unpack entropy table indices and predictor for current CB1 index */
|
||||
silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
|
||||
|
||||
/* Predictive residual dequantizer */
|
||||
silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
|
||||
|
||||
/* Weights from codebook vector */
|
||||
silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );
|
||||
|
||||
/* Apply inverse square-rooted weights and add to output */
|
||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||
NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
|
||||
pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
|
||||
}
|
||||
|
||||
/* NLSF stabilization */
|
||||
silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
|
||||
}
|
217
node_modules/node-opus/deps/opus/silk/NLSF_del_dec_quant.c
generated
vendored
Normal file
217
node_modules/node-opus/deps/opus/silk/NLSF_del_dec_quant.c
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Delayed-decision quantizer for NLSF residuals */
|
||||
opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */
|
||||
opus_int8 indices[], /* O Quantization indices [ order ] */
|
||||
const opus_int16 x_Q10[], /* I Input [ order ] */
|
||||
const opus_int16 w_Q5[], /* I Weights [ order ] */
|
||||
const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
|
||||
const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */
|
||||
const opus_uint8 ec_rates_Q5[], /* I Rates [] */
|
||||
const opus_int quant_step_size_Q16, /* I Quantization step size */
|
||||
const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */
|
||||
const opus_int32 mu_Q20, /* I R/D tradeoff */
|
||||
const opus_int16 order /* I Number of input values */
|
||||
)
|
||||
{
|
||||
opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
|
||||
opus_int pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5;
|
||||
opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16;
|
||||
opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ];
|
||||
opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
|
||||
opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
|
||||
opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
|
||||
opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
|
||||
opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
|
||||
const opus_uint8 *rates_Q5;
|
||||
|
||||
opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
|
||||
opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
|
||||
|
||||
for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
|
||||
{
|
||||
out0_Q10 = silk_LSHIFT( i, 10 );
|
||||
out1_Q10 = silk_ADD16( out0_Q10, 1024 );
|
||||
if( i > 0 ) {
|
||||
out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
} else if( i == 0 ) {
|
||||
out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
} else if( i == -1 ) {
|
||||
out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
} else {
|
||||
out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
|
||||
}
|
||||
out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 );
|
||||
out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 );
|
||||
}
|
||||
|
||||
silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */
|
||||
|
||||
nStates = 1;
|
||||
RD_Q25[ 0 ] = 0;
|
||||
prev_out_Q10[ 0 ] = 0;
|
||||
for( i = order - 1; ; i-- ) {
|
||||
rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
|
||||
pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 );
|
||||
in_Q10 = x_Q10[ i ];
|
||||
for( j = 0; j < nStates; j++ ) {
|
||||
pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] );
|
||||
res_Q10 = silk_SUB16( in_Q10, pred_Q10 );
|
||||
ind_tmp = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 );
|
||||
ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
|
||||
ind[ j ][ i ] = (opus_int8)ind_tmp;
|
||||
|
||||
/* compute outputs for ind_tmp and ind_tmp + 1 */
|
||||
out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
|
||||
out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
|
||||
|
||||
out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 );
|
||||
out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 );
|
||||
prev_out_Q10[ j ] = out0_Q10;
|
||||
prev_out_Q10[ j + nStates ] = out1_Q10;
|
||||
|
||||
/* compute RD for ind_tmp and ind_tmp + 1 */
|
||||
if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
|
||||
rate1_Q5 = 280;
|
||||
} else {
|
||||
rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
|
||||
rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
|
||||
}
|
||||
} else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
rate0_Q5 = 280;
|
||||
rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
|
||||
} else {
|
||||
rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
|
||||
rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
|
||||
}
|
||||
} else {
|
||||
rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
|
||||
rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
|
||||
}
|
||||
RD_tmp_Q25 = RD_Q25[ j ];
|
||||
diff_Q10 = silk_SUB16( in_Q10, out0_Q10 );
|
||||
RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
|
||||
diff_Q10 = silk_SUB16( in_Q10, out1_Q10 );
|
||||
RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
|
||||
}
|
||||
|
||||
if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {
|
||||
/* double number of states and copy */
|
||||
for( j = 0; j < nStates; j++ ) {
|
||||
ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
|
||||
}
|
||||
nStates = silk_LSHIFT( nStates, 1 );
|
||||
for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
|
||||
ind[ j ][ i ] = ind[ j - nStates ][ i ];
|
||||
}
|
||||
} else if( i > 0 ) {
|
||||
/* sort lower and upper half of RD_Q25, pairwise */
|
||||
for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
|
||||
if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
|
||||
RD_max_Q25[ j ] = RD_Q25[ j ];
|
||||
RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
|
||||
RD_Q25[ j ] = RD_min_Q25[ j ];
|
||||
RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
|
||||
/* swap prev_out values */
|
||||
out0_Q10 = prev_out_Q10[ j ];
|
||||
prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
|
||||
prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
|
||||
ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
|
||||
} else {
|
||||
RD_min_Q25[ j ] = RD_Q25[ j ];
|
||||
RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
|
||||
ind_sort[ j ] = j;
|
||||
}
|
||||
}
|
||||
/* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
|
||||
/* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
|
||||
while( 1 ) {
|
||||
min_max_Q25 = silk_int32_MAX;
|
||||
max_min_Q25 = 0;
|
||||
ind_min_max = 0;
|
||||
ind_max_min = 0;
|
||||
for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
|
||||
if( min_max_Q25 > RD_max_Q25[ j ] ) {
|
||||
min_max_Q25 = RD_max_Q25[ j ];
|
||||
ind_min_max = j;
|
||||
}
|
||||
if( max_min_Q25 < RD_min_Q25[ j ] ) {
|
||||
max_min_Q25 = RD_min_Q25[ j ];
|
||||
ind_max_min = j;
|
||||
}
|
||||
}
|
||||
if( min_max_Q25 >= max_min_Q25 ) {
|
||||
break;
|
||||
}
|
||||
/* copy ind_min_max to ind_max_min */
|
||||
ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
|
||||
RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
|
||||
prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
|
||||
RD_min_Q25[ ind_max_min ] = 0;
|
||||
RD_max_Q25[ ind_min_max ] = silk_int32_MAX;
|
||||
silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
|
||||
}
|
||||
/* increment index if it comes from the upper half */
|
||||
for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
|
||||
ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
|
||||
}
|
||||
} else { /* i == 0 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* last sample: find winner, copy indices and return RD value */
|
||||
ind_tmp = 0;
|
||||
min_Q25 = silk_int32_MAX;
|
||||
for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
|
||||
if( min_Q25 > RD_Q25[ j ] ) {
|
||||
min_Q25 = RD_Q25[ j ];
|
||||
ind_tmp = j;
|
||||
}
|
||||
}
|
||||
for( j = 0; j < order; j++ ) {
|
||||
indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
|
||||
silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
|
||||
silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
|
||||
}
|
||||
indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
|
||||
silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
|
||||
silk_assert( min_Q25 >= 0 );
|
||||
return min_Q25;
|
||||
}
|
136
node_modules/node-opus/deps/opus/silk/NLSF_encode.c
generated
vendored
Normal file
136
node_modules/node-opus/deps/opus/silk/NLSF_encode.c
generated
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/***********************/
|
||||
/* NLSF vector encoder */
|
||||
/***********************/
|
||||
opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */
|
||||
opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
||||
opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
||||
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
||||
const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */
|
||||
const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
|
||||
const opus_int nSurvivors, /* I Max survivors after first stage */
|
||||
const opus_int signalType /* I Signal type: 0/1/2 */
|
||||
)
|
||||
{
|
||||
opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
|
||||
opus_int32 W_tmp_Q9;
|
||||
VARDECL( opus_int32, err_Q26 );
|
||||
VARDECL( opus_int32, RD_Q25 );
|
||||
VARDECL( opus_int, tempIndices1 );
|
||||
VARDECL( opus_int8, tempIndices2 );
|
||||
opus_int16 res_Q15[ MAX_LPC_ORDER ];
|
||||
opus_int16 res_Q10[ MAX_LPC_ORDER ];
|
||||
opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
|
||||
opus_int16 W_tmp_QW[ MAX_LPC_ORDER ];
|
||||
opus_int16 W_adj_Q5[ MAX_LPC_ORDER ];
|
||||
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||
const opus_uint8 *pCB_element, *iCDF_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
|
||||
silk_assert( signalType >= 0 && signalType <= 2 );
|
||||
silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
|
||||
|
||||
/* NLSF stabilization */
|
||||
silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
|
||||
|
||||
/* First stage: VQ */
|
||||
ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );
|
||||
silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
|
||||
|
||||
/* Sort the quantization errors */
|
||||
ALLOC( tempIndices1, nSurvivors, opus_int );
|
||||
silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
|
||||
|
||||
ALLOC( RD_Q25, nSurvivors, opus_int32 );
|
||||
ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
|
||||
|
||||
/* Loop over survivors */
|
||||
for( s = 0; s < nSurvivors; s++ ) {
|
||||
ind1 = tempIndices1[ s ];
|
||||
|
||||
/* Residual after first stage */
|
||||
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
|
||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||
NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
|
||||
res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];
|
||||
}
|
||||
|
||||
/* Weights from codebook vector */
|
||||
silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );
|
||||
|
||||
/* Apply square-rooted weights */
|
||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||
W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||
res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
||||
}
|
||||
|
||||
/* Modify input weights accordingly */
|
||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||
W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
|
||||
}
|
||||
|
||||
/* Unpack entropy table indices and predictor for current CB1 index */
|
||||
silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 );
|
||||
|
||||
/* Trellis quantizer */
|
||||
RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix,
|
||||
psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order );
|
||||
|
||||
/* Add rate for first stage */
|
||||
iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ];
|
||||
if( ind1 == 0 ) {
|
||||
prob_Q8 = 256 - iCDF_ptr[ ind1 ];
|
||||
} else {
|
||||
prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ];
|
||||
}
|
||||
bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 );
|
||||
RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) );
|
||||
}
|
||||
|
||||
/* Find the lowest rate-distortion error */
|
||||
silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
|
||||
|
||||
NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];
|
||||
silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
|
||||
|
||||
/* Decode */
|
||||
silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
|
||||
|
||||
RESTORE_STACK;
|
||||
return RD_Q25[ 0 ];
|
||||
}
|
142
node_modules/node-opus/deps/opus/silk/NLSF_stabilize.c
generated
vendored
Normal file
142
node_modules/node-opus/deps/opus/silk/NLSF_stabilize.c
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/* NLSF stabilizer: */
|
||||
/* */
|
||||
/* - Moves NLSFs further apart if they are too close */
|
||||
/* - Moves NLSFs away from borders if they are too close */
|
||||
/* - High effort to achieve a modification with minimum */
|
||||
/* Euclidean distance to input vector */
|
||||
/* - Output are sorted NLSF coefficients */
|
||||
/* */
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
|
||||
/* Constant Definitions */
|
||||
#define MAX_LOOPS 20
|
||||
|
||||
/* NLSF stabilizer, for a single input data vector */
|
||||
void silk_NLSF_stabilize(
|
||||
opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */
|
||||
const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */
|
||||
const opus_int L /* I Number of NLSF parameters in the input vector */
|
||||
)
|
||||
{
|
||||
opus_int i, I=0, k, loops;
|
||||
opus_int16 center_freq_Q15;
|
||||
opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15;
|
||||
|
||||
/* This is necessary to ensure an output within range of a opus_int16 */
|
||||
silk_assert( NDeltaMin_Q15[L] >= 1 );
|
||||
|
||||
for( loops = 0; loops < MAX_LOOPS; loops++ ) {
|
||||
/**************************/
|
||||
/* Find smallest distance */
|
||||
/**************************/
|
||||
/* First element */
|
||||
min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
|
||||
I = 0;
|
||||
/* Middle elements */
|
||||
for( i = 1; i <= L-1; i++ ) {
|
||||
diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||
if( diff_Q15 < min_diff_Q15 ) {
|
||||
min_diff_Q15 = diff_Q15;
|
||||
I = i;
|
||||
}
|
||||
}
|
||||
/* Last element */
|
||||
diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
|
||||
if( diff_Q15 < min_diff_Q15 ) {
|
||||
min_diff_Q15 = diff_Q15;
|
||||
I = L;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Now check if the smallest distance non-negative */
|
||||
/***************************************************/
|
||||
if( min_diff_Q15 >= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( I == 0 ) {
|
||||
/* Move away from lower limit */
|
||||
NLSF_Q15[0] = NDeltaMin_Q15[0];
|
||||
|
||||
} else if( I == L) {
|
||||
/* Move away from higher limit */
|
||||
NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L];
|
||||
|
||||
} else {
|
||||
/* Find the lower extreme for the location of the current center frequency */
|
||||
min_center_Q15 = 0;
|
||||
for( k = 0; k < I; k++ ) {
|
||||
min_center_Q15 += NDeltaMin_Q15[k];
|
||||
}
|
||||
min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||
|
||||
/* Find the upper extreme for the location of the current center frequency */
|
||||
max_center_Q15 = 1 << 15;
|
||||
for( k = L; k > I; k-- ) {
|
||||
max_center_Q15 -= NDeltaMin_Q15[k];
|
||||
}
|
||||
max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||
|
||||
/* Move apart, sorted by value, keeping the same center frequency */
|
||||
center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ),
|
||||
min_center_Q15, max_center_Q15 );
|
||||
NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||
NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
|
||||
}
|
||||
}
|
||||
|
||||
/* Safe and simple fall back method, which is less ideal than the above */
|
||||
if( loops == MAX_LOOPS )
|
||||
{
|
||||
/* Insertion sort (fast for already almost sorted arrays): */
|
||||
/* Best case: O(n) for an already sorted array */
|
||||
/* Worst case: O(n^2) for an inversely sorted array */
|
||||
silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L );
|
||||
|
||||
/* First NLSF should be no less than NDeltaMin[0] */
|
||||
NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
|
||||
|
||||
/* Keep delta_min distance between the NLSFs */
|
||||
for( i = 1; i < L; i++ )
|
||||
NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
|
||||
|
||||
/* Last NLSF should be no higher than 1 - NDeltaMin[L] */
|
||||
NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
|
||||
|
||||
/* Keep NDeltaMin distance between the NLSFs */
|
||||
for( i = L-2; i >= 0; i-- )
|
||||
NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
|
||||
}
|
||||
}
|
55
node_modules/node-opus/deps/opus/silk/NLSF_unpack.c
generated
vendored
Normal file
55
node_modules/node-opus/deps/opus/silk/NLSF_unpack.c
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Unpack predictor values and indices for entropy coding tables */
|
||||
void silk_NLSF_unpack(
|
||||
opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */
|
||||
opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */
|
||||
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
||||
const opus_int CB1_index /* I Index of vector in first LSF codebook */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_uint8 entry;
|
||||
const opus_uint8 *ec_sel_ptr;
|
||||
|
||||
ec_sel_ptr = &psNLSF_CB->ec_sel[ CB1_index * psNLSF_CB->order / 2 ];
|
||||
for( i = 0; i < psNLSF_CB->order; i += 2 ) {
|
||||
entry = *ec_sel_ptr++;
|
||||
ec_ix [ i ] = silk_SMULBB( silk_RSHIFT( entry, 1 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 );
|
||||
pred_Q8[ i ] = psNLSF_CB->pred_Q8[ i + ( entry & 1 ) * ( psNLSF_CB->order - 1 ) ];
|
||||
ec_ix [ i + 1 ] = silk_SMULBB( silk_RSHIFT( entry, 5 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 );
|
||||
pred_Q8[ i + 1 ] = psNLSF_CB->pred_Q8[ i + ( silk_RSHIFT( entry, 4 ) & 1 ) * ( psNLSF_CB->order - 1 ) + 1 ];
|
||||
}
|
||||
}
|
||||
|
453
node_modules/node-opus/deps/opus/silk/NSQ.c
generated
vendored
Normal file
453
node_modules/node-opus/deps/opus/silk/NSQ.c
generated
vendored
Normal file
@ -0,0 +1,453 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
static OPUS_INLINE void silk_nsq_scale_states(
|
||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
const opus_int32 x_Q3[], /* I input in Q3 */
|
||||
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||
opus_int subfr, /* I subframe number */
|
||||
const opus_int LTP_scale_Q14, /* I */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
|
||||
const opus_int signal_type /* I Signal type */
|
||||
);
|
||||
|
||||
#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
static OPUS_INLINE void silk_noise_shape_quantizer(
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
opus_int signalType, /* I Signal type */
|
||||
const opus_int32 x_sc_Q10[], /* I */
|
||||
opus_int8 pulses[], /* O */
|
||||
opus_int16 xq[], /* O */
|
||||
opus_int32 sLTP_Q15[], /* I/O LTP state */
|
||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||
opus_int lag, /* I Pitch lag */
|
||||
opus_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||
opus_int Tilt_Q14, /* I Spectral tilt */
|
||||
opus_int32 LF_shp_Q14, /* I */
|
||||
opus_int32 Gain_Q16, /* I */
|
||||
opus_int Lambda_Q10, /* I */
|
||||
opus_int offset_Q10, /* I */
|
||||
opus_int length, /* I Input length */
|
||||
opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
|
||||
opus_int predictLPCOrder /* I Prediction filter order */
|
||||
);
|
||||
#endif
|
||||
|
||||
void silk_NSQ_c
|
||||
(
|
||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||
const opus_int32 x_Q3[], /* I Prefiltered input signal */
|
||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||
const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
|
||||
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
|
||||
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
|
||||
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
|
||||
const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
|
||||
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
||||
)
|
||||
{
|
||||
opus_int k, lag, start_idx, LSF_interpolation_flag;
|
||||
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||
opus_int16 *pxq;
|
||||
VARDECL( opus_int32, sLTP_Q15 );
|
||||
VARDECL( opus_int16, sLTP );
|
||||
opus_int32 HarmShapeFIRPacked_Q14;
|
||||
opus_int offset_Q10;
|
||||
VARDECL( opus_int32, x_sc_Q10 );
|
||||
SAVE_STACK;
|
||||
|
||||
NSQ->rand_seed = psIndices->Seed;
|
||||
|
||||
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
||||
lag = NSQ->lagPrev;
|
||||
|
||||
silk_assert( NSQ->prev_gain_Q16 != 0 );
|
||||
|
||||
offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
|
||||
|
||||
if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
|
||||
LSF_interpolation_flag = 0;
|
||||
} else {
|
||||
LSF_interpolation_flag = 1;
|
||||
}
|
||||
|
||||
ALLOC( sLTP_Q15,
|
||||
psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
|
||||
ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
|
||||
ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
|
||||
/* Set up pointers to start of sub frame */
|
||||
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
||||
for( k = 0; k < psEncC->nb_subfr; k++ ) {
|
||||
A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
|
||||
B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
|
||||
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||
|
||||
/* Noise shape parameters */
|
||||
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||
|
||||
NSQ->rewhite_flag = 0;
|
||||
if( psIndices->signalType == TYPE_VOICED ) {
|
||||
/* Voiced */
|
||||
lag = pitchL[ k ];
|
||||
|
||||
/* Re-whitening */
|
||||
if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
|
||||
/* Rewhiten with new A coefs */
|
||||
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
|
||||
silk_assert( start_idx > 0 );
|
||||
|
||||
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
|
||||
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
NSQ->rewhite_flag = 1;
|
||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||
}
|
||||
}
|
||||
|
||||
silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
|
||||
|
||||
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
|
||||
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
|
||||
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );
|
||||
|
||||
x_Q3 += psEncC->subfr_length;
|
||||
pulses += psEncC->subfr_length;
|
||||
pxq += psEncC->subfr_length;
|
||||
}
|
||||
|
||||
/* Update lagPrev for next frame */
|
||||
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
|
||||
|
||||
/* Save quantized speech and noise shaping signals */
|
||||
/* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
|
||||
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
|
||||
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
/***********************************/
|
||||
/* silk_noise_shape_quantizer */
|
||||
/***********************************/
|
||||
|
||||
#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
static OPUS_INLINE
|
||||
#endif
|
||||
void silk_noise_shape_quantizer(
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
opus_int signalType, /* I Signal type */
|
||||
const opus_int32 x_sc_Q10[], /* I */
|
||||
opus_int8 pulses[], /* O */
|
||||
opus_int16 xq[], /* O */
|
||||
opus_int32 sLTP_Q15[], /* I/O LTP state */
|
||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
|
||||
opus_int lag, /* I Pitch lag */
|
||||
opus_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||
opus_int Tilt_Q14, /* I Spectral tilt */
|
||||
opus_int32 LF_shp_Q14, /* I */
|
||||
opus_int32 Gain_Q16, /* I */
|
||||
opus_int Lambda_Q10, /* I */
|
||||
opus_int offset_Q10, /* I */
|
||||
opus_int length, /* I Input length */
|
||||
opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
|
||||
opus_int predictLPCOrder /* I Prediction filter order */
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
|
||||
opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
|
||||
opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
|
||||
opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
|
||||
opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
|
||||
|
||||
shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||
Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
|
||||
|
||||
/* Set up short term AR state */
|
||||
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
|
||||
|
||||
for( i = 0; i < length; i++ ) {
|
||||
/* Generate dither */
|
||||
NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
|
||||
|
||||
/* Short-term prediction */
|
||||
silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LPC_pred_Q10 = silk_RSHIFT( predictLPCOrder, 1 );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||
if( predictLPCOrder == 16 ) {
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
|
||||
}
|
||||
|
||||
/* Long-term prediction */
|
||||
if( signalType == TYPE_VOICED ) {
|
||||
/* Unrolled loop */
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LTP_pred_Q13 = 2;
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||
pred_lag_ptr++;
|
||||
} else {
|
||||
LTP_pred_Q13 = 0;
|
||||
}
|
||||
|
||||
/* Noise shape feedback */
|
||||
silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||
tmp2 = psLPC_Q14[ 0 ];
|
||||
tmp1 = NSQ->sAR2_Q14[ 0 ];
|
||||
NSQ->sAR2_Q14[ 0 ] = tmp2;
|
||||
n_AR_Q12 = silk_RSHIFT( shapingLPCOrder, 1 );
|
||||
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ 0 ] );
|
||||
for( j = 2; j < shapingLPCOrder; j += 2 ) {
|
||||
tmp2 = NSQ->sAR2_Q14[ j - 1 ];
|
||||
NSQ->sAR2_Q14[ j - 1 ] = tmp1;
|
||||
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ j - 1 ] );
|
||||
tmp1 = NSQ->sAR2_Q14[ j + 0 ];
|
||||
NSQ->sAR2_Q14[ j + 0 ] = tmp2;
|
||||
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ j ] );
|
||||
}
|
||||
NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
|
||||
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
|
||||
|
||||
n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */
|
||||
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
|
||||
|
||||
n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
|
||||
n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
|
||||
|
||||
silk_assert( lag > 0 || signalType != TYPE_VOICED );
|
||||
|
||||
/* Combine prediction and noise shaping signals */
|
||||
tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
|
||||
tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
|
||||
if( lag > 0 ) {
|
||||
/* Symmetric, packed FIR coefficients */
|
||||
n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||
n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||
n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
|
||||
shp_lag_ptr++;
|
||||
|
||||
tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
|
||||
tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
|
||||
tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
|
||||
} else {
|
||||
tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
|
||||
}
|
||||
|
||||
r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
|
||||
|
||||
/* Flip sign depending on dither */
|
||||
if ( NSQ->rand_seed < 0 ) {
|
||||
r_Q10 = -r_Q10;
|
||||
}
|
||||
r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
|
||||
|
||||
/* Find two quantization level candidates and measure their rate-distortion */
|
||||
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
|
||||
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
|
||||
if( q1_Q0 > 0 ) {
|
||||
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
|
||||
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 );
|
||||
rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
|
||||
rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else if( q1_Q0 == 0 ) {
|
||||
q1_Q10 = offset_Q10;
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
|
||||
rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
|
||||
rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else if( q1_Q0 == -1 ) {
|
||||
q2_Q10 = offset_Q10;
|
||||
q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
|
||||
rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
|
||||
rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else { /* Q1_Q0 < -1 */
|
||||
q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
|
||||
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 );
|
||||
rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
|
||||
rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
|
||||
}
|
||||
rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
|
||||
rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
|
||||
rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
|
||||
rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
|
||||
|
||||
if( rd2_Q20 < rd1_Q20 ) {
|
||||
q1_Q10 = q2_Q10;
|
||||
}
|
||||
|
||||
pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
|
||||
|
||||
/* Excitation */
|
||||
exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
|
||||
if ( NSQ->rand_seed < 0 ) {
|
||||
exc_Q14 = -exc_Q14;
|
||||
}
|
||||
|
||||
/* Add predictions */
|
||||
LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
|
||||
xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
|
||||
|
||||
/* Scale XQ back to normal level before saving */
|
||||
xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
|
||||
|
||||
/* Update states */
|
||||
psLPC_Q14++;
|
||||
*psLPC_Q14 = xq_Q14;
|
||||
sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
|
||||
NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
|
||||
|
||||
NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
|
||||
sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
|
||||
NSQ->sLTP_shp_buf_idx++;
|
||||
NSQ->sLTP_buf_idx++;
|
||||
|
||||
/* Make dither dependent on quantized signal */
|
||||
NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
|
||||
}
|
||||
|
||||
/* Update LPC synth buffer */
|
||||
silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_nsq_scale_states(
|
||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
const opus_int32 x_Q3[], /* I input in Q3 */
|
||||
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
|
||||
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
|
||||
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||
opus_int subfr, /* I subframe number */
|
||||
const opus_int LTP_scale_Q14, /* I */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
|
||||
const opus_int signal_type /* I Signal type */
|
||||
)
|
||||
{
|
||||
opus_int i, lag;
|
||||
opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
|
||||
|
||||
lag = pitchL[ subfr ];
|
||||
inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
|
||||
silk_assert( inv_gain_Q31 != 0 );
|
||||
|
||||
/* Calculate gain adjustment factor */
|
||||
if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
|
||||
gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
|
||||
} else {
|
||||
gain_adj_Q16 = (opus_int32)1 << 16;
|
||||
}
|
||||
|
||||
/* Scale input */
|
||||
inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
|
||||
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
||||
x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
|
||||
}
|
||||
|
||||
/* Save inverse gain */
|
||||
NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
|
||||
|
||||
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||
if( NSQ->rewhite_flag ) {
|
||||
if( subfr == 0 ) {
|
||||
/* Do LTP downscaling */
|
||||
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
|
||||
}
|
||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||
silk_assert( i < MAX_FRAME_LENGTH );
|
||||
sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust for changing gain */
|
||||
if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
|
||||
/* Scale long-term shaping state */
|
||||
for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
|
||||
NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
|
||||
}
|
||||
|
||||
/* Scale long-term prediction state */
|
||||
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||
sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
|
||||
|
||||
/* Scale short-term prediction and shaping states */
|
||||
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
|
||||
NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
|
||||
}
|
||||
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
|
||||
NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
724
node_modules/node-opus/deps/opus/silk/NSQ_del_dec.c
generated
vendored
Normal file
724
node_modules/node-opus/deps/opus/silk/NSQ_del_dec.c
generated
vendored
Normal file
@ -0,0 +1,724 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
typedef struct {
|
||||
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
|
||||
opus_int32 RandState[ DECISION_DELAY ];
|
||||
opus_int32 Q_Q10[ DECISION_DELAY ];
|
||||
opus_int32 Xq_Q14[ DECISION_DELAY ];
|
||||
opus_int32 Pred_Q15[ DECISION_DELAY ];
|
||||
opus_int32 Shape_Q14[ DECISION_DELAY ];
|
||||
opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 LF_AR_Q14;
|
||||
opus_int32 Seed;
|
||||
opus_int32 SeedInit;
|
||||
opus_int32 RD_Q10;
|
||||
} NSQ_del_dec_struct;
|
||||
|
||||
typedef struct {
|
||||
opus_int32 Q_Q10;
|
||||
opus_int32 RD_Q10;
|
||||
opus_int32 xq_Q14;
|
||||
opus_int32 LF_AR_Q14;
|
||||
opus_int32 sLTP_shp_Q14;
|
||||
opus_int32 LPC_exc_Q14;
|
||||
} NSQ_sample_struct;
|
||||
|
||||
typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/NSQ_del_dec_mipsr1.h"
|
||||
#endif
|
||||
static OPUS_INLINE void silk_nsq_del_dec_scale_states(
|
||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||
const opus_int32 x_Q3[], /* I Input in Q3 */
|
||||
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||
opus_int subfr, /* I Subframe number */
|
||||
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
|
||||
const opus_int signal_type, /* I Signal type */
|
||||
const opus_int decisionDelay /* I Decision delay */
|
||||
);
|
||||
|
||||
/******************************************/
|
||||
/* Noise shape quantizer for one subframe */
|
||||
/******************************************/
|
||||
static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||
opus_int signalType, /* I Signal type */
|
||||
const opus_int32 x_Q10[], /* I */
|
||||
opus_int8 pulses[], /* O */
|
||||
opus_int16 xq[], /* O */
|
||||
opus_int32 sLTP_Q15[], /* I/O LTP filter state */
|
||||
opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
|
||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
|
||||
opus_int lag, /* I Pitch lag */
|
||||
opus_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||
opus_int Tilt_Q14, /* I Spectral tilt */
|
||||
opus_int32 LF_shp_Q14, /* I */
|
||||
opus_int32 Gain_Q16, /* I */
|
||||
opus_int Lambda_Q10, /* I */
|
||||
opus_int offset_Q10, /* I */
|
||||
opus_int length, /* I Input length */
|
||||
opus_int subfr, /* I Subframe number */
|
||||
opus_int shapingLPCOrder, /* I Shaping LPC filter order */
|
||||
opus_int predictLPCOrder, /* I Prediction filter order */
|
||||
opus_int warping_Q16, /* I */
|
||||
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
|
||||
opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||
opus_int decisionDelay /* I */
|
||||
);
|
||||
|
||||
void silk_NSQ_del_dec_c(
|
||||
const silk_encoder_state *psEncC, /* I/O Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
SideInfoIndices *psIndices, /* I/O Quantization Indices */
|
||||
const opus_int32 x_Q3[], /* I Prefiltered input signal */
|
||||
opus_int8 pulses[], /* O Quantized pulse signal */
|
||||
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
|
||||
const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
|
||||
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
|
||||
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
|
||||
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
|
||||
const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
|
||||
const opus_int LTP_scale_Q14 /* I LTP state scaling */
|
||||
)
|
||||
{
|
||||
opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
|
||||
opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
|
||||
const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
|
||||
opus_int16 *pxq;
|
||||
VARDECL( opus_int32, sLTP_Q15 );
|
||||
VARDECL( opus_int16, sLTP );
|
||||
opus_int32 HarmShapeFIRPacked_Q14;
|
||||
opus_int offset_Q10;
|
||||
opus_int32 RDmin_Q10, Gain_Q10;
|
||||
VARDECL( opus_int32, x_sc_Q10 );
|
||||
VARDECL( opus_int32, delayedGain_Q10 );
|
||||
VARDECL( NSQ_del_dec_struct, psDelDec );
|
||||
NSQ_del_dec_struct *psDD;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Set unvoiced lag to the previous one, overwrite later for voiced */
|
||||
lag = NSQ->lagPrev;
|
||||
|
||||
silk_assert( NSQ->prev_gain_Q16 != 0 );
|
||||
|
||||
/* Initialize delayed decision states */
|
||||
ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
|
||||
silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
|
||||
for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
|
||||
psDD = &psDelDec[ k ];
|
||||
psDD->Seed = ( k + psIndices->Seed ) & 3;
|
||||
psDD->SeedInit = psDD->Seed;
|
||||
psDD->RD_Q10 = 0;
|
||||
psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
|
||||
psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
|
||||
silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
|
||||
silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
|
||||
}
|
||||
|
||||
offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
|
||||
smpl_buf_idx = 0; /* index of oldest samples */
|
||||
|
||||
decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
|
||||
|
||||
/* For voiced frames limit the decision delay to lower than the pitch lag */
|
||||
if( psIndices->signalType == TYPE_VOICED ) {
|
||||
for( k = 0; k < psEncC->nb_subfr; k++ ) {
|
||||
decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
|
||||
}
|
||||
} else {
|
||||
if( lag > 0 ) {
|
||||
decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
|
||||
LSF_interpolation_flag = 0;
|
||||
} else {
|
||||
LSF_interpolation_flag = 1;
|
||||
}
|
||||
|
||||
ALLOC( sLTP_Q15,
|
||||
psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
|
||||
ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
|
||||
ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
|
||||
ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
|
||||
/* Set up pointers to start of sub frame */
|
||||
pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
|
||||
NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
|
||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||
subfr = 0;
|
||||
for( k = 0; k < psEncC->nb_subfr; k++ ) {
|
||||
A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
|
||||
B_Q14 = <PCoef_Q14[ k * LTP_ORDER ];
|
||||
AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||
|
||||
/* Noise shape parameters */
|
||||
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
|
||||
HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
|
||||
HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
|
||||
|
||||
NSQ->rewhite_flag = 0;
|
||||
if( psIndices->signalType == TYPE_VOICED ) {
|
||||
/* Voiced */
|
||||
lag = pitchL[ k ];
|
||||
|
||||
/* Re-whitening */
|
||||
if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
|
||||
if( k == 2 ) {
|
||||
/* RESET DELAYED DECISIONS */
|
||||
/* Find winner */
|
||||
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
|
||||
Winner_ind = 0;
|
||||
for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
|
||||
if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
|
||||
RDmin_Q10 = psDelDec[ i ].RD_Q10;
|
||||
Winner_ind = i;
|
||||
}
|
||||
}
|
||||
for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
|
||||
if( i != Winner_ind ) {
|
||||
psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
|
||||
silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy final part of signals from winner state to output and long-term filter states */
|
||||
psDD = &psDelDec[ Winner_ind ];
|
||||
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||
for( i = 0; i < decisionDelay; i++ ) {
|
||||
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
|
||||
NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
|
||||
}
|
||||
|
||||
subfr = 0;
|
||||
}
|
||||
|
||||
/* Rewhiten with new A coefs */
|
||||
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
|
||||
silk_assert( start_idx > 0 );
|
||||
|
||||
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
|
||||
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
|
||||
NSQ->rewhite_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
|
||||
psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
|
||||
|
||||
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
|
||||
delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
|
||||
Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
|
||||
psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
|
||||
|
||||
x_Q3 += psEncC->subfr_length;
|
||||
pulses += psEncC->subfr_length;
|
||||
pxq += psEncC->subfr_length;
|
||||
}
|
||||
|
||||
/* Find winner */
|
||||
RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
|
||||
Winner_ind = 0;
|
||||
for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
|
||||
if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
|
||||
RDmin_Q10 = psDelDec[ k ].RD_Q10;
|
||||
Winner_ind = k;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy final part of signals from winner state to output and long-term filter states */
|
||||
psDD = &psDelDec[ Winner_ind ];
|
||||
psIndices->Seed = psDD->SeedInit;
|
||||
last_smple_idx = smpl_buf_idx + decisionDelay;
|
||||
Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
|
||||
for( i = 0; i < decisionDelay; i++ ) {
|
||||
last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
|
||||
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
|
||||
NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
|
||||
}
|
||||
silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
|
||||
silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
|
||||
|
||||
/* Update states */
|
||||
NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
|
||||
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
|
||||
|
||||
/* Save quantized speech signal */
|
||||
/* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
|
||||
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
|
||||
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/* Noise shape quantizer for one subframe */
|
||||
/******************************************/
|
||||
#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec
|
||||
static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||
opus_int signalType, /* I Signal type */
|
||||
const opus_int32 x_Q10[], /* I */
|
||||
opus_int8 pulses[], /* O */
|
||||
opus_int16 xq[], /* O */
|
||||
opus_int32 sLTP_Q15[], /* I/O LTP filter state */
|
||||
opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
|
||||
const opus_int16 a_Q12[], /* I Short term prediction coefs */
|
||||
const opus_int16 b_Q14[], /* I Long term prediction coefs */
|
||||
const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
|
||||
opus_int lag, /* I Pitch lag */
|
||||
opus_int32 HarmShapeFIRPacked_Q14, /* I */
|
||||
opus_int Tilt_Q14, /* I Spectral tilt */
|
||||
opus_int32 LF_shp_Q14, /* I */
|
||||
opus_int32 Gain_Q16, /* I */
|
||||
opus_int Lambda_Q10, /* I */
|
||||
opus_int offset_Q10, /* I */
|
||||
opus_int length, /* I Input length */
|
||||
opus_int subfr, /* I Subframe number */
|
||||
opus_int shapingLPCOrder, /* I Shaping LPC filter order */
|
||||
opus_int predictLPCOrder, /* I Prediction filter order */
|
||||
opus_int warping_Q16, /* I */
|
||||
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
|
||||
opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
|
||||
opus_int decisionDelay /* I */
|
||||
)
|
||||
{
|
||||
opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
|
||||
opus_int32 Winner_rand_state;
|
||||
opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
|
||||
opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
|
||||
opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
|
||||
opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
|
||||
opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
|
||||
VARDECL( NSQ_sample_pair, psSampleState );
|
||||
NSQ_del_dec_struct *psDD;
|
||||
NSQ_sample_struct *psSS;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( nStatesDelayedDecision > 0 );
|
||||
ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
|
||||
|
||||
shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
|
||||
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||
Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
|
||||
|
||||
for( i = 0; i < length; i++ ) {
|
||||
/* Perform common calculations used in all states */
|
||||
|
||||
/* Long-term prediction */
|
||||
if( signalType == TYPE_VOICED ) {
|
||||
/* Unrolled loop */
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LTP_pred_Q14 = 2;
|
||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
|
||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
|
||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
|
||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
|
||||
LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
|
||||
LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
|
||||
pred_lag_ptr++;
|
||||
} else {
|
||||
LTP_pred_Q14 = 0;
|
||||
}
|
||||
|
||||
/* Long-term shaping */
|
||||
if( lag > 0 ) {
|
||||
/* Symmetric, packed FIR coefficients */
|
||||
n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
|
||||
n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
|
||||
n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
|
||||
shp_lag_ptr++;
|
||||
} else {
|
||||
n_LTP_Q14 = 0;
|
||||
}
|
||||
|
||||
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||
/* Delayed decision state */
|
||||
psDD = &psDelDec[ k ];
|
||||
|
||||
/* Sample state */
|
||||
psSS = psSampleState[ k ];
|
||||
|
||||
/* Generate dither */
|
||||
psDD->Seed = silk_RAND( psDD->Seed );
|
||||
|
||||
/* Pointer used in short term prediction and shaping */
|
||||
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
|
||||
/* Short-term prediction */
|
||||
silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
|
||||
if( predictLPCOrder == 16 ) {
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
|
||||
LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
|
||||
}
|
||||
LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
|
||||
|
||||
/* Noise shape feedback */
|
||||
silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
|
||||
/* Output of lowpass section */
|
||||
tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
|
||||
psDD->sAR2_Q14[ 0 ] = tmp2;
|
||||
n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
|
||||
n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
|
||||
/* Loop over allpass sections */
|
||||
for( j = 2; j < shapingLPCOrder; j += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
|
||||
psDD->sAR2_Q14[ j - 1 ] = tmp1;
|
||||
n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
|
||||
psDD->sAR2_Q14[ j + 0 ] = tmp2;
|
||||
n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
|
||||
}
|
||||
psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
|
||||
n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
|
||||
|
||||
n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
|
||||
n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
|
||||
n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
|
||||
|
||||
n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
|
||||
n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
|
||||
n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
|
||||
|
||||
/* Input minus prediction plus noise feedback */
|
||||
/* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
|
||||
tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
|
||||
tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
|
||||
tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
|
||||
tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
|
||||
|
||||
r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
|
||||
|
||||
/* Flip sign depending on dither */
|
||||
if ( psDD->Seed < 0 ) {
|
||||
r_Q10 = -r_Q10;
|
||||
}
|
||||
r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
|
||||
|
||||
/* Find two quantization level candidates and measure their rate-distortion */
|
||||
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
|
||||
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
|
||||
if( q1_Q0 > 0 ) {
|
||||
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
|
||||
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 );
|
||||
rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
|
||||
rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else if( q1_Q0 == 0 ) {
|
||||
q1_Q10 = offset_Q10;
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
|
||||
rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
|
||||
rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else if( q1_Q0 == -1 ) {
|
||||
q2_Q10 = offset_Q10;
|
||||
q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
|
||||
rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
|
||||
rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
|
||||
} else { /* q1_Q0 < -1 */
|
||||
q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
|
||||
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
|
||||
q2_Q10 = silk_ADD32( q1_Q10, 1024 );
|
||||
rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
|
||||
rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
|
||||
}
|
||||
rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
|
||||
rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
|
||||
rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
|
||||
rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
|
||||
|
||||
if( rd1_Q10 < rd2_Q10 ) {
|
||||
psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
|
||||
psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
|
||||
psSS[ 0 ].Q_Q10 = q1_Q10;
|
||||
psSS[ 1 ].Q_Q10 = q2_Q10;
|
||||
} else {
|
||||
psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
|
||||
psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
|
||||
psSS[ 0 ].Q_Q10 = q2_Q10;
|
||||
psSS[ 1 ].Q_Q10 = q1_Q10;
|
||||
}
|
||||
|
||||
/* Update states for best quantization */
|
||||
|
||||
/* Quantized excitation */
|
||||
exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
|
||||
if ( psDD->Seed < 0 ) {
|
||||
exc_Q14 = -exc_Q14;
|
||||
}
|
||||
|
||||
/* Add predictions */
|
||||
LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
|
||||
xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
|
||||
|
||||
/* Update states */
|
||||
sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
|
||||
psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
|
||||
psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
|
||||
psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
|
||||
psSS[ 0 ].xq_Q14 = xq_Q14;
|
||||
|
||||
/* Update states for second best quantization */
|
||||
|
||||
/* Quantized excitation */
|
||||
exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
|
||||
if ( psDD->Seed < 0 ) {
|
||||
exc_Q14 = -exc_Q14;
|
||||
}
|
||||
|
||||
|
||||
/* Add predictions */
|
||||
LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
|
||||
xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
|
||||
|
||||
/* Update states */
|
||||
sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
|
||||
psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
|
||||
psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
|
||||
psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
|
||||
psSS[ 1 ].xq_Q14 = xq_Q14;
|
||||
}
|
||||
|
||||
*smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
|
||||
last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
|
||||
|
||||
/* Find winner */
|
||||
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
|
||||
Winner_ind = 0;
|
||||
for( k = 1; k < nStatesDelayedDecision; k++ ) {
|
||||
if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
|
||||
RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
|
||||
Winner_ind = k;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increase RD values of expired states */
|
||||
Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
|
||||
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||
if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
|
||||
psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
|
||||
psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
|
||||
silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Find worst in first set and best in second set */
|
||||
RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
|
||||
RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
|
||||
RDmax_ind = 0;
|
||||
RDmin_ind = 0;
|
||||
for( k = 1; k < nStatesDelayedDecision; k++ ) {
|
||||
/* find worst in first set */
|
||||
if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
|
||||
RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
|
||||
RDmax_ind = k;
|
||||
}
|
||||
/* find best in second set */
|
||||
if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
|
||||
RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
|
||||
RDmin_ind = k;
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace a state if best from second set outperforms worst in first set */
|
||||
if( RDmin_Q10 < RDmax_Q10 ) {
|
||||
silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
|
||||
( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
|
||||
silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
|
||||
}
|
||||
|
||||
/* Write samples from winner to output and long-term filter states */
|
||||
psDD = &psDelDec[ Winner_ind ];
|
||||
if( subfr > 0 || i >= decisionDelay ) {
|
||||
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
|
||||
xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
|
||||
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
|
||||
NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
|
||||
sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
|
||||
}
|
||||
NSQ->sLTP_shp_buf_idx++;
|
||||
NSQ->sLTP_buf_idx++;
|
||||
|
||||
/* Update states */
|
||||
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||
psDD = &psDelDec[ k ];
|
||||
psSS = &psSampleState[ k ][ 0 ];
|
||||
psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
|
||||
psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
|
||||
psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
|
||||
psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
|
||||
psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
|
||||
psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
|
||||
psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
|
||||
psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
|
||||
psDD->RD_Q10 = psSS->RD_Q10;
|
||||
}
|
||||
delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
|
||||
}
|
||||
/* Update LPC states */
|
||||
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||
psDD = &psDelDec[ k ];
|
||||
silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */
|
||||
|
||||
static OPUS_INLINE void silk_nsq_del_dec_scale_states(
|
||||
const silk_encoder_state *psEncC, /* I Encoder State */
|
||||
silk_nsq_state *NSQ, /* I/O NSQ state */
|
||||
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
|
||||
const opus_int32 x_Q3[], /* I Input in Q3 */
|
||||
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
|
||||
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
|
||||
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
|
||||
opus_int subfr, /* I Subframe number */
|
||||
opus_int nStatesDelayedDecision, /* I Number of del dec states */
|
||||
const opus_int LTP_scale_Q14, /* I LTP state scaling */
|
||||
const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
|
||||
const opus_int signal_type, /* I Signal type */
|
||||
const opus_int decisionDelay /* I Decision delay */
|
||||
)
|
||||
{
|
||||
opus_int i, k, lag;
|
||||
opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
|
||||
NSQ_del_dec_struct *psDD;
|
||||
|
||||
lag = pitchL[ subfr ];
|
||||
inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
|
||||
silk_assert( inv_gain_Q31 != 0 );
|
||||
|
||||
/* Calculate gain adjustment factor */
|
||||
if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
|
||||
gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
|
||||
} else {
|
||||
gain_adj_Q16 = (opus_int32)1 << 16;
|
||||
}
|
||||
|
||||
/* Scale input */
|
||||
inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
|
||||
for( i = 0; i < psEncC->subfr_length; i++ ) {
|
||||
x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
|
||||
}
|
||||
|
||||
/* Save inverse gain */
|
||||
NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
|
||||
|
||||
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
|
||||
if( NSQ->rewhite_flag ) {
|
||||
if( subfr == 0 ) {
|
||||
/* Do LTP downscaling */
|
||||
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
|
||||
}
|
||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
|
||||
silk_assert( i < MAX_FRAME_LENGTH );
|
||||
sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust for changing gain */
|
||||
if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
|
||||
/* Scale long-term shaping state */
|
||||
for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
|
||||
NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
|
||||
}
|
||||
|
||||
/* Scale long-term prediction state */
|
||||
if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
|
||||
for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
|
||||
sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
for( k = 0; k < nStatesDelayedDecision; k++ ) {
|
||||
psDD = &psDelDec[ k ];
|
||||
|
||||
/* Scale scalar states */
|
||||
psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
|
||||
|
||||
/* Scale short-term prediction and shaping states */
|
||||
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
|
||||
psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
|
||||
}
|
||||
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
|
||||
psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
|
||||
}
|
||||
for( i = 0; i < DECISION_DELAY; i++ ) {
|
||||
psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
|
||||
psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
445
node_modules/node-opus/deps/opus/silk/PLC.c
generated
vendored
Normal file
445
node_modules/node-opus/deps/opus/silk/PLC.c
generated
vendored
Normal file
@ -0,0 +1,445 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "PLC.h"
|
||||
|
||||
#define NB_ATT 2
|
||||
static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */
|
||||
static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */
|
||||
static const opus_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */
|
||||
|
||||
static OPUS_INLINE void silk_PLC_update(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl /* I/O Decoder control */
|
||||
);
|
||||
|
||||
static OPUS_INLINE void silk_PLC_conceal(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int16 frame[], /* O LPC residual signal */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
|
||||
void silk_PLC_Reset(
|
||||
silk_decoder_state *psDec /* I/O Decoder state */
|
||||
)
|
||||
{
|
||||
psDec->sPLC.pitchL_Q8 = silk_LSHIFT( psDec->frame_length, 8 - 1 );
|
||||
psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 );
|
||||
psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 );
|
||||
psDec->sPLC.subfr_length = 20;
|
||||
psDec->sPLC.nb_subfr = 2;
|
||||
}
|
||||
|
||||
void silk_PLC(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int16 frame[], /* I/O signal */
|
||||
opus_int lost, /* I Loss flag */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
/* PLC control function */
|
||||
if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) {
|
||||
silk_PLC_Reset( psDec );
|
||||
psDec->sPLC.fs_kHz = psDec->fs_kHz;
|
||||
}
|
||||
|
||||
if( lost ) {
|
||||
/****************************/
|
||||
/* Generate Signal */
|
||||
/****************************/
|
||||
silk_PLC_conceal( psDec, psDecCtrl, frame, arch );
|
||||
|
||||
psDec->lossCnt++;
|
||||
} else {
|
||||
/****************************/
|
||||
/* Update state */
|
||||
/****************************/
|
||||
silk_PLC_update( psDec, psDecCtrl );
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************/
|
||||
/* Update state of PLC */
|
||||
/**************************************************/
|
||||
static OPUS_INLINE void silk_PLC_update(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl /* I/O Decoder control */
|
||||
)
|
||||
{
|
||||
opus_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14;
|
||||
opus_int i, j;
|
||||
silk_PLC_struct *psPLC;
|
||||
|
||||
psPLC = &psDec->sPLC;
|
||||
|
||||
/* Update parameters used in case of packet loss */
|
||||
psDec->prevSignalType = psDec->indices.signalType;
|
||||
LTP_Gain_Q14 = 0;
|
||||
if( psDec->indices.signalType == TYPE_VOICED ) {
|
||||
/* Find the parameters for the last subframe which contains a pitch pulse */
|
||||
for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; j++ ) {
|
||||
if( j == psDec->nb_subfr ) {
|
||||
break;
|
||||
}
|
||||
temp_LTP_Gain_Q14 = 0;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( psDec->nb_subfr - 1 - j ) * LTP_ORDER + i ];
|
||||
}
|
||||
if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) {
|
||||
LTP_Gain_Q14 = temp_LTP_Gain_Q14;
|
||||
silk_memcpy( psPLC->LTPCoef_Q14,
|
||||
&psDecCtrl->LTPCoef_Q14[ silk_SMULBB( psDec->nb_subfr - 1 - j, LTP_ORDER ) ],
|
||||
LTP_ORDER * sizeof( opus_int16 ) );
|
||||
|
||||
psPLC->pitchL_Q8 = silk_LSHIFT( psDecCtrl->pitchL[ psDec->nb_subfr - 1 - j ], 8 );
|
||||
}
|
||||
}
|
||||
|
||||
silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) );
|
||||
psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14;
|
||||
|
||||
/* Limit LT coefs */
|
||||
if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) {
|
||||
opus_int scale_Q10;
|
||||
opus_int32 tmp;
|
||||
|
||||
tmp = silk_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 );
|
||||
scale_Q10 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) );
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 );
|
||||
}
|
||||
} else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) {
|
||||
opus_int scale_Q14;
|
||||
opus_int32 tmp;
|
||||
|
||||
tmp = silk_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 );
|
||||
scale_Q14 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) );
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
psPLC->pitchL_Q8 = silk_LSHIFT( silk_SMULBB( psDec->fs_kHz, 18 ), 8 );
|
||||
silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ));
|
||||
}
|
||||
|
||||
/* Save LPC coeficients */
|
||||
silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
|
||||
psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14;
|
||||
|
||||
/* Save last two gains */
|
||||
silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) );
|
||||
|
||||
psPLC->subfr_length = psDec->subfr_length;
|
||||
psPLC->nb_subfr = psDec->nb_subfr;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, opus_int32 *energy2, opus_int *shift2,
|
||||
const opus_int32 *exc_Q14, const opus_int32 *prevGain_Q10, int subfr_length, int nb_subfr)
|
||||
{
|
||||
int i, k;
|
||||
VARDECL( opus_int16, exc_buf );
|
||||
opus_int16 *exc_buf_ptr;
|
||||
SAVE_STACK;
|
||||
ALLOC( exc_buf, 2*subfr_length, opus_int16 );
|
||||
/* Find random noise component */
|
||||
/* Scale previous excitation signal */
|
||||
exc_buf_ptr = exc_buf;
|
||||
for( k = 0; k < 2; k++ ) {
|
||||
for( i = 0; i < subfr_length; i++ ) {
|
||||
exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT(
|
||||
silk_SMULWW( exc_Q14[ i + ( k + nb_subfr - 2 ) * subfr_length ], prevGain_Q10[ k ] ), 8 ) );
|
||||
}
|
||||
exc_buf_ptr += subfr_length;
|
||||
}
|
||||
/* Find the subframe with lowest energy of the last two and use that as random noise generator */
|
||||
silk_sum_sqr_shift( energy1, shift1, exc_buf, subfr_length );
|
||||
silk_sum_sqr_shift( energy2, shift2, &exc_buf[ subfr_length ], subfr_length );
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_PLC_conceal(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int16 frame[], /* O LPC residual signal */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, j, k;
|
||||
opus_int lag, idx, sLTP_buf_idx, shift1, shift2;
|
||||
opus_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15, inv_gain_Q30;
|
||||
opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr;
|
||||
opus_int32 LPC_pred_Q10, LTP_pred_Q12;
|
||||
opus_int16 rand_scale_Q14;
|
||||
opus_int16 *B_Q14;
|
||||
opus_int32 *sLPC_Q14_ptr;
|
||||
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
||||
#ifdef SMALL_FOOTPRINT
|
||||
opus_int16 *sLTP;
|
||||
#else
|
||||
VARDECL( opus_int16, sLTP );
|
||||
#endif
|
||||
VARDECL( opus_int32, sLTP_Q14 );
|
||||
silk_PLC_struct *psPLC = &psDec->sPLC;
|
||||
opus_int32 prevGain_Q10[2];
|
||||
SAVE_STACK;
|
||||
|
||||
ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
|
||||
#ifdef SMALL_FOOTPRINT
|
||||
/* Ugly hack that breaks aliasing rules to save stack: put sLTP at the very end of sLTP_Q14. */
|
||||
sLTP = ((opus_int16*)&sLTP_Q14[psDec->ltp_mem_length + psDec->frame_length])-psDec->ltp_mem_length;
|
||||
#else
|
||||
ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
|
||||
#endif
|
||||
|
||||
prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6);
|
||||
prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6);
|
||||
|
||||
if( psDec->first_frame_after_reset ) {
|
||||
silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) );
|
||||
}
|
||||
|
||||
silk_PLC_energy(&energy1, &shift1, &energy2, &shift2, psDec->exc_Q14, prevGain_Q10, psDec->subfr_length, psDec->nb_subfr);
|
||||
|
||||
if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) {
|
||||
/* First sub-frame has lowest energy */
|
||||
rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ];
|
||||
} else {
|
||||
/* Second sub-frame has lowest energy */
|
||||
rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ];
|
||||
}
|
||||
|
||||
/* Set up Gain to random noise component */
|
||||
B_Q14 = psPLC->LTPCoef_Q14;
|
||||
rand_scale_Q14 = psPLC->randScale_Q14;
|
||||
|
||||
/* Set up attenuation gains */
|
||||
harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||
if( psDec->prevSignalType == TYPE_VOICED ) {
|
||||
rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||
} else {
|
||||
rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ];
|
||||
}
|
||||
|
||||
/* LPC concealment. Apply BWE to previous LPC */
|
||||
silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, SILK_FIX_CONST( BWE_COEF, 16 ) );
|
||||
|
||||
/* Preload LPC coeficients to array on stack. Gives small performance gain */
|
||||
silk_memcpy( A_Q12, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( opus_int16 ) );
|
||||
|
||||
/* First Lost frame */
|
||||
if( psDec->lossCnt == 0 ) {
|
||||
rand_scale_Q14 = 1 << 14;
|
||||
|
||||
/* Reduce random noise Gain for voiced frames */
|
||||
if( psDec->prevSignalType == TYPE_VOICED ) {
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
rand_scale_Q14 -= B_Q14[ i ];
|
||||
}
|
||||
rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
|
||||
rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
|
||||
} else {
|
||||
/* Reduce random noise for unvoiced frames with high LPC gain */
|
||||
opus_int32 invGain_Q30, down_scale_Q30;
|
||||
|
||||
invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order );
|
||||
|
||||
down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
|
||||
down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
|
||||
down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );
|
||||
|
||||
rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );
|
||||
}
|
||||
}
|
||||
|
||||
rand_seed = psPLC->rand_seed;
|
||||
lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
|
||||
sLTP_buf_idx = psDec->ltp_mem_length;
|
||||
|
||||
/* Rewhiten LTP state */
|
||||
idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
|
||||
silk_assert( idx > 0 );
|
||||
silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );
|
||||
/* Scale LTP state */
|
||||
inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );
|
||||
inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 );
|
||||
for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) {
|
||||
sLTP_Q14[ i ] = silk_SMULWB( inv_gain_Q30, sLTP[ i ] );
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* LTP synthesis filtering */
|
||||
/***************************/
|
||||
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
||||
/* Set up pointer */
|
||||
pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||
/* Unrolled loop */
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LTP_pred_Q12 = 2;
|
||||
LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
||||
LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
||||
LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
||||
LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
||||
LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
||||
pred_lag_ptr++;
|
||||
|
||||
/* Generate LPC excitation */
|
||||
rand_seed = silk_RAND( rand_seed );
|
||||
idx = silk_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;
|
||||
sLTP_Q14[ sLTP_buf_idx ] = silk_LSHIFT32( silk_SMLAWB( LTP_pred_Q12, rand_ptr[ idx ], rand_scale_Q14 ), 2 );
|
||||
sLTP_buf_idx++;
|
||||
}
|
||||
|
||||
/* Gradually reduce LTP gain */
|
||||
for( j = 0; j < LTP_ORDER; j++ ) {
|
||||
B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
|
||||
}
|
||||
/* Gradually reduce excitation gain */
|
||||
rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
|
||||
|
||||
/* Slowly increase pitch lag */
|
||||
psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
|
||||
psPLC->pitchL_Q8 = silk_min_32( psPLC->pitchL_Q8, silk_LSHIFT( silk_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );
|
||||
lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* LPC synthesis filtering */
|
||||
/***************************/
|
||||
sLPC_Q14_ptr = &sLTP_Q14[ psDec->ltp_mem_length - MAX_LPC_ORDER ];
|
||||
|
||||
/* Copy LPC state */
|
||||
silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
|
||||
silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
|
||||
for( i = 0; i < psDec->frame_length; i++ ) {
|
||||
/* partly unrolled */
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
|
||||
for( j = 10; j < psDec->LPC_order; j++ ) {
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] );
|
||||
}
|
||||
|
||||
/* Add prediction to LPC excitation */
|
||||
sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
|
||||
|
||||
/* Scale with Gain */
|
||||
frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) );
|
||||
}
|
||||
|
||||
/* Save LPC state */
|
||||
silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
|
||||
/**************************************/
|
||||
/* Update states */
|
||||
/**************************************/
|
||||
psPLC->rand_seed = rand_seed;
|
||||
psPLC->randScale_Q14 = rand_scale_Q14;
|
||||
for( i = 0; i < MAX_NB_SUBFR; i++ ) {
|
||||
psDecCtrl->pitchL[ i ] = lag;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
/* Glues concealed frames with new good received frames */
|
||||
void silk_PLC_glue_frames(
|
||||
silk_decoder_state *psDec, /* I/O decoder state */
|
||||
opus_int16 frame[], /* I/O signal */
|
||||
opus_int length /* I length of signal */
|
||||
)
|
||||
{
|
||||
opus_int i, energy_shift;
|
||||
opus_int32 energy;
|
||||
silk_PLC_struct *psPLC;
|
||||
psPLC = &psDec->sPLC;
|
||||
|
||||
if( psDec->lossCnt ) {
|
||||
/* Calculate energy in concealed residual */
|
||||
silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, frame, length );
|
||||
|
||||
psPLC->last_frame_lost = 1;
|
||||
} else {
|
||||
if( psDec->sPLC.last_frame_lost ) {
|
||||
/* Calculate residual in decoded signal if last frame was lost */
|
||||
silk_sum_sqr_shift( &energy, &energy_shift, frame, length );
|
||||
|
||||
/* Normalize energies */
|
||||
if( energy_shift > psPLC->conc_energy_shift ) {
|
||||
psPLC->conc_energy = silk_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift );
|
||||
} else if( energy_shift < psPLC->conc_energy_shift ) {
|
||||
energy = silk_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift );
|
||||
}
|
||||
|
||||
/* Fade in the energy difference */
|
||||
if( energy > psPLC->conc_energy ) {
|
||||
opus_int32 frac_Q24, LZ;
|
||||
opus_int32 gain_Q16, slope_Q16;
|
||||
|
||||
LZ = silk_CLZ32( psPLC->conc_energy );
|
||||
LZ = LZ - 1;
|
||||
psPLC->conc_energy = silk_LSHIFT( psPLC->conc_energy, LZ );
|
||||
energy = silk_RSHIFT( energy, silk_max_32( 24 - LZ, 0 ) );
|
||||
|
||||
frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) );
|
||||
|
||||
gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 );
|
||||
slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length );
|
||||
/* Make slope 4x steeper to avoid missing onsets after DTX */
|
||||
slope_Q16 = silk_LSHIFT( slope_Q16, 2 );
|
||||
|
||||
for( i = 0; i < length; i++ ) {
|
||||
frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] );
|
||||
gain_Q16 += slope_Q16;
|
||||
if( gain_Q16 > (opus_int32)1 << 16 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
psPLC->last_frame_lost = 0;
|
||||
}
|
||||
}
|
62
node_modules/node-opus/deps/opus/silk/PLC.h
generated
vendored
Normal file
62
node_modules/node-opus/deps/opus/silk/PLC.h
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_PLC_H
|
||||
#define SILK_PLC_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#define BWE_COEF 0.99
|
||||
#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */
|
||||
#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */
|
||||
#define MAX_PITCH_LAG_MS 18
|
||||
#define RAND_BUF_SIZE 128
|
||||
#define RAND_BUF_MASK ( RAND_BUF_SIZE - 1 )
|
||||
#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */
|
||||
#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */
|
||||
#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */
|
||||
|
||||
void silk_PLC_Reset(
|
||||
silk_decoder_state *psDec /* I/O Decoder state */
|
||||
);
|
||||
|
||||
void silk_PLC(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int16 frame[], /* I/O signal */
|
||||
opus_int lost, /* I Loss flag */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_PLC_glue_frames(
|
||||
silk_decoder_state *psDec, /* I/O decoder state */
|
||||
opus_int16 frame[], /* I/O signal */
|
||||
opus_int length /* I length of signal */
|
||||
);
|
||||
|
||||
#endif
|
||||
|
615
node_modules/node-opus/deps/opus/silk/SigProc_FIX.h
generated
vendored
Normal file
615
node_modules/node-opus/deps/opus/silk/SigProc_FIX.h
generated
vendored
Normal file
@ -0,0 +1,615 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_SIGPROC_FIX_H
|
||||
#define SILK_SIGPROC_FIX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */
|
||||
|
||||
#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */
|
||||
|
||||
#include <string.h> /* for memset(), memcpy(), memmove() */
|
||||
#include "typedef.h"
|
||||
#include "resampler_structs.h"
|
||||
#include "macros.h"
|
||||
#include "cpu_support.h"
|
||||
|
||||
#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
#include "x86/SigProc_FIX_sse.h"
|
||||
#endif
|
||||
|
||||
/********************************************************************/
|
||||
/* SIGNAL PROCESSING FUNCTIONS */
|
||||
/********************************************************************/
|
||||
|
||||
/*!
|
||||
* Initialize/reset the resampler state for a given pair of input/output sampling rates
|
||||
*/
|
||||
opus_int silk_resampler_init(
|
||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||
opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */
|
||||
opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */
|
||||
opus_int forEnc /* I If 1: encoder; if 0: decoder */
|
||||
);
|
||||
|
||||
/*!
|
||||
* Resampler: convert from one sampling rate to another
|
||||
*/
|
||||
opus_int silk_resampler(
|
||||
silk_resampler_state_struct *S, /* I/O Resampler state */
|
||||
opus_int16 out[], /* O Output signal */
|
||||
const opus_int16 in[], /* I Input signal */
|
||||
opus_int32 inLen /* I Number of input samples */
|
||||
);
|
||||
|
||||
/*!
|
||||
* Downsample 2x, mediocre quality
|
||||
*/
|
||||
void silk_resampler_down2(
|
||||
opus_int32 *S, /* I/O State vector [ 2 ] */
|
||||
opus_int16 *out, /* O Output signal [ len ] */
|
||||
const opus_int16 *in, /* I Input signal [ floor(len/2) ] */
|
||||
opus_int32 inLen /* I Number of input samples */
|
||||
);
|
||||
|
||||
/*!
|
||||
* Downsample by a factor 2/3, low quality
|
||||
*/
|
||||
void silk_resampler_down2_3(
|
||||
opus_int32 *S, /* I/O State vector [ 6 ] */
|
||||
opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */
|
||||
const opus_int16 *in, /* I Input signal [ inLen ] */
|
||||
opus_int32 inLen /* I Number of input samples */
|
||||
);
|
||||
|
||||
/*!
|
||||
* second order ARMA filter;
|
||||
* slower than biquad() but uses more precise coefficients
|
||||
* can handle (slowly) varying coefficients
|
||||
*/
|
||||
void silk_biquad_alt(
|
||||
const opus_int16 *in, /* I input signal */
|
||||
const opus_int32 *B_Q28, /* I MA coefficients [3] */
|
||||
const opus_int32 *A_Q28, /* I AR coefficients [2] */
|
||||
opus_int32 *S, /* I/O State vector [2] */
|
||||
opus_int16 *out, /* O output signal */
|
||||
const opus_int32 len, /* I signal length (must be even) */
|
||||
opus_int stride /* I Operate on interleaved signal if > 1 */
|
||||
);
|
||||
|
||||
/* Variable order MA prediction error filter. */
|
||||
void silk_LPC_analysis_filter(
|
||||
opus_int16 *out, /* O Output signal */
|
||||
const opus_int16 *in, /* I Input signal */
|
||||
const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
|
||||
const opus_int32 len, /* I Signal length */
|
||||
const opus_int32 d, /* I Filter order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Chirp (bandwidth expand) LP AR filter */
|
||||
void silk_bwexpander(
|
||||
opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I Length of ar */
|
||||
opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
|
||||
);
|
||||
|
||||
/* Chirp (bandwidth expand) LP AR filter */
|
||||
void silk_bwexpander_32(
|
||||
opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I Length of ar */
|
||||
opus_int32 chirp_Q16 /* I Chirp factor in Q16 */
|
||||
);
|
||||
|
||||
/* Compute inverse of LPC prediction gain, and */
|
||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||
opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
|
||||
const opus_int order /* I Prediction order */
|
||||
);
|
||||
|
||||
/* For input in Q24 domain */
|
||||
opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
|
||||
const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
|
||||
const opus_int order /* I Prediction order */
|
||||
);
|
||||
|
||||
/* Split signal in two decimated bands using first-order allpass filters */
|
||||
void silk_ana_filt_bank_1(
|
||||
const opus_int16 *in, /* I Input signal [N] */
|
||||
opus_int32 *S, /* I/O State vector [2] */
|
||||
opus_int16 *outL, /* O Low band [N/2] */
|
||||
opus_int16 *outH, /* O High band [N/2] */
|
||||
const opus_int32 N /* I Number of input samples */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/* SCALAR FUNCTIONS */
|
||||
/********************************************************************/
|
||||
|
||||
/* Approximation of 128 * log2() (exact inverse of approx 2^() below) */
|
||||
/* Convert input to a log scale */
|
||||
opus_int32 silk_lin2log(
|
||||
const opus_int32 inLin /* I input in linear scale */
|
||||
);
|
||||
|
||||
/* Approximation of a sigmoid function */
|
||||
opus_int silk_sigm_Q15(
|
||||
opus_int in_Q5 /* I */
|
||||
);
|
||||
|
||||
/* Approximation of 2^() (exact inverse of approx log2() above) */
|
||||
/* Convert input to a linear scale */
|
||||
opus_int32 silk_log2lin(
|
||||
const opus_int32 inLog_Q7 /* I input on log scale */
|
||||
);
|
||||
|
||||
/* Compute number of bits to right shift the sum of squares of a vector */
|
||||
/* of int16s to make it fit in an int32 */
|
||||
void silk_sum_sqr_shift(
|
||||
opus_int32 *energy, /* O Energy of x, after shifting to the right */
|
||||
opus_int *shift, /* O Number of bits right shift applied to energy */
|
||||
const opus_int16 *x, /* I Input vector */
|
||||
opus_int len /* I Length of input vector */
|
||||
);
|
||||
|
||||
/* Calculates the reflection coefficients from the correlation sequence */
|
||||
/* Faster than schur64(), but much less accurate. */
|
||||
/* uses SMLAWB(), requiring armv5E and higher. */
|
||||
opus_int32 silk_schur( /* O Returns residual energy */
|
||||
opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */
|
||||
const opus_int32 *c, /* I correlations [order+1] */
|
||||
const opus_int32 order /* I prediction order */
|
||||
);
|
||||
|
||||
/* Calculates the reflection coefficients from the correlation sequence */
|
||||
/* Slower than schur(), but more accurate. */
|
||||
/* Uses SMULL(), available on armv4 */
|
||||
opus_int32 silk_schur64( /* O returns residual energy */
|
||||
opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */
|
||||
const opus_int32 c[], /* I Correlations [order+1] */
|
||||
opus_int32 order /* I Prediction order */
|
||||
);
|
||||
|
||||
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||
void silk_k2a(
|
||||
opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
|
||||
const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */
|
||||
const opus_int32 order /* I Prediction order */
|
||||
);
|
||||
|
||||
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||
void silk_k2a_Q16(
|
||||
opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
|
||||
const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */
|
||||
const opus_int32 order /* I Prediction order */
|
||||
);
|
||||
|
||||
/* Apply sine window to signal vector. */
|
||||
/* Window types: */
|
||||
/* 1 -> sine window from 0 to pi/2 */
|
||||
/* 2 -> sine window from pi/2 to pi */
|
||||
/* every other sample of window is linearly interpolated, for speed */
|
||||
void silk_apply_sine_window(
|
||||
opus_int16 px_win[], /* O Pointer to windowed signal */
|
||||
const opus_int16 px[], /* I Pointer to input signal */
|
||||
const opus_int win_type, /* I Selects a window type */
|
||||
const opus_int length /* I Window length, multiple of 4 */
|
||||
);
|
||||
|
||||
/* Compute autocorrelation */
|
||||
void silk_autocorr(
|
||||
opus_int32 *results, /* O Result (length correlationCount) */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *inputData, /* I Input data to correlate */
|
||||
const opus_int inputDataSize, /* I Length of input */
|
||||
const opus_int correlationCount, /* I Number of correlation taps to compute */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_decode_pitch(
|
||||
opus_int16 lagIndex, /* I */
|
||||
opus_int8 contourIndex, /* O */
|
||||
opus_int pitch_lags[], /* O 4 pitch values */
|
||||
const opus_int Fs_kHz, /* I sampling frequency (kHz) */
|
||||
const opus_int nb_subfr /* I number of sub frames */
|
||||
);
|
||||
|
||||
opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
|
||||
const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
|
||||
opus_int *pitch_out, /* O 4 pitch lag values */
|
||||
opus_int16 *lagIndex, /* O Lag Index */
|
||||
opus_int8 *contourIndex, /* O Pitch contour Index */
|
||||
opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
|
||||
opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
|
||||
const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
|
||||
const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */
|
||||
const opus_int Fs_kHz, /* I Sample frequency (kHz) */
|
||||
const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
|
||||
const opus_int nb_subfr, /* I number of 5 ms subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
|
||||
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
|
||||
void silk_A2NLSF(
|
||||
opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */
|
||||
opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
|
||||
const opus_int d /* I Filter order (must be even) */
|
||||
);
|
||||
|
||||
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||
void silk_NLSF2A(
|
||||
opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
|
||||
const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
|
||||
const opus_int d /* I filter order (should be even) */
|
||||
);
|
||||
|
||||
void silk_insertion_sort_increasing(
|
||||
opus_int32 *a, /* I/O Unsorted / Sorted vector */
|
||||
opus_int *idx, /* O Index vector for the sorted elements */
|
||||
const opus_int L, /* I Vector length */
|
||||
const opus_int K /* I Number of correctly sorted positions */
|
||||
);
|
||||
|
||||
void silk_insertion_sort_decreasing_int16(
|
||||
opus_int16 *a, /* I/O Unsorted / Sorted vector */
|
||||
opus_int *idx, /* O Index vector for the sorted elements */
|
||||
const opus_int L, /* I Vector length */
|
||||
const opus_int K /* I Number of correctly sorted positions */
|
||||
);
|
||||
|
||||
void silk_insertion_sort_increasing_all_values_int16(
|
||||
opus_int16 *a, /* I/O Unsorted / Sorted vector */
|
||||
const opus_int L /* I Vector length */
|
||||
);
|
||||
|
||||
/* NLSF stabilizer, for a single input data vector */
|
||||
void silk_NLSF_stabilize(
|
||||
opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */
|
||||
const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */
|
||||
const opus_int L /* I Number of NLSF parameters in the input vector */
|
||||
);
|
||||
|
||||
/* Laroia low complexity NLSF weights */
|
||||
void silk_NLSF_VQ_weights_laroia(
|
||||
opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */
|
||||
const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */
|
||||
const opus_int D /* I Input vector dimension (even) */
|
||||
);
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
void silk_burg_modified_c(
|
||||
opus_int32 *res_nrg, /* O Residual energy */
|
||||
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
||||
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
||||
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||
const opus_int D, /* I Order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Copy and multiply a vector by a constant */
|
||||
void silk_scale_copy_vector16(
|
||||
opus_int16 *data_out,
|
||||
const opus_int16 *data_in,
|
||||
opus_int32 gain_Q16, /* I Gain in Q16 */
|
||||
const opus_int dataSize /* I Length */
|
||||
);
|
||||
|
||||
/* Some for the LTP related function requires Q26 to work.*/
|
||||
void silk_scale_vector32_Q26_lshift_18(
|
||||
opus_int32 *data1, /* I/O Q0/Q18 */
|
||||
opus_int32 gain_Q26, /* I Q26 */
|
||||
opus_int dataSize /* I length */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/* INLINE ARM MATH */
|
||||
/********************************************************************/
|
||||
|
||||
/* return sum( inVec1[i] * inVec2[i] ) */
|
||||
|
||||
opus_int32 silk_inner_prod_aligned(
|
||||
const opus_int16 *const inVec1, /* I input vector 1 */
|
||||
const opus_int16 *const inVec2, /* I input vector 2 */
|
||||
const opus_int len, /* I vector lengths */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
|
||||
opus_int32 silk_inner_prod_aligned_scale(
|
||||
const opus_int16 *const inVec1, /* I input vector 1 */
|
||||
const opus_int16 *const inVec2, /* I input vector 2 */
|
||||
const opus_int scale, /* I number of bits to shift */
|
||||
const opus_int len /* I vector lengths */
|
||||
);
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_c(
|
||||
const opus_int16 *inVec1, /* I input vector 1 */
|
||||
const opus_int16 *inVec2, /* I input vector 2 */
|
||||
const opus_int len /* I vector lengths */
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/* MACROS */
|
||||
/********************************************************************/
|
||||
|
||||
/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating
|
||||
left. Output is 32bit int.
|
||||
Note: contemporary compilers recognize the C expression below and
|
||||
compile it into a 'ror' instruction if available. No need for OPUS_INLINE ASM! */
|
||||
static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
|
||||
{
|
||||
opus_uint32 x = (opus_uint32) a32;
|
||||
opus_uint32 r = (opus_uint32) rot;
|
||||
opus_uint32 m = (opus_uint32) -rot;
|
||||
if( rot == 0 ) {
|
||||
return a32;
|
||||
} else if( rot < 0 ) {
|
||||
return (opus_int32) ((x << m) | (x >> (32 - m)));
|
||||
} else {
|
||||
return (opus_int32) ((x << (32 - r)) | (x >> r));
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate opus_int16 aligned to 4-byte memory address */
|
||||
#if EMBEDDED_ARM
|
||||
#define silk_DWORD_ALIGN __attribute__((aligned(4)))
|
||||
#else
|
||||
#define silk_DWORD_ALIGN
|
||||
#endif
|
||||
|
||||
/* Useful Macros that can be adjusted to other platforms */
|
||||
#define silk_memcpy(dest, src, size) memcpy((dest), (src), (size))
|
||||
#define silk_memset(dest, src, size) memset((dest), (src), (size))
|
||||
#define silk_memmove(dest, src, size) memmove((dest), (src), (size))
|
||||
|
||||
/* Fixed point macros */
|
||||
|
||||
/* (a32 * b32) output have to be 32bit int */
|
||||
#define silk_MUL(a32, b32) ((a32) * (b32))
|
||||
|
||||
/* (a32 * b32) output have to be 32bit uint */
|
||||
#define silk_MUL_uint(a32, b32) silk_MUL(a32, b32)
|
||||
|
||||
/* a32 + (b32 * c32) output have to be 32bit int */
|
||||
#define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32)))
|
||||
|
||||
/* a32 + (b32 * c32) output have to be 32bit uint */
|
||||
#define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32)
|
||||
|
||||
/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
|
||||
#define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16))
|
||||
|
||||
/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */
|
||||
#define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16))
|
||||
|
||||
#define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16)))
|
||||
|
||||
/* (a32 * b32) */
|
||||
#define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32))
|
||||
|
||||
/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
|
||||
(just standard two's complement implementation-specific behaviour) */
|
||||
#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))
|
||||
/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
|
||||
(just standard two's complement implementation-specific behaviour) */
|
||||
#define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b)))
|
||||
|
||||
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
|
||||
#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32))
|
||||
#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))))
|
||||
|
||||
#define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16)))
|
||||
#define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32)))
|
||||
|
||||
/* These macros enables checking for overflow in silk_API_Debug.h*/
|
||||
#define silk_ADD16(a, b) ((a) + (b))
|
||||
#define silk_ADD32(a, b) ((a) + (b))
|
||||
#define silk_ADD64(a, b) ((a) + (b))
|
||||
|
||||
#define silk_SUB16(a, b) ((a) - (b))
|
||||
#define silk_SUB32(a, b) ((a) - (b))
|
||||
#define silk_SUB64(a, b) ((a) - (b))
|
||||
|
||||
#define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \
|
||||
((a) < silk_int8_MIN ? silk_int8_MIN : (a)))
|
||||
#define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \
|
||||
((a) < silk_int16_MIN ? silk_int16_MIN : (a)))
|
||||
#define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \
|
||||
((a) < silk_int32_MIN ? silk_int32_MIN : (a)))
|
||||
|
||||
#define silk_CHECK_FIT8(a) (a)
|
||||
#define silk_CHECK_FIT16(a) (a)
|
||||
#define silk_CHECK_FIT32(a) (a)
|
||||
|
||||
#define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) )
|
||||
#define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \
|
||||
((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \
|
||||
((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) )
|
||||
|
||||
#define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) )
|
||||
#define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \
|
||||
(( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \
|
||||
((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) )
|
||||
|
||||
/* Saturation for positive input values */
|
||||
#define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a))
|
||||
|
||||
/* Add with saturation for positive input values */
|
||||
#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
|
||||
#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
|
||||
#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
|
||||
#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))
|
||||
|
||||
#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
|
||||
#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */
|
||||
#define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */
|
||||
#define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */
|
||||
#define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */
|
||||
|
||||
#define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */
|
||||
#define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */
|
||||
#define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */
|
||||
#define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */
|
||||
#define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */
|
||||
|
||||
/* saturates before shifting */
|
||||
#define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \
|
||||
silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) ))
|
||||
|
||||
#define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */
|
||||
#define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */
|
||||
#define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */
|
||||
|
||||
#define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */
|
||||
#define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */
|
||||
#define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */
|
||||
#define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */
|
||||
#define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */
|
||||
#define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */
|
||||
#define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */
|
||||
#define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */
|
||||
|
||||
/* Requires that shift > 0 */
|
||||
#define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
|
||||
#define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1)
|
||||
|
||||
/* Number of rightshift required to fit the multiplication */
|
||||
#define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) )
|
||||
#define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) )
|
||||
|
||||
|
||||
#define silk_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define silk_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* Macro to convert floating-point constants to fixed-point */
|
||||
#define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5))
|
||||
|
||||
/* silk_min() versions with typecast in the function call */
|
||||
static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b)
|
||||
{
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b)
|
||||
{
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b)
|
||||
{
|
||||
return (((a) < (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
/* silk_min() versions with typecast in the function call */
|
||||
static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b)
|
||||
{
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b)
|
||||
{
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
|
||||
{
|
||||
return (((a) > (b)) ? (a) : (b));
|
||||
}
|
||||
|
||||
#define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \
|
||||
: ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a))))
|
||||
|
||||
#define silk_LIMIT_int silk_LIMIT
|
||||
#define silk_LIMIT_16 silk_LIMIT
|
||||
#define silk_LIMIT_32 silk_LIMIT
|
||||
|
||||
#define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */
|
||||
#define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1)))
|
||||
#define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
|
||||
#define silk_abs_int64(a) (((a) > 0) ? (a) : -(a))
|
||||
|
||||
#define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 ))
|
||||
|
||||
/* PSEUDO-RANDOM GENERATOR */
|
||||
/* Make sure to store the result as the seed for the next call (also in between */
|
||||
/* frames), otherwise result won't be random at all. When only using some of the */
|
||||
/* bits, take the most significant bits by right-shifting. */
|
||||
#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165))
|
||||
|
||||
/* Add some multiplication functions that can be easily mapped to ARM. */
|
||||
|
||||
/* silk_SMMUL: Signed top word multiply.
|
||||
ARMv6 2 instruction cycles.
|
||||
ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/
|
||||
/*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/
|
||||
/* the following seems faster on x86 */
|
||||
#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32)
|
||||
|
||||
#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
|
||||
((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
|
||||
|
||||
#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
|
||||
((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len))
|
||||
#endif
|
||||
|
||||
#include "Inlines.h"
|
||||
#include "MacroCount.h"
|
||||
#include "MacroDebug.h"
|
||||
|
||||
#ifdef OPUS_ARM_INLINE_ASM
|
||||
#include "arm/SigProc_FIX_armv4.h"
|
||||
#endif
|
||||
|
||||
#ifdef OPUS_ARM_INLINE_EDSP
|
||||
#include "arm/SigProc_FIX_armv5e.h"
|
||||
#endif
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/sigproc_fix_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SILK_SIGPROC_FIX_H */
|
362
node_modules/node-opus/deps/opus/silk/VAD.c
generated
vendored
Normal file
362
node_modules/node-opus/deps/opus/silk/VAD.c
generated
vendored
Normal file
@ -0,0 +1,362 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/* Silk VAD noise level estimation */
|
||||
# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
static OPUS_INLINE void silk_VAD_GetNoiseLevels(
|
||||
const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
|
||||
silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
|
||||
);
|
||||
#endif
|
||||
|
||||
/**********************************/
|
||||
/* Initialization of the Silk VAD */
|
||||
/**********************************/
|
||||
opus_int silk_VAD_Init( /* O Return value, 0 if success */
|
||||
silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
|
||||
)
|
||||
{
|
||||
opus_int b, ret = 0;
|
||||
|
||||
/* reset state memory */
|
||||
silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) );
|
||||
|
||||
/* init noise levels */
|
||||
/* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
|
||||
}
|
||||
|
||||
/* Initialize state */
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
|
||||
psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] );
|
||||
}
|
||||
psSilk_VAD->counter = 15;
|
||||
|
||||
/* init smoothed energy-to-noise ratio*/
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
|
||||
}
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Weighting factors for tilt measure */
|
||||
static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
|
||||
|
||||
/***************************************/
|
||||
/* Get the speech activity level in Q8 */
|
||||
/***************************************/
|
||||
opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
const opus_int16 pIn[] /* I PCM input */
|
||||
)
|
||||
{
|
||||
opus_int SA_Q15, pSNR_dB_Q7, input_tilt;
|
||||
opus_int decimated_framelength1, decimated_framelength2;
|
||||
opus_int decimated_framelength;
|
||||
opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
|
||||
opus_int32 sumSquared, smooth_coef_Q16;
|
||||
opus_int16 HPstateTmp;
|
||||
VARDECL( opus_int16, X );
|
||||
opus_int32 Xnrg[ VAD_N_BANDS ];
|
||||
opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
|
||||
opus_int32 speech_nrg, x_tmp;
|
||||
opus_int X_offset[ VAD_N_BANDS ];
|
||||
opus_int ret = 0;
|
||||
silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Safety checks */
|
||||
silk_assert( VAD_N_BANDS == 4 );
|
||||
silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
|
||||
silk_assert( psEncC->frame_length <= 512 );
|
||||
silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
|
||||
|
||||
/***********************/
|
||||
/* Filter and Decimate */
|
||||
/***********************/
|
||||
decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
|
||||
decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
|
||||
decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
|
||||
/* Decimate into 4 bands:
|
||||
0 L 3L L 3L 5L
|
||||
- -- - -- --
|
||||
8 8 2 4 4
|
||||
|
||||
[0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz |
|
||||
|
||||
They're arranged to allow the minimal ( frame_length / 4 ) extra
|
||||
scratch space during the downsampling process */
|
||||
X_offset[ 0 ] = 0;
|
||||
X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
|
||||
X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
|
||||
X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
|
||||
ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
|
||||
|
||||
/* 0-8 kHz to 0-4 kHz and 4-8 kHz */
|
||||
silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ],
|
||||
X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
|
||||
|
||||
/* 0-4 kHz to 0-2 kHz and 2-4 kHz */
|
||||
silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
|
||||
X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
|
||||
|
||||
/* 0-2 kHz to 0-1 kHz and 1-2 kHz */
|
||||
silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
|
||||
X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
|
||||
|
||||
/*********************************************/
|
||||
/* HP filter on lowest band (differentiator) */
|
||||
/*********************************************/
|
||||
X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
|
||||
HPstateTmp = X[ decimated_framelength - 1 ];
|
||||
for( i = decimated_framelength - 1; i > 0; i-- ) {
|
||||
X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 );
|
||||
X[ i ] -= X[ i - 1 ];
|
||||
}
|
||||
X[ 0 ] -= psSilk_VAD->HPstate;
|
||||
psSilk_VAD->HPstate = HPstateTmp;
|
||||
|
||||
/*************************************/
|
||||
/* Calculate the energy in each band */
|
||||
/*************************************/
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
/* Find the decimated framelength in the non-uniformly divided bands */
|
||||
decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
|
||||
|
||||
/* Split length into subframe lengths */
|
||||
dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
|
||||
dec_subframe_offset = 0;
|
||||
|
||||
/* Compute energy per sub-frame */
|
||||
/* initialize with summed energy of last subframe */
|
||||
Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
|
||||
for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
|
||||
sumSquared = 0;
|
||||
for( i = 0; i < dec_subframe_length; i++ ) {
|
||||
/* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */
|
||||
/* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
|
||||
x_tmp = silk_RSHIFT(
|
||||
X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
|
||||
sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
|
||||
|
||||
/* Safety check */
|
||||
silk_assert( sumSquared >= 0 );
|
||||
}
|
||||
|
||||
/* Add/saturate summed energy of current subframe */
|
||||
if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
|
||||
Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
|
||||
} else {
|
||||
/* Look-ahead subframe */
|
||||
Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
|
||||
}
|
||||
|
||||
dec_subframe_offset += dec_subframe_length;
|
||||
}
|
||||
psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
|
||||
}
|
||||
|
||||
/********************/
|
||||
/* Noise estimation */
|
||||
/********************/
|
||||
silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
|
||||
|
||||
/***********************************************/
|
||||
/* Signal-plus-noise to noise ratio estimation */
|
||||
/***********************************************/
|
||||
sumSquared = 0;
|
||||
input_tilt = 0;
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
|
||||
if( speech_nrg > 0 ) {
|
||||
/* Divide, with sufficient resolution */
|
||||
if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
|
||||
NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
|
||||
} else {
|
||||
NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
|
||||
}
|
||||
|
||||
/* Convert to log domain */
|
||||
SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
|
||||
|
||||
/* Sum-of-squares */
|
||||
sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
|
||||
|
||||
/* Tilt measure */
|
||||
if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
|
||||
/* Scale down SNR value for small subband speech energies */
|
||||
SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
|
||||
}
|
||||
input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
|
||||
} else {
|
||||
NrgToNoiseRatio_Q8[ b ] = 256;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mean-of-squares */
|
||||
sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
|
||||
|
||||
/* Root-mean-square approximation, scale to dBs, and write to output pointer */
|
||||
pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
|
||||
|
||||
/*********************************/
|
||||
/* Speech Probability Estimation */
|
||||
/*********************************/
|
||||
SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
|
||||
|
||||
/**************************/
|
||||
/* Frequency Tilt Measure */
|
||||
/**************************/
|
||||
psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
|
||||
|
||||
/**************************************************/
|
||||
/* Scale the sigmoid output based on power levels */
|
||||
/**************************************************/
|
||||
speech_nrg = 0;
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
/* Accumulate signal-without-noise energies, higher frequency bands have more weight */
|
||||
speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
|
||||
}
|
||||
|
||||
/* Power scaling */
|
||||
if( speech_nrg <= 0 ) {
|
||||
SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
|
||||
} else if( speech_nrg < 32768 ) {
|
||||
if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
|
||||
speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );
|
||||
} else {
|
||||
speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );
|
||||
}
|
||||
|
||||
/* square-root */
|
||||
speech_nrg = silk_SQRT_APPROX( speech_nrg );
|
||||
SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
|
||||
}
|
||||
|
||||
/* Copy the resulting speech activity in Q8 */
|
||||
psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
|
||||
|
||||
/***********************************/
|
||||
/* Energy Level and SNR estimation */
|
||||
/***********************************/
|
||||
/* Smoothing coefficient */
|
||||
smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
|
||||
|
||||
if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
|
||||
smooth_coef_Q16 >>= 1;
|
||||
}
|
||||
|
||||
for( b = 0; b < VAD_N_BANDS; b++ ) {
|
||||
/* compute smoothed energy-to-noise ratio per band */
|
||||
psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
|
||||
NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
|
||||
|
||||
/* signal to noise ratio in dB per band */
|
||||
SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
|
||||
/* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
|
||||
psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
|
||||
}
|
||||
|
||||
RESTORE_STACK;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Noise level estimation */
|
||||
/**************************/
|
||||
# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
|
||||
static OPUS_INLINE
|
||||
#endif
|
||||
void silk_VAD_GetNoiseLevels(
|
||||
const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
|
||||
silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
opus_int32 nl, nrg, inv_nrg;
|
||||
opus_int coef, min_coef;
|
||||
|
||||
/* Initially faster smoothing */
|
||||
if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
|
||||
min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
|
||||
} else {
|
||||
min_coef = 0;
|
||||
}
|
||||
|
||||
for( k = 0; k < VAD_N_BANDS; k++ ) {
|
||||
/* Get old noise level estimate for current band */
|
||||
nl = psSilk_VAD->NL[ k ];
|
||||
silk_assert( nl >= 0 );
|
||||
|
||||
/* Add bias */
|
||||
nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
|
||||
silk_assert( nrg > 0 );
|
||||
|
||||
/* Invert energies */
|
||||
inv_nrg = silk_DIV32( silk_int32_MAX, nrg );
|
||||
silk_assert( inv_nrg >= 0 );
|
||||
|
||||
/* Less update when subband energy is high */
|
||||
if( nrg > silk_LSHIFT( nl, 3 ) ) {
|
||||
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
|
||||
} else if( nrg < nl ) {
|
||||
coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
|
||||
} else {
|
||||
coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
|
||||
}
|
||||
|
||||
/* Initially faster smoothing */
|
||||
coef = silk_max_int( coef, min_coef );
|
||||
|
||||
/* Smooth inverse energies */
|
||||
psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
|
||||
silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
|
||||
|
||||
/* Compute noise level by inverting again */
|
||||
nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] );
|
||||
silk_assert( nl >= 0 );
|
||||
|
||||
/* Limit noise levels (guarantee 7 bits of head room) */
|
||||
nl = silk_min( nl, 0x00FFFFFF );
|
||||
|
||||
/* Store as part of state */
|
||||
psSilk_VAD->NL[ k ] = nl;
|
||||
}
|
||||
|
||||
/* Increment frame counter */
|
||||
psSilk_VAD->counter++;
|
||||
}
|
120
node_modules/node-opus/deps/opus/silk/VQ_WMat_EC.c
generated
vendored
Normal file
120
node_modules/node-opus/deps/opus/silk/VQ_WMat_EC.c
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
|
||||
void silk_VQ_WMat_EC_c(
|
||||
opus_int8 *ind, /* O index of best codebook vector */
|
||||
opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
|
||||
opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
|
||||
const opus_int16 *in_Q14, /* I input vector to be quantized */
|
||||
const opus_int32 *W_Q18, /* I weighting matrix */
|
||||
const opus_int8 *cb_Q7, /* I codebook */
|
||||
const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
|
||||
const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
|
||||
const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
|
||||
const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
|
||||
opus_int L /* I number of vectors in codebook */
|
||||
)
|
||||
{
|
||||
opus_int k, gain_tmp_Q7;
|
||||
const opus_int8 *cb_row_Q7;
|
||||
opus_int16 diff_Q14[ 5 ];
|
||||
opus_int32 sum1_Q14, sum2_Q16;
|
||||
|
||||
/* Loop over codebook */
|
||||
*rate_dist_Q14 = silk_int32_MAX;
|
||||
cb_row_Q7 = cb_Q7;
|
||||
for( k = 0; k < L; k++ ) {
|
||||
gain_tmp_Q7 = cb_gain_Q7[k];
|
||||
|
||||
diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
|
||||
diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 );
|
||||
diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 );
|
||||
diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 );
|
||||
diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 );
|
||||
|
||||
/* Weighted rate */
|
||||
sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
|
||||
|
||||
/* Penalty for too large gain */
|
||||
sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
|
||||
|
||||
silk_assert( sum1_Q14 >= 0 );
|
||||
|
||||
/* first row of W_Q18 */
|
||||
sum2_Q16 = silk_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] );
|
||||
sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
|
||||
sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
|
||||
|
||||
/* second row of W_Q18 */
|
||||
sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
|
||||
sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
|
||||
sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
|
||||
|
||||
/* third row of W_Q18 */
|
||||
sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
|
||||
sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
|
||||
sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
|
||||
|
||||
/* fourth row of W_Q18 */
|
||||
sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
|
||||
sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
|
||||
sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
|
||||
sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
|
||||
|
||||
/* last row of W_Q18 */
|
||||
sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
|
||||
sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
|
||||
|
||||
silk_assert( sum1_Q14 >= 0 );
|
||||
|
||||
/* find best */
|
||||
if( sum1_Q14 < *rate_dist_Q14 ) {
|
||||
*rate_dist_Q14 = sum1_Q14;
|
||||
*ind = (opus_int8)k;
|
||||
*gain_Q7 = gain_tmp_Q7;
|
||||
}
|
||||
|
||||
/* Go to next cbk vector */
|
||||
cb_row_Q7 += LTP_ORDER;
|
||||
}
|
||||
}
|
74
node_modules/node-opus/deps/opus/silk/ana_filt_bank_1.c
generated
vendored
Normal file
74
node_modules/node-opus/deps/opus/silk/ana_filt_bank_1.c
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Coefficients for 2-band filter bank based on first-order allpass filters */
|
||||
static opus_int16 A_fb1_20 = 5394 << 1;
|
||||
static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */
|
||||
|
||||
/* Split signal into two decimated bands using first-order allpass filters */
|
||||
void silk_ana_filt_bank_1(
|
||||
const opus_int16 *in, /* I Input signal [N] */
|
||||
opus_int32 *S, /* I/O State vector [2] */
|
||||
opus_int16 *outL, /* O Low band [N/2] */
|
||||
opus_int16 *outH, /* O High band [N/2] */
|
||||
const opus_int32 N /* I Number of input samples */
|
||||
)
|
||||
{
|
||||
opus_int k, N2 = silk_RSHIFT( N, 1 );
|
||||
opus_int32 in32, X, Y, out_1, out_2;
|
||||
|
||||
/* Internal variables and state are in Q10 format */
|
||||
for( k = 0; k < N2; k++ ) {
|
||||
/* Convert to Q10 */
|
||||
in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );
|
||||
|
||||
/* All-pass section for even input sample */
|
||||
Y = silk_SUB32( in32, S[ 0 ] );
|
||||
X = silk_SMLAWB( Y, Y, A_fb1_21 );
|
||||
out_1 = silk_ADD32( S[ 0 ], X );
|
||||
S[ 0 ] = silk_ADD32( in32, X );
|
||||
|
||||
/* Convert to Q10 */
|
||||
in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );
|
||||
|
||||
/* All-pass section for odd input sample, and add to output of previous section */
|
||||
Y = silk_SUB32( in32, S[ 1 ] );
|
||||
X = silk_SMULWB( Y, A_fb1_20 );
|
||||
out_2 = silk_ADD32( S[ 1 ], X );
|
||||
S[ 1 ] = silk_ADD32( in32, X );
|
||||
|
||||
/* Add/subtract, convert back to int16 and store to output */
|
||||
outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) );
|
||||
outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) );
|
||||
}
|
||||
}
|
47
node_modules/node-opus/deps/opus/silk/arm/SigProc_FIX_armv4.h
generated
vendored
Normal file
47
node_modules/node-opus/deps/opus/silk/arm/SigProc_FIX_armv4.h
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/***********************************************************************
|
||||
Copyright (C) 2013 Xiph.Org Foundation and contributors
|
||||
Copyright (c) 2013 Parrot
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_SIGPROC_FIX_ARMv4_H
|
||||
#define SILK_SIGPROC_FIX_ARMv4_H
|
||||
|
||||
#undef silk_MLA
|
||||
static OPUS_INLINE opus_int32 silk_MLA_armv4(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
opus_int32 res;
|
||||
__asm__(
|
||||
"#silk_MLA\n\t"
|
||||
"mla %0, %1, %2, %3\n\t"
|
||||
: "=&r"(res)
|
||||
: "r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_MLA(a, b, c) (silk_MLA_armv4(a, b, c))
|
||||
|
||||
#endif
|
61
node_modules/node-opus/deps/opus/silk/arm/SigProc_FIX_armv5e.h
generated
vendored
Normal file
61
node_modules/node-opus/deps/opus/silk/arm/SigProc_FIX_armv5e.h
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2013 Parrot
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_SIGPROC_FIX_ARMv5E_H
|
||||
#define SILK_SIGPROC_FIX_ARMv5E_H
|
||||
|
||||
#undef silk_SMULTT
|
||||
static OPUS_INLINE opus_int32 silk_SMULTT_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
opus_int32 res;
|
||||
__asm__(
|
||||
"#silk_SMULTT\n\t"
|
||||
"smultt %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "%r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMULTT(a, b) (silk_SMULTT_armv5e(a, b))
|
||||
|
||||
#undef silk_SMLATT
|
||||
static OPUS_INLINE opus_int32 silk_SMLATT_armv5e(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
opus_int32 res;
|
||||
__asm__(
|
||||
"#silk_SMLATT\n\t"
|
||||
"smlatt %0, %1, %2, %3\n\t"
|
||||
: "=r"(res)
|
||||
: "%r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMLATT(a, b, c) (silk_SMLATT_armv5e(a, b, c))
|
||||
|
||||
#endif
|
103
node_modules/node-opus/deps/opus/silk/arm/macros_armv4.h
generated
vendored
Normal file
103
node_modules/node-opus/deps/opus/silk/arm/macros_armv4.h
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/***********************************************************************
|
||||
Copyright (C) 2013 Xiph.Org Foundation and contributors.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_MACROS_ARMv4_H
|
||||
#define SILK_MACROS_ARMv4_H
|
||||
|
||||
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
|
||||
#undef silk_SMULWB
|
||||
static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
|
||||
{
|
||||
unsigned rd_lo;
|
||||
int rd_hi;
|
||||
__asm__(
|
||||
"#silk_SMULWB\n\t"
|
||||
"smull %0, %1, %2, %3\n\t"
|
||||
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||
: "%r"(a), "r"(b<<16)
|
||||
);
|
||||
return rd_hi;
|
||||
}
|
||||
#define silk_SMULWB(a, b) (silk_SMULWB_armv4(a, b))
|
||||
|
||||
/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
|
||||
#undef silk_SMLAWB
|
||||
#define silk_SMLAWB(a, b, c) ((a) + silk_SMULWB(b, c))
|
||||
|
||||
/* (a32 * (b32 >> 16)) >> 16 */
|
||||
#undef silk_SMULWT
|
||||
static OPUS_INLINE opus_int32 silk_SMULWT_armv4(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
unsigned rd_lo;
|
||||
int rd_hi;
|
||||
__asm__(
|
||||
"#silk_SMULWT\n\t"
|
||||
"smull %0, %1, %2, %3\n\t"
|
||||
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||
: "%r"(a), "r"(b&~0xFFFF)
|
||||
);
|
||||
return rd_hi;
|
||||
}
|
||||
#define silk_SMULWT(a, b) (silk_SMULWT_armv4(a, b))
|
||||
|
||||
/* a32 + (b32 * (c32 >> 16)) >> 16 */
|
||||
#undef silk_SMLAWT
|
||||
#define silk_SMLAWT(a, b, c) ((a) + silk_SMULWT(b, c))
|
||||
|
||||
/* (a32 * b32) >> 16 */
|
||||
#undef silk_SMULWW
|
||||
static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
unsigned rd_lo;
|
||||
int rd_hi;
|
||||
__asm__(
|
||||
"#silk_SMULWW\n\t"
|
||||
"smull %0, %1, %2, %3\n\t"
|
||||
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||
: "%r"(a), "r"(b)
|
||||
);
|
||||
return (rd_hi<<16)+(rd_lo>>16);
|
||||
}
|
||||
#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))
|
||||
|
||||
#undef silk_SMLAWW
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
unsigned rd_lo;
|
||||
int rd_hi;
|
||||
__asm__(
|
||||
"#silk_SMLAWW\n\t"
|
||||
"smull %0, %1, %2, %3\n\t"
|
||||
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||
: "%r"(b), "r"(c)
|
||||
);
|
||||
return a+(rd_hi<<16)+(rd_lo>>16);
|
||||
}
|
||||
#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))
|
||||
|
||||
#endif /* SILK_MACROS_ARMv4_H */
|
213
node_modules/node-opus/deps/opus/silk/arm/macros_armv5e.h
generated
vendored
Normal file
213
node_modules/node-opus/deps/opus/silk/arm/macros_armv5e.h
generated
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
Copyright (c) 2013 Parrot
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_MACROS_ARMv5E_H
|
||||
#define SILK_MACROS_ARMv5E_H
|
||||
|
||||
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
|
||||
#undef silk_SMULWB
|
||||
static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMULWB\n\t"
|
||||
"smulwb %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b))
|
||||
|
||||
/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
|
||||
#undef silk_SMLAWB
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b,
|
||||
opus_int16 c)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMLAWB\n\t"
|
||||
"smlawb %0, %1, %2, %3\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c))
|
||||
|
||||
/* (a32 * (b32 >> 16)) >> 16 */
|
||||
#undef silk_SMULWT
|
||||
static OPUS_INLINE opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMULWT\n\t"
|
||||
"smulwt %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b))
|
||||
|
||||
/* a32 + (b32 * (c32 >> 16)) >> 16 */
|
||||
#undef silk_SMLAWT
|
||||
static OPUS_INLINE opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMLAWT\n\t"
|
||||
"smlawt %0, %1, %2, %3\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c))
|
||||
|
||||
/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
|
||||
#undef silk_SMULBB
|
||||
static OPUS_INLINE opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMULBB\n\t"
|
||||
"smulbb %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "%r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b))
|
||||
|
||||
/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */
|
||||
#undef silk_SMLABB
|
||||
static OPUS_INLINE opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMLABB\n\t"
|
||||
"smlabb %0, %1, %2, %3\n\t"
|
||||
: "=r"(res)
|
||||
: "%r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c))
|
||||
|
||||
/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */
|
||||
#undef silk_SMULBT
|
||||
static OPUS_INLINE opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMULBT\n\t"
|
||||
"smulbt %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b))
|
||||
|
||||
/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */
|
||||
#undef silk_SMLABT
|
||||
static OPUS_INLINE opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b,
|
||||
opus_int32 c)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SMLABT\n\t"
|
||||
"smlabt %0, %1, %2, %3\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(b), "r"(c), "r"(a)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c))
|
||||
|
||||
/* add/subtract with output saturated */
|
||||
#undef silk_ADD_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_ADD_SAT32\n\t"
|
||||
"qadd %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "%r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b))
|
||||
|
||||
#undef silk_SUB_SAT32
|
||||
static OPUS_INLINE opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_SUB_SAT32\n\t"
|
||||
"qsub %0, %1, %2\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(a), "r"(b)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b))
|
||||
|
||||
#undef silk_CLZ16
|
||||
static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_CLZ16\n\t"
|
||||
"clz %0, %1;\n"
|
||||
: "=r"(res)
|
||||
: "r"(in16<<16|0x8000)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_CLZ16(in16) (silk_CLZ16_armv5(in16))
|
||||
|
||||
#undef silk_CLZ32
|
||||
static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)
|
||||
{
|
||||
int res;
|
||||
__asm__(
|
||||
"#silk_CLZ32\n\t"
|
||||
"clz %0, %1\n\t"
|
||||
: "=r"(res)
|
||||
: "r"(in32)
|
||||
);
|
||||
return res;
|
||||
}
|
||||
#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
|
||||
|
||||
#endif /* SILK_MACROS_ARMv5E_H */
|
78
node_modules/node-opus/deps/opus/silk/biquad_alt.c
generated
vendored
Normal file
78
node_modules/node-opus/deps/opus/silk/biquad_alt.c
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
/* *
|
||||
* silk_biquad_alt.c *
|
||||
* *
|
||||
* Second order ARMA filter *
|
||||
* Can handle slowly varying filter coefficients *
|
||||
* */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
|
||||
/* Second order ARMA filter, alternative implementation */
|
||||
void silk_biquad_alt(
|
||||
const opus_int16 *in, /* I input signal */
|
||||
const opus_int32 *B_Q28, /* I MA coefficients [3] */
|
||||
const opus_int32 *A_Q28, /* I AR coefficients [2] */
|
||||
opus_int32 *S, /* I/O State vector [2] */
|
||||
opus_int16 *out, /* O output signal */
|
||||
const opus_int32 len, /* I signal length (must be even) */
|
||||
opus_int stride /* I Operate on interleaved signal if > 1 */
|
||||
)
|
||||
{
|
||||
/* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
|
||||
opus_int k;
|
||||
opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
|
||||
|
||||
/* Negate A_Q28 values and split in two parts */
|
||||
A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
|
||||
A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
|
||||
A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
|
||||
A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
|
||||
|
||||
for( k = 0; k < len; k++ ) {
|
||||
/* S[ 0 ], S[ 1 ]: Q12 */
|
||||
inval = in[ k * stride ];
|
||||
out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
|
||||
|
||||
S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
|
||||
S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
|
||||
S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
|
||||
|
||||
S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
|
||||
S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
|
||||
S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
|
||||
|
||||
/* Scale back to Q0 and saturate */
|
||||
out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
|
||||
}
|
||||
}
|
51
node_modules/node-opus/deps/opus/silk/bwexpander.c
generated
vendored
Normal file
51
node_modules/node-opus/deps/opus/silk/bwexpander.c
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Chirp (bandwidth expand) LP AR filter */
|
||||
void silk_bwexpander(
|
||||
opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I Length of ar */
|
||||
opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
||||
|
||||
/* NB: Dont use silk_SMULWB, instead of silk_RSHIFT_ROUND( silk_MUL(), 16 ), below. */
|
||||
/* Bias in silk_SMULWB can lead to unstable filters */
|
||||
for( i = 0; i < d - 1; i++ ) {
|
||||
ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 );
|
||||
chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
|
||||
}
|
||||
ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
|
||||
}
|
50
node_modules/node-opus/deps/opus/silk/bwexpander_32.c
generated
vendored
Normal file
50
node_modules/node-opus/deps/opus/silk/bwexpander_32.c
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Chirp (bandwidth expand) LP AR filter */
|
||||
void silk_bwexpander_32(
|
||||
opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I Length of ar */
|
||||
opus_int32 chirp_Q16 /* I Chirp factor in Q16 */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
||||
|
||||
for( i = 0; i < d - 1; i++ ) {
|
||||
ar[ i ] = silk_SMULWW( chirp_Q16, ar[ i ] );
|
||||
chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
|
||||
}
|
||||
ar[ d - 1 ] = silk_SMULWW( chirp_Q16, ar[ d - 1 ] );
|
||||
}
|
||||
|
106
node_modules/node-opus/deps/opus/silk/check_control_input.c
generated
vendored
Normal file
106
node_modules/node-opus/deps/opus/silk/check_control_input.c
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "control.h"
|
||||
#include "errors.h"
|
||||
|
||||
/* Check encoder control struct */
|
||||
opus_int check_control_input(
|
||||
silk_EncControlStruct *encControl /* I Control structure */
|
||||
)
|
||||
{
|
||||
silk_assert( encControl != NULL );
|
||||
|
||||
if( ( ( encControl->API_sampleRate != 8000 ) &&
|
||||
( encControl->API_sampleRate != 12000 ) &&
|
||||
( encControl->API_sampleRate != 16000 ) &&
|
||||
( encControl->API_sampleRate != 24000 ) &&
|
||||
( encControl->API_sampleRate != 32000 ) &&
|
||||
( encControl->API_sampleRate != 44100 ) &&
|
||||
( encControl->API_sampleRate != 48000 ) ) ||
|
||||
( ( encControl->desiredInternalSampleRate != 8000 ) &&
|
||||
( encControl->desiredInternalSampleRate != 12000 ) &&
|
||||
( encControl->desiredInternalSampleRate != 16000 ) ) ||
|
||||
( ( encControl->maxInternalSampleRate != 8000 ) &&
|
||||
( encControl->maxInternalSampleRate != 12000 ) &&
|
||||
( encControl->maxInternalSampleRate != 16000 ) ) ||
|
||||
( ( encControl->minInternalSampleRate != 8000 ) &&
|
||||
( encControl->minInternalSampleRate != 12000 ) &&
|
||||
( encControl->minInternalSampleRate != 16000 ) ) ||
|
||||
( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||
|
||||
( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||
|
||||
( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_FS_NOT_SUPPORTED;
|
||||
}
|
||||
if( encControl->payloadSize_ms != 10 &&
|
||||
encControl->payloadSize_ms != 20 &&
|
||||
encControl->payloadSize_ms != 40 &&
|
||||
encControl->payloadSize_ms != 60 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
|
||||
}
|
||||
if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_LOSS_RATE;
|
||||
}
|
||||
if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_DTX_SETTING;
|
||||
}
|
||||
if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_CBR_SETTING;
|
||||
}
|
||||
if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_INBAND_FEC_SETTING;
|
||||
}
|
||||
if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
|
||||
}
|
||||
if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
|
||||
}
|
||||
if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
|
||||
}
|
||||
if( encControl->complexity < 0 || encControl->complexity > 10 ) {
|
||||
silk_assert( 0 );
|
||||
return SILK_ENC_INVALID_COMPLEXITY_SETTING;
|
||||
}
|
||||
|
||||
return SILK_NO_ERROR;
|
||||
}
|
115
node_modules/node-opus/deps/opus/silk/code_signs.c
generated
vendored
Normal file
115
node_modules/node-opus/deps/opus/silk/code_signs.c
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/*#define silk_enc_map(a) ((a) > 0 ? 1 : 0)*/
|
||||
/*#define silk_dec_map(a) ((a) > 0 ? 1 : -1)*/
|
||||
/* shifting avoids if-statement */
|
||||
#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 )
|
||||
#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 )
|
||||
|
||||
/* Encodes signs of excitation */
|
||||
void silk_encode_signs(
|
||||
ec_enc *psRangeEnc, /* I/O Compressor data structure */
|
||||
const opus_int8 pulses[], /* I pulse signal */
|
||||
opus_int length, /* I length of input */
|
||||
const opus_int signalType, /* I Signal type */
|
||||
const opus_int quantOffsetType, /* I Quantization offset type */
|
||||
const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
|
||||
)
|
||||
{
|
||||
opus_int i, j, p;
|
||||
opus_uint8 icdf[ 2 ];
|
||||
const opus_int8 *q_ptr;
|
||||
const opus_uint8 *icdf_ptr;
|
||||
|
||||
icdf[ 1 ] = 0;
|
||||
q_ptr = pulses;
|
||||
i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
|
||||
icdf_ptr = &silk_sign_iCDF[ i ];
|
||||
length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
|
||||
for( i = 0; i < length; i++ ) {
|
||||
p = sum_pulses[ i ];
|
||||
if( p > 0 ) {
|
||||
icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
|
||||
for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
|
||||
if( q_ptr[ j ] != 0 ) {
|
||||
ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 );
|
||||
}
|
||||
}
|
||||
}
|
||||
q_ptr += SHELL_CODEC_FRAME_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes signs of excitation */
|
||||
void silk_decode_signs(
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int16 pulses[], /* I/O pulse signal */
|
||||
opus_int length, /* I length of input */
|
||||
const opus_int signalType, /* I Signal type */
|
||||
const opus_int quantOffsetType, /* I Quantization offset type */
|
||||
const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
|
||||
)
|
||||
{
|
||||
opus_int i, j, p;
|
||||
opus_uint8 icdf[ 2 ];
|
||||
opus_int16 *q_ptr;
|
||||
const opus_uint8 *icdf_ptr;
|
||||
|
||||
icdf[ 1 ] = 0;
|
||||
q_ptr = pulses;
|
||||
i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
|
||||
icdf_ptr = &silk_sign_iCDF[ i ];
|
||||
length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
|
||||
for( i = 0; i < length; i++ ) {
|
||||
p = sum_pulses[ i ];
|
||||
if( p > 0 ) {
|
||||
icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ];
|
||||
for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
|
||||
if( q_ptr[ j ] > 0 ) {
|
||||
/* attach sign */
|
||||
#if 0
|
||||
/* conditional implementation */
|
||||
if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) {
|
||||
q_ptr[ j ] = -q_ptr[ j ];
|
||||
}
|
||||
#else
|
||||
/* implementation with shift, subtraction, multiplication */
|
||||
q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
q_ptr += SHELL_CODEC_FRAME_LENGTH;
|
||||
}
|
||||
}
|
142
node_modules/node-opus/deps/opus/silk/control.h
generated
vendored
Normal file
142
node_modules/node-opus/deps/opus/silk/control.h
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_CONTROL_H
|
||||
#define SILK_CONTROL_H
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Decoder API flags */
|
||||
#define FLAG_DECODE_NORMAL 0
|
||||
#define FLAG_PACKET_LOST 1
|
||||
#define FLAG_DECODE_LBRR 2
|
||||
|
||||
/***********************************************/
|
||||
/* Structure for controlling encoder operation */
|
||||
/***********************************************/
|
||||
typedef struct {
|
||||
/* I: Number of channels; 1/2 */
|
||||
opus_int32 nChannelsAPI;
|
||||
|
||||
/* I: Number of channels; 1/2 */
|
||||
opus_int32 nChannelsInternal;
|
||||
|
||||
/* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */
|
||||
opus_int32 API_sampleRate;
|
||||
|
||||
/* I: Maximum internal sampling rate in Hertz; 8000/12000/16000 */
|
||||
opus_int32 maxInternalSampleRate;
|
||||
|
||||
/* I: Minimum internal sampling rate in Hertz; 8000/12000/16000 */
|
||||
opus_int32 minInternalSampleRate;
|
||||
|
||||
/* I: Soft request for internal sampling rate in Hertz; 8000/12000/16000 */
|
||||
opus_int32 desiredInternalSampleRate;
|
||||
|
||||
/* I: Number of samples per packet in milliseconds; 10/20/40/60 */
|
||||
opus_int payloadSize_ms;
|
||||
|
||||
/* I: Bitrate during active speech in bits/second; internally limited */
|
||||
opus_int32 bitRate;
|
||||
|
||||
/* I: Uplink packet loss in percent (0-100) */
|
||||
opus_int packetLossPercentage;
|
||||
|
||||
/* I: Complexity mode; 0 is lowest, 10 is highest complexity */
|
||||
opus_int complexity;
|
||||
|
||||
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
|
||||
opus_int useInBandFEC;
|
||||
|
||||
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
|
||||
opus_int useDTX;
|
||||
|
||||
/* I: Flag to use constant bitrate */
|
||||
opus_int useCBR;
|
||||
|
||||
/* I: Maximum number of bits allowed for the frame */
|
||||
opus_int maxBits;
|
||||
|
||||
/* I: Causes a smooth downmix to mono */
|
||||
opus_int toMono;
|
||||
|
||||
/* I: Opus encoder is allowing us to switch bandwidth */
|
||||
opus_int opusCanSwitch;
|
||||
|
||||
/* I: Make frames as independent as possible (but still use LPC) */
|
||||
opus_int reducedDependency;
|
||||
|
||||
/* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */
|
||||
opus_int32 internalSampleRate;
|
||||
|
||||
/* O: Flag that bandwidth switching is allowed (because low voice activity) */
|
||||
opus_int allowBandwidthSwitch;
|
||||
|
||||
/* O: Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */
|
||||
opus_int inWBmodeWithoutVariableLP;
|
||||
|
||||
/* O: Stereo width */
|
||||
opus_int stereoWidth_Q14;
|
||||
|
||||
/* O: Tells the Opus encoder we're ready to switch */
|
||||
opus_int switchReady;
|
||||
|
||||
} silk_EncControlStruct;
|
||||
|
||||
/**************************************************************************/
|
||||
/* Structure for controlling decoder operation and reading decoder status */
|
||||
/**************************************************************************/
|
||||
typedef struct {
|
||||
/* I: Number of channels; 1/2 */
|
||||
opus_int32 nChannelsAPI;
|
||||
|
||||
/* I: Number of channels; 1/2 */
|
||||
opus_int32 nChannelsInternal;
|
||||
|
||||
/* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */
|
||||
opus_int32 API_sampleRate;
|
||||
|
||||
/* I: Internal sampling rate used, in Hertz; 8000/12000/16000 */
|
||||
opus_int32 internalSampleRate;
|
||||
|
||||
/* I: Number of samples per packet in milliseconds; 10/20/40/60 */
|
||||
opus_int payloadSize_ms;
|
||||
|
||||
/* O: Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz */
|
||||
opus_int prevPitchLag;
|
||||
} silk_DecControlStruct;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
76
node_modules/node-opus/deps/opus/silk/control_SNR.c
generated
vendored
Normal file
76
node_modules/node-opus/deps/opus/silk/control_SNR.c
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Control SNR of redidual quantizer */
|
||||
opus_int silk_control_SNR(
|
||||
silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
|
||||
opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
|
||||
)
|
||||
{
|
||||
opus_int k, ret = SILK_NO_ERROR;
|
||||
opus_int32 frac_Q6;
|
||||
const opus_int32 *rateTable;
|
||||
|
||||
/* Set bitrate/coding quality */
|
||||
TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
|
||||
if( TargetRate_bps != psEncC->TargetRate_bps ) {
|
||||
psEncC->TargetRate_bps = TargetRate_bps;
|
||||
|
||||
/* If new TargetRate_bps, translate to SNR_dB value */
|
||||
if( psEncC->fs_kHz == 8 ) {
|
||||
rateTable = silk_TargetRate_table_NB;
|
||||
} else if( psEncC->fs_kHz == 12 ) {
|
||||
rateTable = silk_TargetRate_table_MB;
|
||||
} else {
|
||||
rateTable = silk_TargetRate_table_WB;
|
||||
}
|
||||
|
||||
/* Reduce bitrate for 10 ms modes in these calculations */
|
||||
if( psEncC->nb_subfr == 2 ) {
|
||||
TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;
|
||||
}
|
||||
|
||||
/* Find bitrate interval in table and interpolate */
|
||||
for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
|
||||
if( TargetRate_bps <= rateTable[ k ] ) {
|
||||
frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),
|
||||
rateTable[ k ] - rateTable[ k - 1 ] );
|
||||
psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
126
node_modules/node-opus/deps/opus/silk/control_audio_bandwidth.c
generated
vendored
Normal file
126
node_modules/node-opus/deps/opus/silk/control_audio_bandwidth.c
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Control internal sampling rate */
|
||||
opus_int silk_control_audio_bandwidth(
|
||||
silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
|
||||
silk_EncControlStruct *encControl /* I Control structure */
|
||||
)
|
||||
{
|
||||
opus_int fs_kHz;
|
||||
opus_int32 fs_Hz;
|
||||
|
||||
fs_kHz = psEncC->fs_kHz;
|
||||
fs_Hz = silk_SMULBB( fs_kHz, 1000 );
|
||||
if( fs_Hz == 0 ) {
|
||||
/* Encoder has just been initialized */
|
||||
fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz );
|
||||
fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
|
||||
} else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) {
|
||||
/* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
|
||||
fs_Hz = psEncC->API_fs_Hz;
|
||||
fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz );
|
||||
fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz );
|
||||
fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
|
||||
} else {
|
||||
/* State machine for the internal sampling rate switching */
|
||||
if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
|
||||
/* Stop transition phase */
|
||||
psEncC->sLP.mode = 0;
|
||||
}
|
||||
if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
|
||||
/* Check if we should switch down */
|
||||
if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
|
||||
{
|
||||
/* Switch down */
|
||||
if( psEncC->sLP.mode == 0 ) {
|
||||
/* New transition */
|
||||
psEncC->sLP.transition_frame_no = TRANSITION_FRAMES;
|
||||
|
||||
/* Reset transition filter state */
|
||||
silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
|
||||
}
|
||||
if( encControl->opusCanSwitch ) {
|
||||
/* Stop transition phase */
|
||||
psEncC->sLP.mode = 0;
|
||||
|
||||
/* Switch to a lower sample frequency */
|
||||
fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8;
|
||||
} else {
|
||||
if( psEncC->sLP.transition_frame_no <= 0 ) {
|
||||
encControl->switchReady = 1;
|
||||
/* Make room for redundancy */
|
||||
encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
|
||||
} else {
|
||||
/* Direction: down (at double speed) */
|
||||
psEncC->sLP.mode = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Check if we should switch up */
|
||||
if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
|
||||
{
|
||||
/* Switch up */
|
||||
if( encControl->opusCanSwitch ) {
|
||||
/* Switch to a higher sample frequency */
|
||||
fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16;
|
||||
|
||||
/* New transition */
|
||||
psEncC->sLP.transition_frame_no = 0;
|
||||
|
||||
/* Reset transition filter state */
|
||||
silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
|
||||
|
||||
/* Direction: up */
|
||||
psEncC->sLP.mode = 1;
|
||||
} else {
|
||||
if( psEncC->sLP.mode == 0 ) {
|
||||
encControl->switchReady = 1;
|
||||
/* Make room for redundancy */
|
||||
encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
|
||||
} else {
|
||||
/* Direction: up */
|
||||
psEncC->sLP.mode = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (psEncC->sLP.mode<0)
|
||||
psEncC->sLP.mode = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fs_kHz;
|
||||
}
|
428
node_modules/node-opus/deps/opus/silk/control_codec.c
generated
vendored
Normal file
428
node_modules/node-opus/deps/opus/silk/control_codec.c
generated
vendored
Normal file
@ -0,0 +1,428 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
#ifdef FIXED_POINT
|
||||
#include "main_FIX.h"
|
||||
#define silk_encoder_state_Fxx silk_encoder_state_FIX
|
||||
#else
|
||||
#include "main_FLP.h"
|
||||
#define silk_encoder_state_Fxx silk_encoder_state_FLP
|
||||
#endif
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "pitch_est_defines.h"
|
||||
|
||||
static opus_int silk_setup_resamplers(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O */
|
||||
opus_int fs_kHz /* I */
|
||||
);
|
||||
|
||||
static opus_int silk_setup_fs(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O */
|
||||
opus_int fs_kHz, /* I */
|
||||
opus_int PacketSize_ms /* I */
|
||||
);
|
||||
|
||||
static opus_int silk_setup_complexity(
|
||||
silk_encoder_state *psEncC, /* I/O */
|
||||
opus_int Complexity /* I */
|
||||
);
|
||||
|
||||
static OPUS_INLINE opus_int silk_setup_LBRR(
|
||||
silk_encoder_state *psEncC, /* I/O */
|
||||
const opus_int32 TargetRate_bps /* I */
|
||||
);
|
||||
|
||||
|
||||
/* Control encoder */
|
||||
opus_int silk_control_encoder(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
|
||||
silk_EncControlStruct *encControl, /* I Control structure */
|
||||
const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
|
||||
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
|
||||
const opus_int channelNb, /* I Channel number */
|
||||
const opus_int force_fs_kHz
|
||||
)
|
||||
{
|
||||
opus_int fs_kHz, ret = 0;
|
||||
|
||||
psEnc->sCmn.useDTX = encControl->useDTX;
|
||||
psEnc->sCmn.useCBR = encControl->useCBR;
|
||||
psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
|
||||
psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
|
||||
psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
|
||||
psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
|
||||
psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
|
||||
psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI;
|
||||
psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal;
|
||||
psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;
|
||||
psEnc->sCmn.channelNb = channelNb;
|
||||
|
||||
if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {
|
||||
if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
|
||||
/* Change in API sampling rate in the middle of encoding a packet */
|
||||
ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Beyond this point we know that there are no previously coded frames in the payload buffer */
|
||||
|
||||
/********************************************/
|
||||
/* Determine internal sampling rate */
|
||||
/********************************************/
|
||||
fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl );
|
||||
if( force_fs_kHz ) {
|
||||
fs_kHz = force_fs_kHz;
|
||||
}
|
||||
/********************************************/
|
||||
/* Prepare resampler and buffered data */
|
||||
/********************************************/
|
||||
ret += silk_setup_resamplers( psEnc, fs_kHz );
|
||||
|
||||
/********************************************/
|
||||
/* Set internal sampling frequency */
|
||||
/********************************************/
|
||||
ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms );
|
||||
|
||||
/********************************************/
|
||||
/* Set encoding complexity */
|
||||
/********************************************/
|
||||
ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity );
|
||||
|
||||
/********************************************/
|
||||
/* Set packet loss rate measured by farend */
|
||||
/********************************************/
|
||||
psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage;
|
||||
|
||||
/********************************************/
|
||||
/* Set LBRR usage */
|
||||
/********************************************/
|
||||
ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps );
|
||||
|
||||
psEnc->sCmn.controlled_since_last_payload = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static opus_int silk_setup_resamplers(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O */
|
||||
opus_int fs_kHz /* I */
|
||||
)
|
||||
{
|
||||
opus_int ret = SILK_NO_ERROR;
|
||||
SAVE_STACK;
|
||||
|
||||
if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )
|
||||
{
|
||||
if( psEnc->sCmn.fs_kHz == 0 ) {
|
||||
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
|
||||
} else {
|
||||
VARDECL( opus_int16, x_buf_API_fs_Hz );
|
||||
VARDECL( silk_resampler_state_struct, temp_resampler_state );
|
||||
#ifdef FIXED_POINT
|
||||
opus_int16 *x_bufFIX = psEnc->x_buf;
|
||||
#else
|
||||
VARDECL( opus_int16, x_bufFIX );
|
||||
opus_int32 new_buf_samples;
|
||||
#endif
|
||||
opus_int32 api_buf_samples;
|
||||
opus_int32 old_buf_samples;
|
||||
opus_int32 buf_length_ms;
|
||||
|
||||
buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS;
|
||||
old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz;
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
new_buf_samples = buf_length_ms * fs_kHz;
|
||||
ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ),
|
||||
opus_int16 );
|
||||
silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples );
|
||||
#endif
|
||||
|
||||
/* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
|
||||
ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );
|
||||
ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
|
||||
|
||||
/* Calculate number of samples to temporarily upsample */
|
||||
api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 );
|
||||
|
||||
/* Temporary resampling of x_buf data to API_fs_Hz */
|
||||
ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 );
|
||||
ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples );
|
||||
|
||||
/* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
|
||||
ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
|
||||
|
||||
/* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
|
||||
ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples );
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
|
||||
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static opus_int silk_setup_fs(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O */
|
||||
opus_int fs_kHz, /* I */
|
||||
opus_int PacketSize_ms /* I */
|
||||
)
|
||||
{
|
||||
opus_int ret = SILK_NO_ERROR;
|
||||
|
||||
/* Set packet size */
|
||||
if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
|
||||
if( ( PacketSize_ms != 10 ) &&
|
||||
( PacketSize_ms != 20 ) &&
|
||||
( PacketSize_ms != 40 ) &&
|
||||
( PacketSize_ms != 60 ) ) {
|
||||
ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
|
||||
}
|
||||
if( PacketSize_ms <= 10 ) {
|
||||
psEnc->sCmn.nFramesPerPacket = 1;
|
||||
psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;
|
||||
psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz );
|
||||
psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
|
||||
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
|
||||
} else {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
|
||||
}
|
||||
} else {
|
||||
psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );
|
||||
psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;
|
||||
psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz );
|
||||
psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
|
||||
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
|
||||
} else {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
|
||||
}
|
||||
}
|
||||
psEnc->sCmn.PacketSize_ms = PacketSize_ms;
|
||||
psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
|
||||
}
|
||||
|
||||
/* Set internal sampling frequency */
|
||||
silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
|
||||
silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
|
||||
if( psEnc->sCmn.fs_kHz != fs_kHz ) {
|
||||
/* reset part of the state */
|
||||
silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) );
|
||||
silk_memset( &psEnc->sPrefilt, 0, sizeof( psEnc->sPrefilt ) );
|
||||
silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) );
|
||||
silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
|
||||
silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
|
||||
psEnc->sCmn.inputBufIx = 0;
|
||||
psEnc->sCmn.nFramesEncoded = 0;
|
||||
psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
|
||||
|
||||
/* Initialize non-zero parameters */
|
||||
psEnc->sCmn.prevLag = 100;
|
||||
psEnc->sCmn.first_frame_after_reset = 1;
|
||||
psEnc->sPrefilt.lagPrev = 100;
|
||||
psEnc->sShape.LastGainIndex = 10;
|
||||
psEnc->sCmn.sNSQ.lagPrev = 100;
|
||||
psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536;
|
||||
psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
|
||||
psEnc->sCmn.fs_kHz = fs_kHz;
|
||||
if( psEnc->sCmn.fs_kHz == 8 ) {
|
||||
if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
|
||||
} else {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
|
||||
}
|
||||
} else {
|
||||
if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
|
||||
} else {
|
||||
psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
|
||||
}
|
||||
}
|
||||
if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {
|
||||
psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
|
||||
psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB;
|
||||
} else {
|
||||
psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
|
||||
psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB;
|
||||
}
|
||||
psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz;
|
||||
psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
|
||||
psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );
|
||||
psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz );
|
||||
psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz );
|
||||
if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
|
||||
psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
|
||||
} else {
|
||||
psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
|
||||
}
|
||||
if( psEnc->sCmn.fs_kHz == 16 ) {
|
||||
psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 );
|
||||
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
|
||||
} else if( psEnc->sCmn.fs_kHz == 12 ) {
|
||||
psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 );
|
||||
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
|
||||
} else {
|
||||
psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 );
|
||||
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that settings are valid */
|
||||
silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static opus_int silk_setup_complexity(
|
||||
silk_encoder_state *psEncC, /* I/O */
|
||||
opus_int Complexity /* I */
|
||||
)
|
||||
{
|
||||
opus_int ret = 0;
|
||||
|
||||
/* Set encoding complexity */
|
||||
silk_assert( Complexity >= 0 && Complexity <= 10 );
|
||||
if( Complexity < 2 ) {
|
||||
psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
|
||||
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
|
||||
psEncC->pitchEstimationLPCOrder = 6;
|
||||
psEncC->shapingLPCOrder = 8;
|
||||
psEncC->la_shape = 3 * psEncC->fs_kHz;
|
||||
psEncC->nStatesDelayedDecision = 1;
|
||||
psEncC->useInterpolatedNLSFs = 0;
|
||||
psEncC->LTPQuantLowComplexity = 1;
|
||||
psEncC->NLSF_MSVQ_Survivors = 2;
|
||||
psEncC->warping_Q16 = 0;
|
||||
} else if( Complexity < 4 ) {
|
||||
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
|
||||
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
|
||||
psEncC->pitchEstimationLPCOrder = 8;
|
||||
psEncC->shapingLPCOrder = 10;
|
||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||
psEncC->nStatesDelayedDecision = 1;
|
||||
psEncC->useInterpolatedNLSFs = 0;
|
||||
psEncC->LTPQuantLowComplexity = 0;
|
||||
psEncC->NLSF_MSVQ_Survivors = 4;
|
||||
psEncC->warping_Q16 = 0;
|
||||
} else if( Complexity < 6 ) {
|
||||
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
|
||||
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 );
|
||||
psEncC->pitchEstimationLPCOrder = 10;
|
||||
psEncC->shapingLPCOrder = 12;
|
||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||
psEncC->nStatesDelayedDecision = 2;
|
||||
psEncC->useInterpolatedNLSFs = 1;
|
||||
psEncC->LTPQuantLowComplexity = 0;
|
||||
psEncC->NLSF_MSVQ_Survivors = 8;
|
||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||
} else if( Complexity < 8 ) {
|
||||
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
|
||||
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 );
|
||||
psEncC->pitchEstimationLPCOrder = 12;
|
||||
psEncC->shapingLPCOrder = 14;
|
||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||
psEncC->nStatesDelayedDecision = 3;
|
||||
psEncC->useInterpolatedNLSFs = 1;
|
||||
psEncC->LTPQuantLowComplexity = 0;
|
||||
psEncC->NLSF_MSVQ_Survivors = 16;
|
||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||
} else {
|
||||
psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
|
||||
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 );
|
||||
psEncC->pitchEstimationLPCOrder = 16;
|
||||
psEncC->shapingLPCOrder = 16;
|
||||
psEncC->la_shape = 5 * psEncC->fs_kHz;
|
||||
psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
|
||||
psEncC->useInterpolatedNLSFs = 1;
|
||||
psEncC->LTPQuantLowComplexity = 0;
|
||||
psEncC->NLSF_MSVQ_Survivors = 32;
|
||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||
}
|
||||
|
||||
/* Do not allow higher pitch estimation LPC order than predict LPC order */
|
||||
psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
|
||||
psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
|
||||
psEncC->Complexity = Complexity;
|
||||
|
||||
silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
|
||||
silk_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
|
||||
silk_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
|
||||
silk_assert( psEncC->warping_Q16 <= 32767 );
|
||||
silk_assert( psEncC->la_shape <= LA_SHAPE_MAX );
|
||||
silk_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
|
||||
silk_assert( psEncC->NLSF_MSVQ_Survivors <= NLSF_VQ_MAX_SURVIVORS );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OPUS_INLINE opus_int silk_setup_LBRR(
|
||||
silk_encoder_state *psEncC, /* I/O */
|
||||
const opus_int32 TargetRate_bps /* I */
|
||||
)
|
||||
{
|
||||
opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR;
|
||||
opus_int32 LBRR_rate_thres_bps;
|
||||
|
||||
LBRR_in_previous_packet = psEncC->LBRR_enabled;
|
||||
psEncC->LBRR_enabled = 0;
|
||||
if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) {
|
||||
if( psEncC->fs_kHz == 8 ) {
|
||||
LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS;
|
||||
} else if( psEncC->fs_kHz == 12 ) {
|
||||
LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS;
|
||||
} else {
|
||||
LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS;
|
||||
}
|
||||
LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
|
||||
|
||||
if( TargetRate_bps > LBRR_rate_thres_bps ) {
|
||||
/* Set gain increase for coding LBRR excitation */
|
||||
if( LBRR_in_previous_packet == 0 ) {
|
||||
/* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
|
||||
psEncC->LBRR_GainIncreases = 7;
|
||||
} else {
|
||||
psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
|
||||
}
|
||||
psEncC->LBRR_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
170
node_modules/node-opus/deps/opus/silk/debug.c
generated
vendored
Normal file
170
node_modules/node-opus/deps/opus/silk/debug.c
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "debug.h"
|
||||
#include "SigProc_FIX.h"
|
||||
|
||||
#if SILK_TIC_TOC
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#if (defined(_WIN32) || defined(_WINCE))
|
||||
#include <windows.h> /* timer */
|
||||
#else /* Linux or Mac*/
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/
|
||||
{
|
||||
/* Returns a time counter in microsec */
|
||||
/* the resolution is platform dependent */
|
||||
/* but is typically 1.62 us resolution */
|
||||
LARGE_INTEGER lpPerformanceCount;
|
||||
LARGE_INTEGER lpFrequency;
|
||||
QueryPerformanceCounter(&lpPerformanceCount);
|
||||
QueryPerformanceFrequency(&lpFrequency);
|
||||
return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
|
||||
}
|
||||
#else /* Linux or Mac*/
|
||||
unsigned long GetHighResolutionTime(void) /* O time in usec*/
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
return((tv.tv_sec*1000000)+(tv.tv_usec));
|
||||
}
|
||||
#endif
|
||||
|
||||
int silk_Timer_nTimers = 0;
|
||||
int silk_Timer_depth_ctr = 0;
|
||||
char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
|
||||
#ifdef WIN32
|
||||
LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
|
||||
#else
|
||||
unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
|
||||
#endif
|
||||
unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
|
||||
opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
|
||||
opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
|
||||
opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
|
||||
opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
|
||||
|
||||
#ifdef WIN32
|
||||
void silk_TimerSave(char *file_name)
|
||||
{
|
||||
if( silk_Timer_nTimers > 0 )
|
||||
{
|
||||
int k;
|
||||
FILE *fp;
|
||||
LARGE_INTEGER lpFrequency;
|
||||
LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2;
|
||||
int del = 0x7FFFFFFF;
|
||||
double avg, sum_avg;
|
||||
/* estimate overhead of calling performance counters */
|
||||
for( k = 0; k < 1000; k++ ) {
|
||||
QueryPerformanceCounter(&lpPerformanceCount1);
|
||||
QueryPerformanceCounter(&lpPerformanceCount2);
|
||||
lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart;
|
||||
if( (int)lpPerformanceCount2.LowPart < del )
|
||||
del = lpPerformanceCount2.LowPart;
|
||||
}
|
||||
QueryPerformanceFrequency(&lpFrequency);
|
||||
/* print results to file */
|
||||
sum_avg = 0.0f;
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) {
|
||||
if (silk_Timer_depth[k] == 0) {
|
||||
sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k];
|
||||
}
|
||||
}
|
||||
fp = fopen(file_name, "w");
|
||||
fprintf(fp, " min avg %% max count\n");
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) {
|
||||
if (silk_Timer_depth[k] == 0) {
|
||||
fprintf(fp, "%-28s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 1) {
|
||||
fprintf(fp, " %-27s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 2) {
|
||||
fprintf(fp, " %-26s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 3) {
|
||||
fprintf(fp, " %-25s", silk_Timer_tags[k]);
|
||||
} else {
|
||||
fprintf(fp, " %-24s", silk_Timer_tags[k]);
|
||||
}
|
||||
avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart;
|
||||
fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart);
|
||||
fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]);
|
||||
fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart);
|
||||
fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
|
||||
}
|
||||
fprintf(fp, " microseconds\n");
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void silk_TimerSave(char *file_name)
|
||||
{
|
||||
if( silk_Timer_nTimers > 0 )
|
||||
{
|
||||
int k;
|
||||
FILE *fp;
|
||||
/* print results to file */
|
||||
fp = fopen(file_name, "w");
|
||||
fprintf(fp, " min avg max count\n");
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ )
|
||||
{
|
||||
if (silk_Timer_depth[k] == 0) {
|
||||
fprintf(fp, "%-28s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 1) {
|
||||
fprintf(fp, " %-27s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 2) {
|
||||
fprintf(fp, " %-26s", silk_Timer_tags[k]);
|
||||
} else if (silk_Timer_depth[k] == 3) {
|
||||
fprintf(fp, " %-25s", silk_Timer_tags[k]);
|
||||
} else {
|
||||
fprintf(fp, " %-24s", silk_Timer_tags[k]);
|
||||
}
|
||||
fprintf(fp, "%d ", silk_Timer_min[k]);
|
||||
fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]);
|
||||
fprintf(fp, "%d ", silk_Timer_max[k]);
|
||||
fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
|
||||
}
|
||||
fprintf(fp, " microseconds\n");
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SILK_TIC_TOC */
|
||||
|
||||
#if SILK_DEBUG
|
||||
FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
|
||||
int silk_debug_store_count = 0;
|
||||
#endif /* SILK_DEBUG */
|
||||
|
279
node_modules/node-opus/deps/opus/silk/debug.h
generated
vendored
Normal file
279
node_modules/node-opus/deps/opus/silk/debug.h
generated
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_DEBUG_H
|
||||
#define SILK_DEBUG_H
|
||||
|
||||
#include "typedef.h"
|
||||
#include <stdio.h> /* file writing */
|
||||
#include <string.h> /* strcpy, strcmp */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
unsigned long GetHighResolutionTime(void); /* O time in usec*/
|
||||
|
||||
/* make SILK_DEBUG dependent on compiler's _DEBUG */
|
||||
#if defined _WIN32
|
||||
#ifdef _DEBUG
|
||||
#define SILK_DEBUG 1
|
||||
#else
|
||||
#define SILK_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* overrule the above */
|
||||
#if 0
|
||||
/* #define NO_ASSERTS*/
|
||||
#undef SILK_DEBUG
|
||||
#define SILK_DEBUG 1
|
||||
#endif
|
||||
#else
|
||||
#define SILK_DEBUG 0
|
||||
#endif
|
||||
|
||||
/* Flag for using timers */
|
||||
#define SILK_TIC_TOC 0
|
||||
|
||||
|
||||
#if SILK_TIC_TOC
|
||||
|
||||
#if (defined(_WIN32) || defined(_WINCE))
|
||||
#include <windows.h> /* timer */
|
||||
#else /* Linux or Mac*/
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/*********************************/
|
||||
/* timer functions for profiling */
|
||||
/*********************************/
|
||||
/* example: */
|
||||
/* */
|
||||
/* TIC(LPC) */
|
||||
/* do_LPC(in_vec, order, acoef); // do LPC analysis */
|
||||
/* TOC(LPC) */
|
||||
/* */
|
||||
/* and call the following just before exiting (from main) */
|
||||
/* */
|
||||
/* silk_TimerSave("silk_TimingData.txt"); */
|
||||
/* */
|
||||
/* results are now in silk_TimingData.txt */
|
||||
|
||||
void silk_TimerSave(char *file_name);
|
||||
|
||||
/* max number of timers (in different locations) */
|
||||
#define silk_NUM_TIMERS_MAX 50
|
||||
/* max length of name tags in TIC(..), TOC(..) */
|
||||
#define silk_NUM_TIMERS_MAX_TAG_LEN 30
|
||||
|
||||
extern int silk_Timer_nTimers;
|
||||
extern int silk_Timer_depth_ctr;
|
||||
extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
|
||||
#ifdef _WIN32
|
||||
extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
|
||||
#else
|
||||
extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
|
||||
#endif
|
||||
extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
|
||||
extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
|
||||
extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
|
||||
extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
|
||||
extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
|
||||
|
||||
/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */
|
||||
#ifdef _WIN32
|
||||
#define TIC(TAG_NAME) { \
|
||||
static int init = 0; \
|
||||
static int ID = -1; \
|
||||
if( init == 0 ) \
|
||||
{ \
|
||||
int k; \
|
||||
init = 1; \
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) { \
|
||||
if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
|
||||
ID = k; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (ID == -1) { \
|
||||
ID = silk_Timer_nTimers; \
|
||||
silk_Timer_nTimers++; \
|
||||
silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
|
||||
strcpy(silk_Timer_tags[ID], #TAG_NAME); \
|
||||
silk_Timer_cnt[ID] = 0; \
|
||||
silk_Timer_sum[ID] = 0; \
|
||||
silk_Timer_min[ID] = 0xFFFFFFFF; \
|
||||
silk_Timer_max[ID] = 0; \
|
||||
} \
|
||||
} \
|
||||
silk_Timer_depth_ctr++; \
|
||||
QueryPerformanceCounter(&silk_Timer_start[ID]); \
|
||||
}
|
||||
#else
|
||||
#define TIC(TAG_NAME) { \
|
||||
static int init = 0; \
|
||||
static int ID = -1; \
|
||||
if( init == 0 ) \
|
||||
{ \
|
||||
int k; \
|
||||
init = 1; \
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) { \
|
||||
if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
|
||||
ID = k; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (ID == -1) { \
|
||||
ID = silk_Timer_nTimers; \
|
||||
silk_Timer_nTimers++; \
|
||||
silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
|
||||
strcpy(silk_Timer_tags[ID], #TAG_NAME); \
|
||||
silk_Timer_cnt[ID] = 0; \
|
||||
silk_Timer_sum[ID] = 0; \
|
||||
silk_Timer_min[ID] = 0xFFFFFFFF; \
|
||||
silk_Timer_max[ID] = 0; \
|
||||
} \
|
||||
} \
|
||||
silk_Timer_depth_ctr++; \
|
||||
silk_Timer_start[ID] = GetHighResolutionTime(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define TOC(TAG_NAME) { \
|
||||
LARGE_INTEGER lpPerformanceCount; \
|
||||
static int init = 0; \
|
||||
static int ID = 0; \
|
||||
if( init == 0 ) \
|
||||
{ \
|
||||
int k; \
|
||||
init = 1; \
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) { \
|
||||
if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
|
||||
ID = k; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
QueryPerformanceCounter(&lpPerformanceCount); \
|
||||
lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \
|
||||
if((lpPerformanceCount.QuadPart < 100000000) && \
|
||||
(lpPerformanceCount.QuadPart >= 0)) { \
|
||||
silk_Timer_cnt[ID]++; \
|
||||
silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \
|
||||
if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \
|
||||
silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \
|
||||
if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \
|
||||
silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \
|
||||
} \
|
||||
silk_Timer_depth_ctr--; \
|
||||
}
|
||||
#else
|
||||
#define TOC(TAG_NAME) { \
|
||||
unsigned long endTime; \
|
||||
static int init = 0; \
|
||||
static int ID = 0; \
|
||||
if( init == 0 ) \
|
||||
{ \
|
||||
int k; \
|
||||
init = 1; \
|
||||
for( k = 0; k < silk_Timer_nTimers; k++ ) { \
|
||||
if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
|
||||
ID = k; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
endTime = GetHighResolutionTime(); \
|
||||
endTime -= silk_Timer_start[ID]; \
|
||||
if((endTime < 100000000) && \
|
||||
(endTime >= 0)) { \
|
||||
silk_Timer_cnt[ID]++; \
|
||||
silk_Timer_sum[ID] += endTime; \
|
||||
if( endTime > silk_Timer_max[ID] ) \
|
||||
silk_Timer_max[ID] = endTime; \
|
||||
if( endTime < silk_Timer_min[ID] ) \
|
||||
silk_Timer_min[ID] = endTime; \
|
||||
} \
|
||||
silk_Timer_depth_ctr--; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* SILK_TIC_TOC */
|
||||
|
||||
/* define macros as empty strings */
|
||||
#define TIC(TAG_NAME)
|
||||
#define TOC(TAG_NAME)
|
||||
#define silk_TimerSave(FILE_NAME)
|
||||
|
||||
#endif /* SILK_TIC_TOC */
|
||||
|
||||
|
||||
#if SILK_DEBUG
|
||||
/************************************/
|
||||
/* write data to file for debugging */
|
||||
/************************************/
|
||||
/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */
|
||||
|
||||
#define silk_NUM_STORES_MAX 100
|
||||
extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
|
||||
extern int silk_debug_store_count;
|
||||
|
||||
/* Faster way of storing the data */
|
||||
#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \
|
||||
static opus_int init = 0, cnt = 0; \
|
||||
static FILE **fp; \
|
||||
if (init == 0) { \
|
||||
init = 1; \
|
||||
cnt = silk_debug_store_count++; \
|
||||
silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \
|
||||
} \
|
||||
fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \
|
||||
}
|
||||
|
||||
/* Call this at the end of main() */
|
||||
#define SILK_DEBUG_STORE_CLOSE_FILES { \
|
||||
opus_int i; \
|
||||
for( i = 0; i < silk_debug_store_count; i++ ) { \
|
||||
fclose( silk_debug_store_fp[ i ] ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else /* SILK_DEBUG */
|
||||
|
||||
/* define macros as empty strings */
|
||||
#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES)
|
||||
#define SILK_DEBUG_STORE_CLOSE_FILES
|
||||
|
||||
#endif /* SILK_DEBUG */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SILK_DEBUG_H */
|
419
node_modules/node-opus/deps/opus/silk/dec_API.c
generated
vendored
Normal file
419
node_modules/node-opus/deps/opus/silk/dec_API.c
generated
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "API.h"
|
||||
#include "main.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/************************/
|
||||
/* Decoder Super Struct */
|
||||
/************************/
|
||||
typedef struct {
|
||||
silk_decoder_state channel_state[ DECODER_NUM_CHANNELS ];
|
||||
stereo_dec_state sStereo;
|
||||
opus_int nChannelsAPI;
|
||||
opus_int nChannelsInternal;
|
||||
opus_int prev_decode_only_middle;
|
||||
} silk_decoder;
|
||||
|
||||
/*********************/
|
||||
/* Decoder functions */
|
||||
/*********************/
|
||||
|
||||
opus_int silk_Get_Decoder_Size( /* O Returns error code */
|
||||
opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */
|
||||
)
|
||||
{
|
||||
opus_int ret = SILK_NO_ERROR;
|
||||
|
||||
*decSizeBytes = sizeof( silk_decoder );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reset decoder state */
|
||||
opus_int silk_InitDecoder( /* O Returns error code */
|
||||
void *decState /* I/O State */
|
||||
)
|
||||
{
|
||||
opus_int n, ret = SILK_NO_ERROR;
|
||||
silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state;
|
||||
|
||||
for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
|
||||
ret = silk_init_decoder( &channel_state[ n ] );
|
||||
}
|
||||
silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo));
|
||||
/* Not strictly needed, but it's cleaner that way */
|
||||
((silk_decoder *)decState)->prev_decode_only_middle = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Decode a frame */
|
||||
opus_int silk_Decode( /* O Returns error code */
|
||||
void* decState, /* I/O State */
|
||||
silk_DecControlStruct* decControl, /* I/O Control Structure */
|
||||
opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
|
||||
opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int16 *samplesOut, /* O Decoded output speech vector */
|
||||
opus_int32 *nSamplesOut, /* O Number of samples decoded */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
|
||||
opus_int32 nSamplesOutDec, LBRR_symbol;
|
||||
opus_int16 *samplesOut1_tmp[ 2 ];
|
||||
VARDECL( opus_int16, samplesOut1_tmp_storage1 );
|
||||
VARDECL( opus_int16, samplesOut1_tmp_storage2 );
|
||||
VARDECL( opus_int16, samplesOut2_tmp );
|
||||
opus_int32 MS_pred_Q13[ 2 ] = { 0 };
|
||||
opus_int16 *resample_out_ptr;
|
||||
silk_decoder *psDec = ( silk_decoder * )decState;
|
||||
silk_decoder_state *channel_state = psDec->channel_state;
|
||||
opus_int has_side;
|
||||
opus_int stereo_to_mono;
|
||||
int delay_stack_alloc;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
|
||||
|
||||
/**********************************/
|
||||
/* Test if first frame in payload */
|
||||
/**********************************/
|
||||
if( newPacketFlag ) {
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
channel_state[ n ].nFramesDecoded = 0; /* Used to count frames in packet */
|
||||
}
|
||||
}
|
||||
|
||||
/* If Mono -> Stereo transition in bitstream: init state of second channel */
|
||||
if( decControl->nChannelsInternal > psDec->nChannelsInternal ) {
|
||||
ret += silk_init_decoder( &channel_state[ 1 ] );
|
||||
}
|
||||
|
||||
stereo_to_mono = decControl->nChannelsInternal == 1 && psDec->nChannelsInternal == 2 &&
|
||||
( decControl->internalSampleRate == 1000*channel_state[ 0 ].fs_kHz );
|
||||
|
||||
if( channel_state[ 0 ].nFramesDecoded == 0 ) {
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
opus_int fs_kHz_dec;
|
||||
if( decControl->payloadSize_ms == 0 ) {
|
||||
/* Assuming packet loss, use 10 ms */
|
||||
channel_state[ n ].nFramesPerPacket = 1;
|
||||
channel_state[ n ].nb_subfr = 2;
|
||||
} else if( decControl->payloadSize_ms == 10 ) {
|
||||
channel_state[ n ].nFramesPerPacket = 1;
|
||||
channel_state[ n ].nb_subfr = 2;
|
||||
} else if( decControl->payloadSize_ms == 20 ) {
|
||||
channel_state[ n ].nFramesPerPacket = 1;
|
||||
channel_state[ n ].nb_subfr = 4;
|
||||
} else if( decControl->payloadSize_ms == 40 ) {
|
||||
channel_state[ n ].nFramesPerPacket = 2;
|
||||
channel_state[ n ].nb_subfr = 4;
|
||||
} else if( decControl->payloadSize_ms == 60 ) {
|
||||
channel_state[ n ].nFramesPerPacket = 3;
|
||||
channel_state[ n ].nb_subfr = 4;
|
||||
} else {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return SILK_DEC_INVALID_FRAME_SIZE;
|
||||
}
|
||||
fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
|
||||
if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
|
||||
}
|
||||
ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate );
|
||||
}
|
||||
}
|
||||
|
||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) {
|
||||
silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) );
|
||||
silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) );
|
||||
silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) );
|
||||
}
|
||||
psDec->nChannelsAPI = decControl->nChannelsAPI;
|
||||
psDec->nChannelsInternal = decControl->nChannelsInternal;
|
||||
|
||||
if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) {
|
||||
ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY;
|
||||
RESTORE_STACK;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) {
|
||||
/* First decoder call for this payload */
|
||||
/* Decode VAD flags and LBRR flag */
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {
|
||||
channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1);
|
||||
}
|
||||
channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1);
|
||||
}
|
||||
/* Decode LBRR flags */
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) );
|
||||
if( channel_state[ n ].LBRR_flag ) {
|
||||
if( channel_state[ n ].nFramesPerPacket == 1 ) {
|
||||
channel_state[ n ].LBRR_flags[ 0 ] = 1;
|
||||
} else {
|
||||
LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1;
|
||||
for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {
|
||||
channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( lostFlag == FLAG_DECODE_NORMAL ) {
|
||||
/* Regular decoding: skip all LBRR data */
|
||||
for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) {
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
if( channel_state[ n ].LBRR_flags[ i ] ) {
|
||||
opus_int16 pulses[ MAX_FRAME_LENGTH ];
|
||||
opus_int condCoding;
|
||||
|
||||
if( decControl->nChannelsInternal == 2 && n == 0 ) {
|
||||
silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );
|
||||
if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) {
|
||||
silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );
|
||||
}
|
||||
}
|
||||
/* Use conditional coding if previous frame available */
|
||||
if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) {
|
||||
condCoding = CODE_CONDITIONALLY;
|
||||
} else {
|
||||
condCoding = CODE_INDEPENDENTLY;
|
||||
}
|
||||
silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding );
|
||||
silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType,
|
||||
channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get MS predictor index */
|
||||
if( decControl->nChannelsInternal == 2 ) {
|
||||
if( lostFlag == FLAG_DECODE_NORMAL ||
|
||||
( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) )
|
||||
{
|
||||
silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );
|
||||
/* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */
|
||||
if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ||
|
||||
( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) )
|
||||
{
|
||||
silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );
|
||||
} else {
|
||||
decode_only_middle = 0;
|
||||
}
|
||||
} else {
|
||||
for( n = 0; n < 2; n++ ) {
|
||||
MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset side channel decoder prediction memory for first frame with side coding */
|
||||
if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) {
|
||||
silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) );
|
||||
silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) );
|
||||
psDec->channel_state[ 1 ].lagPrev = 100;
|
||||
psDec->channel_state[ 1 ].LastGainIndex = 10;
|
||||
psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
psDec->channel_state[ 1 ].first_frame_after_reset = 1;
|
||||
}
|
||||
|
||||
/* Check if the temp buffer fits into the output PCM buffer. If it fits,
|
||||
we can delay allocating the temp buffer until after the SILK peak stack
|
||||
usage. We need to use a < and not a <= because of the two extra samples. */
|
||||
delay_stack_alloc = decControl->internalSampleRate*decControl->nChannelsInternal
|
||||
< decControl->API_sampleRate*decControl->nChannelsAPI;
|
||||
ALLOC( samplesOut1_tmp_storage1, delay_stack_alloc ? ALLOC_NONE
|
||||
: decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 ),
|
||||
opus_int16 );
|
||||
if ( delay_stack_alloc )
|
||||
{
|
||||
samplesOut1_tmp[ 0 ] = samplesOut;
|
||||
samplesOut1_tmp[ 1 ] = samplesOut + channel_state[ 0 ].frame_length + 2;
|
||||
} else {
|
||||
samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage1;
|
||||
samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage1 + channel_state[ 0 ].frame_length + 2;
|
||||
}
|
||||
|
||||
if( lostFlag == FLAG_DECODE_NORMAL ) {
|
||||
has_side = !decode_only_middle;
|
||||
} else {
|
||||
has_side = !psDec->prev_decode_only_middle
|
||||
|| (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 );
|
||||
}
|
||||
/* Call decoder for one frame */
|
||||
for( n = 0; n < decControl->nChannelsInternal; n++ ) {
|
||||
if( n == 0 || has_side ) {
|
||||
opus_int FrameIndex;
|
||||
opus_int condCoding;
|
||||
|
||||
FrameIndex = channel_state[ 0 ].nFramesDecoded - n;
|
||||
/* Use independent coding if no previous frame available */
|
||||
if( FrameIndex <= 0 ) {
|
||||
condCoding = CODE_INDEPENDENTLY;
|
||||
} else if( lostFlag == FLAG_DECODE_LBRR ) {
|
||||
condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY;
|
||||
} else if( n > 0 && psDec->prev_decode_only_middle ) {
|
||||
/* If we skipped a side frame in this packet, we don't
|
||||
need LTP scaling; the LTP state is well-defined. */
|
||||
condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
|
||||
} else {
|
||||
condCoding = CODE_CONDITIONALLY;
|
||||
}
|
||||
ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch);
|
||||
} else {
|
||||
silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
|
||||
}
|
||||
channel_state[ n ].nFramesDecoded++;
|
||||
}
|
||||
|
||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
|
||||
/* Convert Mid/Side to Left/Right */
|
||||
silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec );
|
||||
} else {
|
||||
/* Buffering */
|
||||
silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) );
|
||||
silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) );
|
||||
}
|
||||
|
||||
/* Number of output samples */
|
||||
*nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );
|
||||
|
||||
/* Set up pointers to temp buffers */
|
||||
ALLOC( samplesOut2_tmp,
|
||||
decControl->nChannelsAPI == 2 ? *nSamplesOut : ALLOC_NONE, opus_int16 );
|
||||
if( decControl->nChannelsAPI == 2 ) {
|
||||
resample_out_ptr = samplesOut2_tmp;
|
||||
} else {
|
||||
resample_out_ptr = samplesOut;
|
||||
}
|
||||
|
||||
ALLOC( samplesOut1_tmp_storage2, delay_stack_alloc
|
||||
? decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2 )
|
||||
: ALLOC_NONE,
|
||||
opus_int16 );
|
||||
if ( delay_stack_alloc ) {
|
||||
OPUS_COPY(samplesOut1_tmp_storage2, samplesOut, decControl->nChannelsInternal*(channel_state[ 0 ].frame_length + 2));
|
||||
samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage2;
|
||||
samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage2 + channel_state[ 0 ].frame_length + 2;
|
||||
}
|
||||
for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {
|
||||
|
||||
/* Resample decoded signal to API_sampleRate */
|
||||
ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec );
|
||||
|
||||
/* Interleave if stereo output and stereo stream */
|
||||
if( decControl->nChannelsAPI == 2 ) {
|
||||
for( i = 0; i < *nSamplesOut; i++ ) {
|
||||
samplesOut[ n + 2 * i ] = resample_out_ptr[ i ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create two channel output from mono stream */
|
||||
if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) {
|
||||
if ( stereo_to_mono ){
|
||||
/* Resample right channel for newly collapsed stereo just in case
|
||||
we weren't doing collapsing when switching to mono */
|
||||
ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec );
|
||||
|
||||
for( i = 0; i < *nSamplesOut; i++ ) {
|
||||
samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ];
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < *nSamplesOut; i++ ) {
|
||||
samplesOut[ 1 + 2 * i ] = samplesOut[ 0 + 2 * i ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Export pitch lag, measured at 48 kHz sampling rate */
|
||||
if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) {
|
||||
int mult_tab[ 3 ] = { 6, 4, 3 };
|
||||
decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ];
|
||||
} else {
|
||||
decControl->prevPitchLag = 0;
|
||||
}
|
||||
|
||||
if( lostFlag == FLAG_PACKET_LOST ) {
|
||||
/* On packet loss, remove the gain clamping to prevent having the energy "bounce back"
|
||||
if we lose packets when the energy is going down */
|
||||
for ( i = 0; i < psDec->nChannelsInternal; i++ )
|
||||
psDec->channel_state[ i ].LastGainIndex = 10;
|
||||
} else {
|
||||
psDec->prev_decode_only_middle = decode_only_middle;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Getting table of contents for a packet */
|
||||
opus_int silk_get_TOC(
|
||||
const opus_uint8 *payload, /* I Payload data */
|
||||
const opus_int nBytesIn, /* I Number of input bytes */
|
||||
const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */
|
||||
silk_TOC_struct *Silk_TOC /* O Type of content */
|
||||
)
|
||||
{
|
||||
opus_int i, flags, ret = SILK_NO_ERROR;
|
||||
|
||||
if( nBytesIn < 1 ) {
|
||||
return -1;
|
||||
}
|
||||
if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) );
|
||||
|
||||
/* For stereo, extract the flags for the mid channel */
|
||||
flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 );
|
||||
|
||||
Silk_TOC->inbandFECFlag = flags & 1;
|
||||
for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) {
|
||||
flags = silk_RSHIFT( flags, 1 );
|
||||
Silk_TOC->VADFlags[ i ] = flags & 1;
|
||||
Silk_TOC->VADFlag |= flags & 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
239
node_modules/node-opus/deps/opus/silk/decode_core.c
generated
vendored
Normal file
239
node_modules/node-opus/deps/opus/silk/decode_core.c
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/**********************************************************/
|
||||
/* Core decoder. Performs inverse NSQ operation LTP + LPC */
|
||||
/**********************************************************/
|
||||
void silk_decode_core(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state */
|
||||
silk_decoder_control *psDecCtrl, /* I Decoder control */
|
||||
opus_int16 xq[], /* O Decoded speech */
|
||||
const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
|
||||
opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
|
||||
VARDECL( opus_int16, sLTP );
|
||||
VARDECL( opus_int32, sLTP_Q15 );
|
||||
opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;
|
||||
opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14;
|
||||
VARDECL( opus_int32, res_Q14 );
|
||||
VARDECL( opus_int32, sLPC_Q14 );
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( psDec->prev_gain_Q16 != 0 );
|
||||
|
||||
ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
|
||||
ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
|
||||
ALLOC( res_Q14, psDec->subfr_length, opus_int32 );
|
||||
ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 );
|
||||
|
||||
offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ];
|
||||
|
||||
if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) {
|
||||
NLSF_interpolation_flag = 1;
|
||||
} else {
|
||||
NLSF_interpolation_flag = 0;
|
||||
}
|
||||
|
||||
/* Decode excitation */
|
||||
rand_seed = psDec->indices.Seed;
|
||||
for( i = 0; i < psDec->frame_length; i++ ) {
|
||||
rand_seed = silk_RAND( rand_seed );
|
||||
psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 );
|
||||
if( psDec->exc_Q14[ i ] > 0 ) {
|
||||
psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4;
|
||||
} else
|
||||
if( psDec->exc_Q14[ i ] < 0 ) {
|
||||
psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4;
|
||||
}
|
||||
psDec->exc_Q14[ i ] += offset_Q10 << 4;
|
||||
if( rand_seed < 0 ) {
|
||||
psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ];
|
||||
}
|
||||
|
||||
rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] );
|
||||
}
|
||||
|
||||
/* Copy LPC state */
|
||||
silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
|
||||
pexc_Q14 = psDec->exc_Q14;
|
||||
pxq = xq;
|
||||
sLTP_buf_idx = psDec->ltp_mem_length;
|
||||
/* Loop over subframes */
|
||||
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
||||
pres_Q14 = res_Q14;
|
||||
A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ];
|
||||
|
||||
/* Preload LPC coeficients to array on stack. Gives small performance gain */
|
||||
silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) );
|
||||
B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ];
|
||||
signalType = psDec->indices.signalType;
|
||||
|
||||
Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 );
|
||||
inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 );
|
||||
|
||||
/* Calculate gain adjustment factor */
|
||||
if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) {
|
||||
gain_adj_Q16 = silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 );
|
||||
|
||||
/* Scale short term state */
|
||||
for( i = 0; i < MAX_LPC_ORDER; i++ ) {
|
||||
sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] );
|
||||
}
|
||||
} else {
|
||||
gain_adj_Q16 = (opus_int32)1 << 16;
|
||||
}
|
||||
|
||||
/* Save inv_gain */
|
||||
silk_assert( inv_gain_Q31 != 0 );
|
||||
psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ];
|
||||
|
||||
/* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */
|
||||
if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED &&
|
||||
psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) {
|
||||
|
||||
silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) );
|
||||
B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 );
|
||||
|
||||
signalType = TYPE_VOICED;
|
||||
psDecCtrl->pitchL[ k ] = psDec->lagPrev;
|
||||
}
|
||||
|
||||
if( signalType == TYPE_VOICED ) {
|
||||
/* Voiced */
|
||||
lag = psDecCtrl->pitchL[ k ];
|
||||
|
||||
/* Re-whitening */
|
||||
if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
|
||||
/* Rewhiten with new A coefs */
|
||||
start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
|
||||
silk_assert( start_idx > 0 );
|
||||
|
||||
if( k == 2 ) {
|
||||
silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
|
||||
}
|
||||
|
||||
silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ],
|
||||
A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch );
|
||||
|
||||
/* After rewhitening the LTP state is unscaled */
|
||||
if( k == 0 ) {
|
||||
/* Do LTP downscaling to reduce inter-packet dependency */
|
||||
inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 );
|
||||
}
|
||||
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
||||
sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] );
|
||||
}
|
||||
} else {
|
||||
/* Update LTP state when Gain changes */
|
||||
if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
|
||||
for( i = 0; i < lag + LTP_ORDER/2; i++ ) {
|
||||
sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Long-term prediction */
|
||||
if( signalType == TYPE_VOICED ) {
|
||||
/* Set up pointer */
|
||||
pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ];
|
||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||
/* Unrolled loop */
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LTP_pred_Q13 = 2;
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], B_Q14[ 0 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
|
||||
LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
|
||||
pred_lag_ptr++;
|
||||
|
||||
/* Generate LPC excitation */
|
||||
pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 );
|
||||
|
||||
/* Update states */
|
||||
sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 );
|
||||
sLTP_buf_idx++;
|
||||
}
|
||||
} else {
|
||||
pres_Q14 = pexc_Q14;
|
||||
}
|
||||
|
||||
for( i = 0; i < psDec->subfr_length; i++ ) {
|
||||
/* Short-term prediction */
|
||||
silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
|
||||
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
|
||||
LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] );
|
||||
if( psDec->LPC_order == 16 ) {
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] );
|
||||
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] );
|
||||
}
|
||||
|
||||
/* Add prediction to LPC excitation */
|
||||
sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 );
|
||||
|
||||
/* Scale with gain */
|
||||
pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
|
||||
}
|
||||
|
||||
/* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
|
||||
|
||||
/* Update LPC filter state */
|
||||
silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
pexc_Q14 += psDec->subfr_length;
|
||||
pxq += psDec->subfr_length;
|
||||
}
|
||||
|
||||
/* Save LPC state */
|
||||
silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) );
|
||||
RESTORE_STACK;
|
||||
}
|
129
node_modules/node-opus/deps/opus/silk/decode_frame.c
generated
vendored
Normal file
129
node_modules/node-opus/deps/opus/silk/decode_frame.c
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "PLC.h"
|
||||
|
||||
/****************/
|
||||
/* Decode frame */
|
||||
/****************/
|
||||
opus_int silk_decode_frame(
|
||||
silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int16 pOut[], /* O Pointer to output speech frame */
|
||||
opus_int32 *pN, /* O Pointer to size of output frame */
|
||||
opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
VARDECL( silk_decoder_control, psDecCtrl );
|
||||
opus_int L, mv_len, ret = 0;
|
||||
SAVE_STACK;
|
||||
|
||||
L = psDec->frame_length;
|
||||
ALLOC( psDecCtrl, 1, silk_decoder_control );
|
||||
psDecCtrl->LTP_scale_Q14 = 0;
|
||||
|
||||
/* Safety checks */
|
||||
silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );
|
||||
|
||||
if( lostFlag == FLAG_DECODE_NORMAL ||
|
||||
( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )
|
||||
{
|
||||
VARDECL( opus_int16, pulses );
|
||||
ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) &
|
||||
~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int16 );
|
||||
/*********************************************/
|
||||
/* Decode quantization indices of side info */
|
||||
/*********************************************/
|
||||
silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag, condCoding );
|
||||
|
||||
/*********************************************/
|
||||
/* Decode quantization indices of excitation */
|
||||
/*********************************************/
|
||||
silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType,
|
||||
psDec->indices.quantOffsetType, psDec->frame_length );
|
||||
|
||||
/********************************************/
|
||||
/* Decode parameters and pulse signal */
|
||||
/********************************************/
|
||||
silk_decode_parameters( psDec, psDecCtrl, condCoding );
|
||||
|
||||
/********************************************************/
|
||||
/* Run inverse NSQ */
|
||||
/********************************************************/
|
||||
silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch );
|
||||
|
||||
/********************************************************/
|
||||
/* Update PLC state */
|
||||
/********************************************************/
|
||||
silk_PLC( psDec, psDecCtrl, pOut, 0, arch );
|
||||
|
||||
psDec->lossCnt = 0;
|
||||
psDec->prevSignalType = psDec->indices.signalType;
|
||||
silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
|
||||
|
||||
/* A frame has been decoded without errors */
|
||||
psDec->first_frame_after_reset = 0;
|
||||
} else {
|
||||
/* Handle packet loss by extrapolation */
|
||||
silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Update output buffer. */
|
||||
/*************************/
|
||||
silk_assert( psDec->ltp_mem_length >= psDec->frame_length );
|
||||
mv_len = psDec->ltp_mem_length - psDec->frame_length;
|
||||
silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );
|
||||
silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );
|
||||
|
||||
/************************************************/
|
||||
/* Comfort noise generation / estimation */
|
||||
/************************************************/
|
||||
silk_CNG( psDec, psDecCtrl, pOut, L );
|
||||
|
||||
/****************************************************************/
|
||||
/* Ensure smooth connection of extrapolated and good frames */
|
||||
/****************************************************************/
|
||||
silk_PLC_glue_frames( psDec, pOut, L );
|
||||
|
||||
/* Update some decoder state variables */
|
||||
psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ];
|
||||
|
||||
/* Set output frame length */
|
||||
*pN = L;
|
||||
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
151
node_modules/node-opus/deps/opus/silk/decode_indices.c
generated
vendored
Normal file
151
node_modules/node-opus/deps/opus/silk/decode_indices.c
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Decode side-information parameters from payload */
|
||||
void silk_decode_indices(
|
||||
silk_decoder_state *psDec, /* I/O State */
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int FrameIndex, /* I Frame number */
|
||||
opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int i, k, Ix;
|
||||
opus_int decode_absolute_lagIndex, delta_lagIndex;
|
||||
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||
|
||||
/*******************************************/
|
||||
/* Decode signal type and quantizer offset */
|
||||
/*******************************************/
|
||||
if( decode_LBRR || psDec->VAD_flags[ FrameIndex ] ) {
|
||||
Ix = ec_dec_icdf( psRangeDec, silk_type_offset_VAD_iCDF, 8 ) + 2;
|
||||
} else {
|
||||
Ix = ec_dec_icdf( psRangeDec, silk_type_offset_no_VAD_iCDF, 8 );
|
||||
}
|
||||
psDec->indices.signalType = (opus_int8)silk_RSHIFT( Ix, 1 );
|
||||
psDec->indices.quantOffsetType = (opus_int8)( Ix & 1 );
|
||||
|
||||
/****************/
|
||||
/* Decode gains */
|
||||
/****************/
|
||||
/* First subframe */
|
||||
if( condCoding == CODE_CONDITIONALLY ) {
|
||||
/* Conditional coding */
|
||||
psDec->indices.GainsIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 );
|
||||
} else {
|
||||
/* Independent coding, in two stages: MSB bits followed by 3 LSBs */
|
||||
psDec->indices.GainsIndices[ 0 ] = (opus_int8)silk_LSHIFT( ec_dec_icdf( psRangeDec, silk_gain_iCDF[ psDec->indices.signalType ], 8 ), 3 );
|
||||
psDec->indices.GainsIndices[ 0 ] += (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform8_iCDF, 8 );
|
||||
}
|
||||
|
||||
/* Remaining subframes */
|
||||
for( i = 1; i < psDec->nb_subfr; i++ ) {
|
||||
psDec->indices.GainsIndices[ i ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 );
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Decode LSF Indices */
|
||||
/**********************/
|
||||
psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );
|
||||
silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );
|
||||
silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
|
||||
for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {
|
||||
Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
|
||||
if( Ix == 0 ) {
|
||||
Ix -= ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 );
|
||||
} else if( Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
Ix += ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 );
|
||||
}
|
||||
psDec->indices.NLSFIndices[ i+1 ] = (opus_int8)( Ix - NLSF_QUANT_MAX_AMPLITUDE );
|
||||
}
|
||||
|
||||
/* Decode LSF interpolation factor */
|
||||
if( psDec->nb_subfr == MAX_NB_SUBFR ) {
|
||||
psDec->indices.NLSFInterpCoef_Q2 = (opus_int8)ec_dec_icdf( psRangeDec, silk_NLSF_interpolation_factor_iCDF, 8 );
|
||||
} else {
|
||||
psDec->indices.NLSFInterpCoef_Q2 = 4;
|
||||
}
|
||||
|
||||
if( psDec->indices.signalType == TYPE_VOICED )
|
||||
{
|
||||
/*********************/
|
||||
/* Decode pitch lags */
|
||||
/*********************/
|
||||
/* Get lag index */
|
||||
decode_absolute_lagIndex = 1;
|
||||
if( condCoding == CODE_CONDITIONALLY && psDec->ec_prevSignalType == TYPE_VOICED ) {
|
||||
/* Decode Delta index */
|
||||
delta_lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_delta_iCDF, 8 );
|
||||
if( delta_lagIndex > 0 ) {
|
||||
delta_lagIndex = delta_lagIndex - 9;
|
||||
psDec->indices.lagIndex = (opus_int16)( psDec->ec_prevLagIndex + delta_lagIndex );
|
||||
decode_absolute_lagIndex = 0;
|
||||
}
|
||||
}
|
||||
if( decode_absolute_lagIndex ) {
|
||||
/* Absolute decoding */
|
||||
psDec->indices.lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_lag_iCDF, 8 ) * silk_RSHIFT( psDec->fs_kHz, 1 );
|
||||
psDec->indices.lagIndex += (opus_int16)ec_dec_icdf( psRangeDec, psDec->pitch_lag_low_bits_iCDF, 8 );
|
||||
}
|
||||
psDec->ec_prevLagIndex = psDec->indices.lagIndex;
|
||||
|
||||
/* Get countour index */
|
||||
psDec->indices.contourIndex = (opus_int8)ec_dec_icdf( psRangeDec, psDec->pitch_contour_iCDF, 8 );
|
||||
|
||||
/********************/
|
||||
/* Decode LTP gains */
|
||||
/********************/
|
||||
/* Decode PERIndex value */
|
||||
psDec->indices.PERIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_per_index_iCDF, 8 );
|
||||
|
||||
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
||||
psDec->indices.LTPIndex[ k ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_gain_iCDF_ptrs[ psDec->indices.PERIndex ], 8 );
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Decode LTP scaling */
|
||||
/**********************/
|
||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||
psDec->indices.LTP_scaleIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTPscale_iCDF, 8 );
|
||||
} else {
|
||||
psDec->indices.LTP_scaleIndex = 0;
|
||||
}
|
||||
}
|
||||
psDec->ec_prevSignalType = psDec->indices.signalType;
|
||||
|
||||
/***************/
|
||||
/* Decode seed */
|
||||
/***************/
|
||||
psDec->indices.Seed = (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform4_iCDF, 8 );
|
||||
}
|
115
node_modules/node-opus/deps/opus/silk/decode_parameters.c
generated
vendored
Normal file
115
node_modules/node-opus/deps/opus/silk/decode_parameters.c
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Decode parameters from payload */
|
||||
void silk_decode_parameters(
|
||||
silk_decoder_state *psDec, /* I/O State */
|
||||
silk_decoder_control *psDecCtrl, /* I/O Decoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int i, k, Ix;
|
||||
opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ];
|
||||
const opus_int8 *cbk_ptr_Q7;
|
||||
|
||||
/* Dequant Gains */
|
||||
silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices,
|
||||
&psDec->LastGainIndex, condCoding == CODE_CONDITIONALLY, psDec->nb_subfr );
|
||||
|
||||
/****************/
|
||||
/* Decode NLSFs */
|
||||
/****************/
|
||||
silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
|
||||
|
||||
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
|
||||
|
||||
/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
|
||||
/* improves the case of packet loss in the first frame after a switch */
|
||||
if( psDec->first_frame_after_reset == 1 ) {
|
||||
psDec->indices.NLSFInterpCoef_Q2 = 4;
|
||||
}
|
||||
|
||||
if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) {
|
||||
/* Calculation of the interpolated NLSF0 vector from the interpolation factor, */
|
||||
/* the previous NLSF1, and the current NLSF1 */
|
||||
for( i = 0; i < psDec->LPC_order; i++ ) {
|
||||
pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + silk_RSHIFT( silk_MUL( psDec->indices.NLSFInterpCoef_Q2,
|
||||
pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 );
|
||||
}
|
||||
|
||||
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
||||
} else {
|
||||
/* Copy LPC coefficients for first half from second half */
|
||||
silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
|
||||
}
|
||||
|
||||
silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) );
|
||||
|
||||
/* After a packet loss do BWE of LPC coefs */
|
||||
if( psDec->lossCnt ) {
|
||||
silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
|
||||
silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 );
|
||||
}
|
||||
|
||||
if( psDec->indices.signalType == TYPE_VOICED ) {
|
||||
/*********************/
|
||||
/* Decode pitch lags */
|
||||
/*********************/
|
||||
|
||||
/* Decode pitch values */
|
||||
silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr );
|
||||
|
||||
/* Decode Codebook Index */
|
||||
cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */
|
||||
|
||||
for( k = 0; k < psDec->nb_subfr; k++ ) {
|
||||
Ix = psDec->indices.LTPIndex[ k ];
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = silk_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 );
|
||||
}
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Decode LTP scaling */
|
||||
/**********************/
|
||||
Ix = psDec->indices.LTP_scaleIndex;
|
||||
psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ];
|
||||
} else {
|
||||
silk_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( opus_int ) );
|
||||
silk_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( opus_int16 ) );
|
||||
psDec->indices.PERIndex = 0;
|
||||
psDecCtrl->LTP_scale_Q14 = 0;
|
||||
}
|
||||
}
|
77
node_modules/node-opus/deps/opus/silk/decode_pitch.c
generated
vendored
Normal file
77
node_modules/node-opus/deps/opus/silk/decode_pitch.c
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/***********************************************************
|
||||
* Pitch analyser function
|
||||
********************************************************** */
|
||||
#include "SigProc_FIX.h"
|
||||
#include "pitch_est_defines.h"
|
||||
|
||||
void silk_decode_pitch(
|
||||
opus_int16 lagIndex, /* I */
|
||||
opus_int8 contourIndex, /* O */
|
||||
opus_int pitch_lags[], /* O 4 pitch values */
|
||||
const opus_int Fs_kHz, /* I sampling frequency (kHz) */
|
||||
const opus_int nb_subfr /* I number of sub frames */
|
||||
)
|
||||
{
|
||||
opus_int lag, k, min_lag, max_lag, cbk_size;
|
||||
const opus_int8 *Lag_CB_ptr;
|
||||
|
||||
if( Fs_kHz == 8 ) {
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
||||
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
||||
} else {
|
||||
silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
|
||||
Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
|
||||
cbk_size = PE_NB_CBKS_STAGE2_10MS;
|
||||
}
|
||||
} else {
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
|
||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||
} else {
|
||||
silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
|
||||
cbk_size = PE_NB_CBKS_STAGE3_10MS;
|
||||
}
|
||||
}
|
||||
|
||||
min_lag = silk_SMULBB( PE_MIN_LAG_MS, Fs_kHz );
|
||||
max_lag = silk_SMULBB( PE_MAX_LAG_MS, Fs_kHz );
|
||||
lag = min_lag + lagIndex;
|
||||
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
pitch_lags[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, contourIndex, cbk_size );
|
||||
pitch_lags[ k ] = silk_LIMIT( pitch_lags[ k ], min_lag, max_lag );
|
||||
}
|
||||
}
|
115
node_modules/node-opus/deps/opus/silk/decode_pulses.c
generated
vendored
Normal file
115
node_modules/node-opus/deps/opus/silk/decode_pulses.c
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/*********************************************/
|
||||
/* Decode quantization indices of excitation */
|
||||
/*********************************************/
|
||||
void silk_decode_pulses(
|
||||
ec_dec *psRangeDec, /* I/O Compressor data structure */
|
||||
opus_int16 pulses[], /* O Excitation signal */
|
||||
const opus_int signalType, /* I Sigtype */
|
||||
const opus_int quantOffsetType, /* I quantOffsetType */
|
||||
const opus_int frame_length /* I Frame length */
|
||||
)
|
||||
{
|
||||
opus_int i, j, k, iter, abs_q, nLS, RateLevelIndex;
|
||||
opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ];
|
||||
opus_int16 *pulses_ptr;
|
||||
const opus_uint8 *cdf_ptr;
|
||||
|
||||
/*********************/
|
||||
/* Decode rate level */
|
||||
/*********************/
|
||||
RateLevelIndex = ec_dec_icdf( psRangeDec, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );
|
||||
|
||||
/* Calculate number of shell blocks */
|
||||
silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
|
||||
iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
|
||||
if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
|
||||
silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
|
||||
iter++;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Sum-Weighted-Pulses Decoding */
|
||||
/***************************************************/
|
||||
cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
nLshifts[ i ] = 0;
|
||||
sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 );
|
||||
|
||||
/* LSB indication */
|
||||
while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) {
|
||||
nLshifts[ i ]++;
|
||||
/* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */
|
||||
sum_pulses[ i ] = ec_dec_icdf( psRangeDec,
|
||||
silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* Shell decoding */
|
||||
/***************************************************/
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( sum_pulses[ i ] > 0 ) {
|
||||
silk_shell_decoder( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRangeDec, sum_pulses[ i ] );
|
||||
} else {
|
||||
silk_memset( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( pulses[0] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/* LSB Decoding */
|
||||
/***************************************************/
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( nLshifts[ i ] > 0 ) {
|
||||
nLS = nLshifts[ i ];
|
||||
pulses_ptr = &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ];
|
||||
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||
abs_q = pulses_ptr[ k ];
|
||||
for( j = 0; j < nLS; j++ ) {
|
||||
abs_q = silk_LSHIFT( abs_q, 1 );
|
||||
abs_q += ec_dec_icdf( psRangeDec, silk_lsb_iCDF, 8 );
|
||||
}
|
||||
pulses_ptr[ k ] = abs_q;
|
||||
}
|
||||
/* Mark the number of pulses non-zero for sign decoding. */
|
||||
sum_pulses[ i ] |= nLS << 5;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Decode and add signs to pulse signal */
|
||||
/****************************************/
|
||||
silk_decode_signs( psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses );
|
||||
}
|
108
node_modules/node-opus/deps/opus/silk/decoder_set_fs.c
generated
vendored
Normal file
108
node_modules/node-opus/deps/opus/silk/decoder_set_fs.c
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Set decoder sampling rate */
|
||||
opus_int silk_decoder_set_fs(
|
||||
silk_decoder_state *psDec, /* I/O Decoder state pointer */
|
||||
opus_int fs_kHz, /* I Sampling frequency (kHz) */
|
||||
opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */
|
||||
)
|
||||
{
|
||||
opus_int frame_length, ret = 0;
|
||||
|
||||
silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
|
||||
silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
|
||||
|
||||
/* New (sub)frame length */
|
||||
psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );
|
||||
frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length );
|
||||
|
||||
/* Initialize resampler when switching internal or external sampling frequency */
|
||||
if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) {
|
||||
/* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */
|
||||
ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 );
|
||||
|
||||
psDec->fs_API_hz = fs_API_Hz;
|
||||
}
|
||||
|
||||
if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) {
|
||||
if( fs_kHz == 8 ) {
|
||||
if( psDec->nb_subfr == MAX_NB_SUBFR ) {
|
||||
psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
|
||||
} else {
|
||||
psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
|
||||
}
|
||||
} else {
|
||||
if( psDec->nb_subfr == MAX_NB_SUBFR ) {
|
||||
psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF;
|
||||
} else {
|
||||
psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
|
||||
}
|
||||
}
|
||||
if( psDec->fs_kHz != fs_kHz ) {
|
||||
psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );
|
||||
if( fs_kHz == 8 || fs_kHz == 12 ) {
|
||||
psDec->LPC_order = MIN_LPC_ORDER;
|
||||
psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB;
|
||||
} else {
|
||||
psDec->LPC_order = MAX_LPC_ORDER;
|
||||
psDec->psNLSF_CB = &silk_NLSF_CB_WB;
|
||||
}
|
||||
if( fs_kHz == 16 ) {
|
||||
psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
|
||||
} else if( fs_kHz == 12 ) {
|
||||
psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
|
||||
} else if( fs_kHz == 8 ) {
|
||||
psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
|
||||
} else {
|
||||
/* unsupported sampling rate */
|
||||
silk_assert( 0 );
|
||||
}
|
||||
psDec->first_frame_after_reset = 1;
|
||||
psDec->lagPrev = 100;
|
||||
psDec->LastGainIndex = 10;
|
||||
psDec->prevSignalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf));
|
||||
silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) );
|
||||
}
|
||||
|
||||
psDec->fs_kHz = fs_kHz;
|
||||
psDec->frame_length = frame_length;
|
||||
}
|
||||
|
||||
/* Check that settings are valid */
|
||||
silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
235
node_modules/node-opus/deps/opus/silk/define.h
generated
vendored
Normal file
235
node_modules/node-opus/deps/opus/silk/define.h
generated
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_DEFINE_H
|
||||
#define SILK_DEFINE_H
|
||||
|
||||
#include "errors.h"
|
||||
#include "typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Max number of encoder channels (1/2) */
|
||||
#define ENCODER_NUM_CHANNELS 2
|
||||
/* Number of decoder channels (1/2) */
|
||||
#define DECODER_NUM_CHANNELS 2
|
||||
|
||||
#define MAX_FRAMES_PER_PACKET 3
|
||||
|
||||
/* Limits on bitrate */
|
||||
#define MIN_TARGET_RATE_BPS 5000
|
||||
#define MAX_TARGET_RATE_BPS 80000
|
||||
#define TARGET_RATE_TAB_SZ 8
|
||||
|
||||
/* LBRR thresholds */
|
||||
#define LBRR_NB_MIN_RATE_BPS 12000
|
||||
#define LBRR_MB_MIN_RATE_BPS 14000
|
||||
#define LBRR_WB_MIN_RATE_BPS 16000
|
||||
|
||||
/* DTX settings */
|
||||
#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */
|
||||
#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
|
||||
|
||||
/* Maximum sampling frequency */
|
||||
#define MAX_FS_KHZ 16
|
||||
#define MAX_API_FS_KHZ 48
|
||||
|
||||
/* Signal types */
|
||||
#define TYPE_NO_VOICE_ACTIVITY 0
|
||||
#define TYPE_UNVOICED 1
|
||||
#define TYPE_VOICED 2
|
||||
|
||||
/* Conditional coding types */
|
||||
#define CODE_INDEPENDENTLY 0
|
||||
#define CODE_INDEPENDENTLY_NO_LTP_SCALING 1
|
||||
#define CODE_CONDITIONALLY 2
|
||||
|
||||
/* Settings for stereo processing */
|
||||
#define STEREO_QUANT_TAB_SIZE 16
|
||||
#define STEREO_QUANT_SUB_STEPS 5
|
||||
#define STEREO_INTERP_LEN_MS 8 /* must be even */
|
||||
#define STEREO_RATIO_SMOOTH_COEF 0.01 /* smoothing coef for signal norms and stereo width */
|
||||
|
||||
/* Range of pitch lag estimates */
|
||||
#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */
|
||||
#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */
|
||||
|
||||
/* Maximum number of subframes */
|
||||
#define MAX_NB_SUBFR 4
|
||||
|
||||
/* Number of samples per frame */
|
||||
#define LTP_MEM_LENGTH_MS 20
|
||||
#define SUB_FRAME_LENGTH_MS 5
|
||||
#define MAX_SUB_FRAME_LENGTH ( SUB_FRAME_LENGTH_MS * MAX_FS_KHZ )
|
||||
#define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR )
|
||||
#define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ )
|
||||
|
||||
/* Milliseconds of lookahead for pitch analysis */
|
||||
#define LA_PITCH_MS 2
|
||||
#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ )
|
||||
|
||||
/* Order of LPC used in find pitch */
|
||||
#define MAX_FIND_PITCH_LPC_ORDER 16
|
||||
|
||||
/* Length of LPC window used in find pitch */
|
||||
#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) )
|
||||
#define FIND_PITCH_LPC_WIN_MS_2_SF ( 10 + (LA_PITCH_MS << 1) )
|
||||
#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ )
|
||||
|
||||
/* Milliseconds of lookahead for noise shape analysis */
|
||||
#define LA_SHAPE_MS 5
|
||||
#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ )
|
||||
|
||||
/* Maximum length of LPC window used in noise shape analysis */
|
||||
#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ )
|
||||
|
||||
/* dB level of lowest gain quantization level */
|
||||
#define MIN_QGAIN_DB 2
|
||||
/* dB level of highest gain quantization level */
|
||||
#define MAX_QGAIN_DB 88
|
||||
/* Number of gain quantization levels */
|
||||
#define N_LEVELS_QGAIN 64
|
||||
/* Max increase in gain quantization index */
|
||||
#define MAX_DELTA_GAIN_QUANT 36
|
||||
/* Max decrease in gain quantization index */
|
||||
#define MIN_DELTA_GAIN_QUANT -4
|
||||
|
||||
/* Quantization offsets (multiples of 4) */
|
||||
#define OFFSET_VL_Q10 32
|
||||
#define OFFSET_VH_Q10 100
|
||||
#define OFFSET_UVL_Q10 100
|
||||
#define OFFSET_UVH_Q10 240
|
||||
|
||||
#define QUANT_LEVEL_ADJUST_Q10 80
|
||||
|
||||
/* Maximum numbers of iterations used to stabilize an LPC vector */
|
||||
#define MAX_LPC_STABILIZE_ITERATIONS 16
|
||||
#define MAX_PREDICTION_POWER_GAIN 1e4f
|
||||
#define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f
|
||||
|
||||
#define MAX_LPC_ORDER 16
|
||||
#define MIN_LPC_ORDER 10
|
||||
|
||||
/* Find Pred Coef defines */
|
||||
#define LTP_ORDER 5
|
||||
|
||||
/* LTP quantization settings */
|
||||
#define NB_LTP_CBKS 3
|
||||
|
||||
/* Flag to use harmonic noise shaping */
|
||||
#define USE_HARM_SHAPING 1
|
||||
|
||||
/* Max LPC order of noise shaping filters */
|
||||
#define MAX_SHAPE_LPC_ORDER 16
|
||||
|
||||
#define HARM_SHAPE_FIR_TAPS 3
|
||||
|
||||
/* Maximum number of delayed decision states */
|
||||
#define MAX_DEL_DEC_STATES 4
|
||||
|
||||
#define LTP_BUF_LENGTH 512
|
||||
#define LTP_MASK ( LTP_BUF_LENGTH - 1 )
|
||||
|
||||
#define DECISION_DELAY 32
|
||||
#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 )
|
||||
|
||||
/* Number of subframes for excitation entropy coding */
|
||||
#define SHELL_CODEC_FRAME_LENGTH 16
|
||||
#define LOG2_SHELL_CODEC_FRAME_LENGTH 4
|
||||
#define MAX_NB_SHELL_BLOCKS ( MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH )
|
||||
|
||||
/* Number of rate levels, for entropy coding of excitation */
|
||||
#define N_RATE_LEVELS 10
|
||||
|
||||
/* Maximum sum of pulses per shell coding frame */
|
||||
#define SILK_MAX_PULSES 16
|
||||
|
||||
#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
|
||||
|
||||
#if( MAX_LPC_ORDER > DECISION_DELAY )
|
||||
# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
|
||||
#else
|
||||
# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
|
||||
#endif
|
||||
|
||||
/***************************/
|
||||
/* Voice activity detector */
|
||||
/***************************/
|
||||
#define VAD_N_BANDS 4
|
||||
|
||||
#define VAD_INTERNAL_SUBFRAMES_LOG2 2
|
||||
#define VAD_INTERNAL_SUBFRAMES ( 1 << VAD_INTERNAL_SUBFRAMES_LOG2 )
|
||||
|
||||
#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */
|
||||
#define VAD_NOISE_LEVELS_BIAS 50
|
||||
|
||||
/* Sigmoid settings */
|
||||
#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */
|
||||
#define VAD_SNR_FACTOR_Q16 45000
|
||||
|
||||
/* smoothing for SNR measurement */
|
||||
#define VAD_SNR_SMOOTH_COEF_Q18 4096
|
||||
|
||||
/* Size of the piecewise linear cosine approximation table for the LSFs */
|
||||
#define LSF_COS_TAB_SZ_FIX 128
|
||||
|
||||
/******************/
|
||||
/* NLSF quantizer */
|
||||
/******************/
|
||||
#define NLSF_W_Q 2
|
||||
#define NLSF_VQ_MAX_VECTORS 32
|
||||
#define NLSF_VQ_MAX_SURVIVORS 32
|
||||
#define NLSF_QUANT_MAX_AMPLITUDE 4
|
||||
#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
|
||||
#define NLSF_QUANT_LEVEL_ADJ 0.1
|
||||
#define NLSF_QUANT_DEL_DEC_STATES_LOG2 2
|
||||
#define NLSF_QUANT_DEL_DEC_STATES ( 1 << NLSF_QUANT_DEL_DEC_STATES_LOG2 )
|
||||
|
||||
/* Transition filtering for mode switching */
|
||||
#define TRANSITION_TIME_MS 5120 /* 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)*/
|
||||
#define TRANSITION_NB 3 /* Hardcoded in tables */
|
||||
#define TRANSITION_NA 2 /* Hardcoded in tables */
|
||||
#define TRANSITION_INT_NUM 5 /* Hardcoded in tables */
|
||||
#define TRANSITION_FRAMES ( TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS )
|
||||
#define TRANSITION_INT_STEPS ( TRANSITION_FRAMES / ( TRANSITION_INT_NUM - 1 ) )
|
||||
|
||||
/* BWE factors to apply after packet loss */
|
||||
#define BWE_AFTER_LOSS_Q16 63570
|
||||
|
||||
/* Defines for CN generation */
|
||||
#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */
|
||||
#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */
|
||||
#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
563
node_modules/node-opus/deps/opus/silk/enc_API.c
generated
vendored
Normal file
563
node_modules/node-opus/deps/opus/silk/enc_API.c
generated
vendored
Normal file
@ -0,0 +1,563 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "define.h"
|
||||
#include "API.h"
|
||||
#include "control.h"
|
||||
#include "typedef.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "structs.h"
|
||||
#include "tuning_parameters.h"
|
||||
#ifdef FIXED_POINT
|
||||
#include "main_FIX.h"
|
||||
#else
|
||||
#include "main_FLP.h"
|
||||
#endif
|
||||
|
||||
/***************************************/
|
||||
/* Read control structure from encoder */
|
||||
/***************************************/
|
||||
static opus_int silk_QueryEncoder( /* O Returns error code */
|
||||
const void *encState, /* I State */
|
||||
silk_EncControlStruct *encStatus /* O Encoder Status */
|
||||
);
|
||||
|
||||
/****************************************/
|
||||
/* Encoder functions */
|
||||
/****************************************/
|
||||
|
||||
opus_int silk_Get_Encoder_Size( /* O Returns error code */
|
||||
opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */
|
||||
)
|
||||
{
|
||||
opus_int ret = SILK_NO_ERROR;
|
||||
|
||||
*encSizeBytes = sizeof( silk_encoder );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Init or Reset encoder */
|
||||
/*************************/
|
||||
opus_int silk_InitEncoder( /* O Returns error code */
|
||||
void *encState, /* I/O State */
|
||||
int arch, /* I Run-time architecture */
|
||||
silk_EncControlStruct *encStatus /* O Encoder Status */
|
||||
)
|
||||
{
|
||||
silk_encoder *psEnc;
|
||||
opus_int n, ret = SILK_NO_ERROR;
|
||||
|
||||
psEnc = (silk_encoder *)encState;
|
||||
|
||||
/* Reset encoder */
|
||||
silk_memset( psEnc, 0, sizeof( silk_encoder ) );
|
||||
for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
|
||||
if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
|
||||
silk_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
psEnc->nChannelsAPI = 1;
|
||||
psEnc->nChannelsInternal = 1;
|
||||
|
||||
/* Read control structure */
|
||||
if( ret += silk_QueryEncoder( encState, encStatus ) ) {
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************/
|
||||
/* Read control structure from encoder */
|
||||
/***************************************/
|
||||
static opus_int silk_QueryEncoder( /* O Returns error code */
|
||||
const void *encState, /* I State */
|
||||
silk_EncControlStruct *encStatus /* O Encoder Status */
|
||||
)
|
||||
{
|
||||
opus_int ret = SILK_NO_ERROR;
|
||||
silk_encoder_state_Fxx *state_Fxx;
|
||||
silk_encoder *psEnc = (silk_encoder *)encState;
|
||||
|
||||
state_Fxx = psEnc->state_Fxx;
|
||||
|
||||
encStatus->nChannelsAPI = psEnc->nChannelsAPI;
|
||||
encStatus->nChannelsInternal = psEnc->nChannelsInternal;
|
||||
encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz;
|
||||
encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;
|
||||
encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;
|
||||
encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;
|
||||
encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms;
|
||||
encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps;
|
||||
encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc;
|
||||
encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity;
|
||||
encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC;
|
||||
encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX;
|
||||
encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR;
|
||||
encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
|
||||
encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;
|
||||
encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**************************/
|
||||
/* Encode frame with Silk */
|
||||
/**************************/
|
||||
/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */
|
||||
/* encControl->payloadSize_ms is set to */
|
||||
opus_int silk_Encode( /* O Returns error code */
|
||||
void *encState, /* I/O State */
|
||||
silk_EncControlStruct *encControl, /* I Control status */
|
||||
const opus_int16 *samplesIn, /* I Speech sample input vector */
|
||||
opus_int nSamplesIn, /* I Number of samples in input vector */
|
||||
ec_enc *psRangeEnc, /* I/O Compressor data structure */
|
||||
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
|
||||
const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */
|
||||
)
|
||||
{
|
||||
opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
|
||||
opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
|
||||
opus_int nSamplesFromInput = 0, nSamplesFromInputMax;
|
||||
opus_int speech_act_thr_for_switch_Q8;
|
||||
opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
|
||||
silk_encoder *psEnc = ( silk_encoder * )encState;
|
||||
VARDECL( opus_int16, buf );
|
||||
opus_int transition, curr_block, tot_blocks;
|
||||
SAVE_STACK;
|
||||
|
||||
if (encControl->reducedDependency)
|
||||
{
|
||||
psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
|
||||
psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
|
||||
}
|
||||
psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
|
||||
|
||||
/* Check values in encoder control structure */
|
||||
if( ( ret = check_control_input( encControl ) ) != 0 ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
encControl->switchReady = 0;
|
||||
|
||||
if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
|
||||
/* Mono -> Stereo transition: init state of second channel and stereo state */
|
||||
ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
|
||||
silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
|
||||
silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
|
||||
psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
|
||||
psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
|
||||
psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
|
||||
psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
|
||||
psEnc->sStereo.width_prev_Q14 = 0;
|
||||
psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
|
||||
if( psEnc->nChannelsAPI == 2 ) {
|
||||
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
|
||||
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) );
|
||||
}
|
||||
}
|
||||
|
||||
transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);
|
||||
|
||||
psEnc->nChannelsAPI = encControl->nChannelsAPI;
|
||||
psEnc->nChannelsInternal = encControl->nChannelsInternal;
|
||||
|
||||
nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
|
||||
tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
|
||||
curr_block = 0;
|
||||
if( prefillFlag ) {
|
||||
/* Only accept input length of 10 ms */
|
||||
if( nBlocksOf10ms != 1 ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
|
||||
}
|
||||
/* Reset Encoder */
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
|
||||
silk_assert( !ret );
|
||||
}
|
||||
tmp_payloadSize_ms = encControl->payloadSize_ms;
|
||||
encControl->payloadSize_ms = 10;
|
||||
tmp_complexity = encControl->complexity;
|
||||
encControl->complexity = 0;
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
|
||||
psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
|
||||
}
|
||||
} else {
|
||||
/* Only accept input lengths that are a multiple of 10 ms */
|
||||
if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
|
||||
}
|
||||
/* Make sure no more than one packet can be produced */
|
||||
if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
|
||||
}
|
||||
}
|
||||
|
||||
TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
/* Force the side channel to the same rate as the mid */
|
||||
opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
|
||||
if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
|
||||
silk_assert( 0 );
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
|
||||
for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
|
||||
psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
|
||||
}
|
||||
}
|
||||
psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
|
||||
}
|
||||
silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
||||
|
||||
/* Input buffering/resampling and encoding */
|
||||
nSamplesToBufferMax =
|
||||
10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
|
||||
nSamplesFromInputMax =
|
||||
silk_DIV32_16( nSamplesToBufferMax *
|
||||
psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
|
||||
psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
|
||||
ALLOC( buf, nSamplesFromInputMax, opus_int16 );
|
||||
while( 1 ) {
|
||||
nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
|
||||
nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
|
||||
nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
|
||||
/* Resample and write to buffer */
|
||||
if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
|
||||
opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
|
||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||
buf[ n ] = samplesIn[ 2 * n ];
|
||||
}
|
||||
/* Making sure to start both resamplers from the same state when switching from mono to stereo */
|
||||
if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
|
||||
silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
|
||||
}
|
||||
|
||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||
|
||||
nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
|
||||
nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
|
||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||
buf[ n ] = samplesIn[ 2 * n + 1 ];
|
||||
}
|
||||
ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
|
||||
&psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||
|
||||
psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||
} else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
|
||||
/* Combine left and right channels before resampling */
|
||||
for( n = 0; n < nSamplesFromInput; n++ ) {
|
||||
sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
|
||||
buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
|
||||
}
|
||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||
/* On the first mono frame, average the results for the two resampler states */
|
||||
if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
|
||||
ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
|
||||
&psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||
for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
|
||||
psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
|
||||
silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
|
||||
+ psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
|
||||
}
|
||||
}
|
||||
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||
} else {
|
||||
silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
|
||||
silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
|
||||
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
|
||||
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
|
||||
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
|
||||
}
|
||||
|
||||
samplesIn += nSamplesFromInput * encControl->nChannelsAPI;
|
||||
nSamplesIn -= nSamplesFromInput;
|
||||
|
||||
/* Default */
|
||||
psEnc->allowBandwidthSwitch = 0;
|
||||
|
||||
/* Silk encoder */
|
||||
if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
|
||||
/* Enough data in input buffer, so encode */
|
||||
silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
|
||||
silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
|
||||
|
||||
/* Deal with LBRR data */
|
||||
if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
|
||||
/* Create space at start of payload for VAD and FEC flags */
|
||||
opus_uint8 iCDF[ 2 ] = { 0, 0 };
|
||||
iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
|
||||
ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
|
||||
|
||||
/* Encode any LBRR data from previous packet */
|
||||
/* Encode LBRR flags */
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
LBRR_symbol = 0;
|
||||
for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
|
||||
LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
|
||||
}
|
||||
psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
|
||||
if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
|
||||
ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Code LBRR indices and excitation signals */
|
||||
for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
|
||||
opus_int condCoding;
|
||||
|
||||
if( encControl->nChannelsInternal == 2 && n == 0 ) {
|
||||
silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
|
||||
/* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
|
||||
if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
|
||||
silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
|
||||
}
|
||||
}
|
||||
/* Use conditional coding if previous frame available */
|
||||
if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
|
||||
condCoding = CODE_CONDITIONALLY;
|
||||
} else {
|
||||
condCoding = CODE_INDEPENDENTLY;
|
||||
}
|
||||
silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
|
||||
silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
|
||||
psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset LBRR flags */
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
|
||||
}
|
||||
|
||||
psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
|
||||
}
|
||||
|
||||
silk_HP_variable_cutoff( psEnc->state_Fxx );
|
||||
|
||||
/* Total target bits for packet */
|
||||
nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
|
||||
/* Subtract bits used for LBRR */
|
||||
if( !prefillFlag ) {
|
||||
nBits -= psEnc->nBitsUsedLBRR;
|
||||
}
|
||||
/* Divide by number of uncoded frames left in packet */
|
||||
nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
|
||||
/* Convert to bits/second */
|
||||
if( encControl->payloadSize_ms == 10 ) {
|
||||
TargetRate_bps = silk_SMULBB( nBits, 100 );
|
||||
} else {
|
||||
TargetRate_bps = silk_SMULBB( nBits, 50 );
|
||||
}
|
||||
/* Subtract fraction of bits in excess of target in previous frames and packets */
|
||||
TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
|
||||
if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
|
||||
/* Compare actual vs target bits so far in this packet */
|
||||
opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
|
||||
TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
|
||||
}
|
||||
/* Never exceed input bitrate */
|
||||
TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );
|
||||
|
||||
/* Convert Left/Right to Mid/Side */
|
||||
if( encControl->nChannelsInternal == 2 ) {
|
||||
silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
|
||||
psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
|
||||
MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
|
||||
psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
|
||||
if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
|
||||
/* Reset side channel encoder memory for first frame with side coding */
|
||||
if( psEnc->prev_decode_only_middle == 1 ) {
|
||||
silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
|
||||
silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt, 0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );
|
||||
silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
|
||||
silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
|
||||
silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
|
||||
psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100;
|
||||
psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100;
|
||||
psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10;
|
||||
psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536;
|
||||
psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
|
||||
}
|
||||
silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );
|
||||
} else {
|
||||
psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
|
||||
}
|
||||
if( !prefillFlag ) {
|
||||
silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
|
||||
if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
|
||||
silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Buffering */
|
||||
silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
|
||||
silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
|
||||
}
|
||||
silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );
|
||||
|
||||
/* Encode */
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
opus_int maxBits, useCBR;
|
||||
|
||||
/* Handling rate constraints */
|
||||
maxBits = encControl->maxBits;
|
||||
if( tot_blocks == 2 && curr_block == 0 ) {
|
||||
maxBits = maxBits * 3 / 5;
|
||||
} else if( tot_blocks == 3 ) {
|
||||
if( curr_block == 0 ) {
|
||||
maxBits = maxBits * 2 / 5;
|
||||
} else if( curr_block == 1 ) {
|
||||
maxBits = maxBits * 3 / 4;
|
||||
}
|
||||
}
|
||||
useCBR = encControl->useCBR && curr_block == tot_blocks - 1;
|
||||
|
||||
if( encControl->nChannelsInternal == 1 ) {
|
||||
channelRate_bps = TargetRate_bps;
|
||||
} else {
|
||||
channelRate_bps = MStargetRates_bps[ n ];
|
||||
if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
|
||||
useCBR = 0;
|
||||
/* Give mid up to 1/2 of the max bits for that frame */
|
||||
maxBits -= encControl->maxBits / ( tot_blocks * 2 );
|
||||
}
|
||||
}
|
||||
|
||||
if( channelRate_bps > 0 ) {
|
||||
opus_int condCoding;
|
||||
|
||||
silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );
|
||||
|
||||
/* Use independent coding if no previous frame available */
|
||||
if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
|
||||
condCoding = CODE_INDEPENDENTLY;
|
||||
} else if( n > 0 && psEnc->prev_decode_only_middle ) {
|
||||
/* If we skipped a side frame in this packet, we don't
|
||||
need LTP scaling; the LTP state is well-defined. */
|
||||
condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
|
||||
} else {
|
||||
condCoding = CODE_CONDITIONALLY;
|
||||
}
|
||||
if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
|
||||
silk_assert( 0 );
|
||||
}
|
||||
}
|
||||
psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
|
||||
psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
|
||||
psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
|
||||
}
|
||||
psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];
|
||||
|
||||
/* Insert VAD and FEC flags at beginning of bitstream */
|
||||
if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
|
||||
flags = 0;
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
|
||||
flags = silk_LSHIFT( flags, 1 );
|
||||
flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
|
||||
}
|
||||
flags = silk_LSHIFT( flags, 1 );
|
||||
flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
|
||||
}
|
||||
if( !prefillFlag ) {
|
||||
ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
|
||||
}
|
||||
|
||||
/* Return zero bytes if all channels DTXed */
|
||||
if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
|
||||
*nBytesOut = 0;
|
||||
}
|
||||
|
||||
psEnc->nBitsExceeded += *nBytesOut * 8;
|
||||
psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
|
||||
psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
|
||||
|
||||
/* Update flag indicating if bandwidth switching is allowed */
|
||||
speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
|
||||
SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
|
||||
if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
|
||||
psEnc->allowBandwidthSwitch = 1;
|
||||
psEnc->timeSinceSwitchAllowed_ms = 0;
|
||||
} else {
|
||||
psEnc->allowBandwidthSwitch = 0;
|
||||
psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
|
||||
}
|
||||
}
|
||||
|
||||
if( nSamplesIn == 0 ) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
curr_block++;
|
||||
}
|
||||
|
||||
psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;
|
||||
|
||||
encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
|
||||
encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
|
||||
encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
|
||||
encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
|
||||
if( prefillFlag ) {
|
||||
encControl->payloadSize_ms = tmp_payloadSize_ms;
|
||||
encControl->complexity = tmp_complexity;
|
||||
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
|
||||
psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
|
||||
psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
181
node_modules/node-opus/deps/opus/silk/encode_indices.c
generated
vendored
Normal file
181
node_modules/node-opus/deps/opus/silk/encode_indices.c
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
|
||||
/* Encode side-information parameters to payload */
|
||||
void silk_encode_indices(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
ec_enc *psRangeEnc, /* I/O Compressor data structure */
|
||||
opus_int FrameIndex, /* I Frame number */
|
||||
opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int i, k, typeOffset;
|
||||
opus_int encode_absolute_lagIndex, delta_lagIndex;
|
||||
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||
const SideInfoIndices *psIndices;
|
||||
|
||||
if( encode_LBRR ) {
|
||||
psIndices = &psEncC->indices_LBRR[ FrameIndex ];
|
||||
} else {
|
||||
psIndices = &psEncC->indices;
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
/* Encode signal type and quantizer offset */
|
||||
/*******************************************/
|
||||
typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;
|
||||
silk_assert( typeOffset >= 0 && typeOffset < 6 );
|
||||
silk_assert( encode_LBRR == 0 || typeOffset >= 2 );
|
||||
if( encode_LBRR || typeOffset >= 2 ) {
|
||||
ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );
|
||||
} else {
|
||||
ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 );
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode gains */
|
||||
/****************/
|
||||
/* first subframe */
|
||||
if( condCoding == CODE_CONDITIONALLY ) {
|
||||
/* conditional coding */
|
||||
silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 );
|
||||
} else {
|
||||
/* independent coding, in two stages: MSB bits followed by 3 LSBs */
|
||||
silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN );
|
||||
ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 );
|
||||
}
|
||||
|
||||
/* remaining subframes */
|
||||
for( i = 1; i < psEncC->nb_subfr; i++ ) {
|
||||
silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 );
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode NLSFs */
|
||||
/****************/
|
||||
ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );
|
||||
silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );
|
||||
silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
|
||||
for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {
|
||||
if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
|
||||
} else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) {
|
||||
ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
|
||||
ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
|
||||
} else {
|
||||
ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Encode NLSF interpolation factor */
|
||||
if( psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||
silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 );
|
||||
}
|
||||
|
||||
if( psIndices->signalType == TYPE_VOICED )
|
||||
{
|
||||
/*********************/
|
||||
/* Encode pitch lags */
|
||||
/*********************/
|
||||
/* lag index */
|
||||
encode_absolute_lagIndex = 1;
|
||||
if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) {
|
||||
/* Delta Encoding */
|
||||
delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex;
|
||||
if( delta_lagIndex < -8 || delta_lagIndex > 11 ) {
|
||||
delta_lagIndex = 0;
|
||||
} else {
|
||||
delta_lagIndex = delta_lagIndex + 9;
|
||||
encode_absolute_lagIndex = 0; /* Only use delta */
|
||||
}
|
||||
silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 );
|
||||
ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 );
|
||||
}
|
||||
if( encode_absolute_lagIndex ) {
|
||||
/* Absolute encoding */
|
||||
opus_int32 pitch_high_bits, pitch_low_bits;
|
||||
pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
|
||||
pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
|
||||
silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 );
|
||||
silk_assert( pitch_high_bits < 32 );
|
||||
ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 );
|
||||
ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 );
|
||||
}
|
||||
psEncC->ec_prevLagIndex = psIndices->lagIndex;
|
||||
|
||||
/* Countour index */
|
||||
silk_assert( psIndices->contourIndex >= 0 );
|
||||
silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) ||
|
||||
( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) ||
|
||||
( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) ||
|
||||
( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 );
|
||||
|
||||
/********************/
|
||||
/* Encode LTP gains */
|
||||
/********************/
|
||||
/* PERIndex value */
|
||||
silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 );
|
||||
|
||||
/* Codebook Indices */
|
||||
for( k = 0; k < psEncC->nb_subfr; k++ ) {
|
||||
silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 );
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Encode LTP scaling */
|
||||
/**********************/
|
||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||
silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 );
|
||||
}
|
||||
silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 );
|
||||
}
|
||||
|
||||
psEncC->ec_prevSignalType = psIndices->signalType;
|
||||
|
||||
/***************/
|
||||
/* Encode seed */
|
||||
/***************/
|
||||
silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 );
|
||||
ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 );
|
||||
}
|
206
node_modules/node-opus/deps/opus/silk/encode_pulses.c
generated
vendored
Normal file
206
node_modules/node-opus/deps/opus/silk/encode_pulses.c
generated
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/*********************************************/
|
||||
/* Encode quantization indices of excitation */
|
||||
/*********************************************/
|
||||
|
||||
static OPUS_INLINE opus_int combine_and_check( /* return ok */
|
||||
opus_int *pulses_comb, /* O */
|
||||
const opus_int *pulses_in, /* I */
|
||||
opus_int max_pulses, /* I max value for sum of pulses */
|
||||
opus_int len /* I number of output values */
|
||||
)
|
||||
{
|
||||
opus_int k, sum;
|
||||
|
||||
for( k = 0; k < len; k++ ) {
|
||||
sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
|
||||
if( sum > max_pulses ) {
|
||||
return 1;
|
||||
}
|
||||
pulses_comb[ k ] = sum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encode quantization indices of excitation */
|
||||
void silk_encode_pulses(
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
const opus_int signalType, /* I Signal type */
|
||||
const opus_int quantOffsetType, /* I quantOffsetType */
|
||||
opus_int8 pulses[], /* I quantization indices */
|
||||
const opus_int frame_length /* I Frame length */
|
||||
)
|
||||
{
|
||||
opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
|
||||
opus_int32 abs_q, minSumBits_Q5, sumBits_Q5;
|
||||
VARDECL( opus_int, abs_pulses );
|
||||
VARDECL( opus_int, sum_pulses );
|
||||
VARDECL( opus_int, nRshifts );
|
||||
opus_int pulses_comb[ 8 ];
|
||||
opus_int *abs_pulses_ptr;
|
||||
const opus_int8 *pulses_ptr;
|
||||
const opus_uint8 *cdf_ptr;
|
||||
const opus_uint8 *nBits_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/
|
||||
|
||||
/****************************/
|
||||
/* Prepare for shell coding */
|
||||
/****************************/
|
||||
/* Calculate number of shell blocks */
|
||||
silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
|
||||
iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
|
||||
if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
|
||||
silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
|
||||
iter++;
|
||||
silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));
|
||||
}
|
||||
|
||||
/* Take the absolute value of the pulses */
|
||||
ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int );
|
||||
silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) );
|
||||
for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) {
|
||||
abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] );
|
||||
abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] );
|
||||
abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] );
|
||||
abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] );
|
||||
}
|
||||
|
||||
/* Calc sum pulses per shell code frame */
|
||||
ALLOC( sum_pulses, iter, opus_int );
|
||||
ALLOC( nRshifts, iter, opus_int );
|
||||
abs_pulses_ptr = abs_pulses;
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
nRshifts[ i ] = 0;
|
||||
|
||||
while( 1 ) {
|
||||
/* 1+1 -> 2 */
|
||||
scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 );
|
||||
/* 2+2 -> 4 */
|
||||
scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 );
|
||||
/* 4+4 -> 8 */
|
||||
scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 );
|
||||
/* 8+8 -> 16 */
|
||||
scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 );
|
||||
|
||||
if( scale_down ) {
|
||||
/* We need to downscale the quantization signal */
|
||||
nRshifts[ i ]++;
|
||||
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||
abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 );
|
||||
}
|
||||
} else {
|
||||
/* Jump out of while(1) loop and go to next shell coding frame */
|
||||
break;
|
||||
}
|
||||
}
|
||||
abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
|
||||
}
|
||||
|
||||
/**************/
|
||||
/* Rate level */
|
||||
/**************/
|
||||
/* find rate level that leads to fewest bits for coding of pulses per block info */
|
||||
minSumBits_Q5 = silk_int32_MAX;
|
||||
for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
|
||||
nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ];
|
||||
sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ];
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( nRshifts[ i ] > 0 ) {
|
||||
sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ];
|
||||
} else {
|
||||
sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ];
|
||||
}
|
||||
}
|
||||
if( sumBits_Q5 < minSumBits_Q5 ) {
|
||||
minSumBits_Q5 = sumBits_Q5;
|
||||
RateLevelIndex = k;
|
||||
}
|
||||
}
|
||||
ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );
|
||||
|
||||
/***************************************************/
|
||||
/* Sum-Weighted-Pulses Encoding */
|
||||
/***************************************************/
|
||||
cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( nRshifts[ i ] == 0 ) {
|
||||
ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 );
|
||||
} else {
|
||||
ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 );
|
||||
for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
|
||||
ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
|
||||
}
|
||||
ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
|
||||
}
|
||||
}
|
||||
|
||||
/******************/
|
||||
/* Shell Encoding */
|
||||
/******************/
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( sum_pulses[ i ] > 0 ) {
|
||||
silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* LSB Encoding */
|
||||
/****************/
|
||||
for( i = 0; i < iter; i++ ) {
|
||||
if( nRshifts[ i ] > 0 ) {
|
||||
pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ];
|
||||
nLS = nRshifts[ i ] - 1;
|
||||
for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
|
||||
abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] );
|
||||
for( j = nLS; j > 0; j-- ) {
|
||||
bit = silk_RSHIFT( abs_q, j ) & 1;
|
||||
ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
|
||||
}
|
||||
bit = abs_q & 1;
|
||||
ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode signs */
|
||||
/****************/
|
||||
silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses );
|
||||
RESTORE_STACK;
|
||||
}
|
98
node_modules/node-opus/deps/opus/silk/errors.h
generated
vendored
Normal file
98
node_modules/node-opus/deps/opus/silk/errors.h
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_ERRORS_H
|
||||
#define SILK_ERRORS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************/
|
||||
/* Error messages */
|
||||
/******************/
|
||||
#define SILK_NO_ERROR 0
|
||||
|
||||
/**************************/
|
||||
/* Encoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Input length is not a multiple of 10 ms, or length is longer than the packet length */
|
||||
#define SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -101
|
||||
|
||||
/* Sampling frequency not 8000, 12000 or 16000 Hertz */
|
||||
#define SILK_ENC_FS_NOT_SUPPORTED -102
|
||||
|
||||
/* Packet size not 10, 20, 40, or 60 ms */
|
||||
#define SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -103
|
||||
|
||||
/* Allocated payload buffer too short */
|
||||
#define SILK_ENC_PAYLOAD_BUF_TOO_SHORT -104
|
||||
|
||||
/* Loss rate not between 0 and 100 percent */
|
||||
#define SILK_ENC_INVALID_LOSS_RATE -105
|
||||
|
||||
/* Complexity setting not valid, use 0...10 */
|
||||
#define SILK_ENC_INVALID_COMPLEXITY_SETTING -106
|
||||
|
||||
/* Inband FEC setting not valid, use 0 or 1 */
|
||||
#define SILK_ENC_INVALID_INBAND_FEC_SETTING -107
|
||||
|
||||
/* DTX setting not valid, use 0 or 1 */
|
||||
#define SILK_ENC_INVALID_DTX_SETTING -108
|
||||
|
||||
/* CBR setting not valid, use 0 or 1 */
|
||||
#define SILK_ENC_INVALID_CBR_SETTING -109
|
||||
|
||||
/* Internal encoder error */
|
||||
#define SILK_ENC_INTERNAL_ERROR -110
|
||||
|
||||
/* Internal encoder error */
|
||||
#define SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR -111
|
||||
|
||||
/**************************/
|
||||
/* Decoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Output sampling frequency lower than internal decoded sampling frequency */
|
||||
#define SILK_DEC_INVALID_SAMPLING_FREQUENCY -200
|
||||
|
||||
/* Payload size exceeded the maximum allowed 1024 bytes */
|
||||
#define SILK_DEC_PAYLOAD_TOO_LARGE -201
|
||||
|
||||
/* Payload has bit errors */
|
||||
#define SILK_DEC_PAYLOAD_ERROR -202
|
||||
|
||||
/* Payload has bit errors */
|
||||
#define SILK_DEC_INVALID_FRAME_SIZE -203
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
90
node_modules/node-opus/deps/opus/silk/fixed/LTP_analysis_filter_FIX.c
generated
vendored
Normal file
90
node_modules/node-opus/deps/opus/silk/fixed/LTP_analysis_filter_FIX.c
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
|
||||
void silk_LTP_analysis_filter_FIX(
|
||||
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
|
||||
const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
|
||||
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
|
||||
const opus_int subfr_length, /* I Length of each subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
|
||||
)
|
||||
{
|
||||
const opus_int16 *x_ptr, *x_lag_ptr;
|
||||
opus_int16 Btmp_Q14[ LTP_ORDER ];
|
||||
opus_int16 *LTP_res_ptr;
|
||||
opus_int k, i;
|
||||
opus_int32 LTP_est;
|
||||
|
||||
x_ptr = x;
|
||||
LTP_res_ptr = LTP_res;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
|
||||
x_lag_ptr = x_ptr - pitchL[ k ];
|
||||
|
||||
Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ];
|
||||
Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ];
|
||||
Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ];
|
||||
Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ];
|
||||
Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ];
|
||||
|
||||
/* LTP analysis FIR filter */
|
||||
for( i = 0; i < subfr_length + pre_length; i++ ) {
|
||||
LTP_res_ptr[ i ] = x_ptr[ i ];
|
||||
|
||||
/* Long-term prediction */
|
||||
LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] );
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] );
|
||||
|
||||
LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
|
||||
|
||||
/* Subtract long-term prediction */
|
||||
LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );
|
||||
|
||||
/* Scale residual */
|
||||
LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
|
||||
|
||||
x_lag_ptr++;
|
||||
}
|
||||
|
||||
/* Update pointers */
|
||||
LTP_res_ptr += subfr_length + pre_length;
|
||||
x_ptr += subfr_length;
|
||||
}
|
||||
}
|
||||
|
53
node_modules/node-opus/deps/opus/silk/fixed/LTP_scale_ctrl_FIX.c
generated
vendored
Normal file
53
node_modules/node-opus/deps/opus/silk/fixed/LTP_scale_ctrl_FIX.c
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
|
||||
/* Calculation of LTP state scaling */
|
||||
void silk_LTP_scale_ctrl_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int round_loss;
|
||||
|
||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||
/* Only scale if first frame in packet */
|
||||
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
|
||||
silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
|
||||
} else {
|
||||
/* Default is minimum scaling */
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
||||
}
|
||||
psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];
|
||||
}
|
101
node_modules/node-opus/deps/opus/silk/fixed/apply_sine_window_FIX.c
generated
vendored
Normal file
101
node_modules/node-opus/deps/opus/silk/fixed/apply_sine_window_FIX.c
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Apply sine window to signal vector. */
|
||||
/* Window types: */
|
||||
/* 1 -> sine window from 0 to pi/2 */
|
||||
/* 2 -> sine window from pi/2 to pi */
|
||||
/* Every other sample is linearly interpolated, for speed. */
|
||||
/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
|
||||
|
||||
/* Matlab code for table:
|
||||
for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
|
||||
*/
|
||||
static const opus_int16 freq_table_Q16[ 27 ] = {
|
||||
12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
|
||||
3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
|
||||
2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
|
||||
};
|
||||
|
||||
void silk_apply_sine_window(
|
||||
opus_int16 px_win[], /* O Pointer to windowed signal */
|
||||
const opus_int16 px[], /* I Pointer to input signal */
|
||||
const opus_int win_type, /* I Selects a window type */
|
||||
const opus_int length /* I Window length, multiple of 4 */
|
||||
)
|
||||
{
|
||||
opus_int k, f_Q16, c_Q16;
|
||||
opus_int32 S0_Q16, S1_Q16;
|
||||
|
||||
silk_assert( win_type == 1 || win_type == 2 );
|
||||
|
||||
/* Length must be in a range from 16 to 120 and a multiple of 4 */
|
||||
silk_assert( length >= 16 && length <= 120 );
|
||||
silk_assert( ( length & 3 ) == 0 );
|
||||
|
||||
/* Frequency */
|
||||
k = ( length >> 2 ) - 4;
|
||||
silk_assert( k >= 0 && k <= 26 );
|
||||
f_Q16 = (opus_int)freq_table_Q16[ k ];
|
||||
|
||||
/* Factor used for cosine approximation */
|
||||
c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 );
|
||||
silk_assert( c_Q16 >= -32768 );
|
||||
|
||||
/* initialize state */
|
||||
if( win_type == 1 ) {
|
||||
/* start from 0 */
|
||||
S0_Q16 = 0;
|
||||
/* approximation of sin(f) */
|
||||
S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );
|
||||
} else {
|
||||
/* start from 1 */
|
||||
S0_Q16 = ( (opus_int32)1 << 16 );
|
||||
/* approximation of cos(f) */
|
||||
S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );
|
||||
}
|
||||
|
||||
/* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
|
||||
/* 4 samples at a time */
|
||||
for( k = 0; k < length; k += 4 ) {
|
||||
px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
|
||||
px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );
|
||||
S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
|
||||
S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) );
|
||||
|
||||
px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
|
||||
px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );
|
||||
S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;
|
||||
S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) );
|
||||
}
|
||||
}
|
48
node_modules/node-opus/deps/opus/silk/fixed/autocorr_FIX.c
generated
vendored
Normal file
48
node_modules/node-opus/deps/opus/silk/fixed/autocorr_FIX.c
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
#include "celt_lpc.h"
|
||||
|
||||
/* Compute autocorrelation */
|
||||
void silk_autocorr(
|
||||
opus_int32 *results, /* O Result (length correlationCount) */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *inputData, /* I Input data to correlate */
|
||||
const opus_int inputDataSize, /* I Length of input */
|
||||
const opus_int correlationCount, /* I Number of correlation taps to compute */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int corrCount;
|
||||
corrCount = silk_min_int( inputDataSize, correlationCount );
|
||||
*scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch);
|
||||
}
|
275
node_modules/node-opus/deps/opus/silk/fixed/burg_modified_FIX.c
generated
vendored
Normal file
275
node_modules/node-opus/deps/opus/silk/fixed/burg_modified_FIX.c
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
#include "define.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "pitch.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||
|
||||
#define QA 25
|
||||
#define N_BITS_HEAD_ROOM 2
|
||||
#define MIN_RSHIFTS -16
|
||||
#define MAX_RSHIFTS (32 - QA)
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
void silk_burg_modified_c(
|
||||
opus_int32 *res_nrg, /* O Residual energy */
|
||||
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
||||
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
||||
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||
const opus_int D, /* I Order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, reached_max_gain;
|
||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int64 C0_64;
|
||||
|
||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* Compute autocorrelations, added over subframes */
|
||||
C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
|
||||
lz = silk_CLZ64(C0_64);
|
||||
rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
|
||||
if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
|
||||
if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
|
||||
|
||||
if (rshifts > 0) {
|
||||
C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
|
||||
} else {
|
||||
C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
|
||||
}
|
||||
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
|
||||
silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
int i;
|
||||
opus_int32 d;
|
||||
x_ptr = x + s * subfr_length;
|
||||
celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
|
||||
d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
|
||||
xcorr[ n - 1 ] += d;
|
||||
}
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
|
||||
}
|
||||
}
|
||||
}
|
||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
|
||||
/* Initialize */
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
|
||||
invGain_Q30 = (opus_int32)1 << 30;
|
||||
reached_max_gain = 0;
|
||||
for( n = 0; n < D; n++ ) {
|
||||
/* Update first row of correlation matrix (without first element) */
|
||||
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||
/* Update C * Af */
|
||||
/* Update C * flipud(Af) (stored in reversed order) */
|
||||
if( rshifts > -2 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
|
||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
|
||||
for( k = 0; k < n; k++ ) {
|
||||
C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||
C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||
Atmp_QA = Af_QA[ k ];
|
||||
tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
|
||||
tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
|
||||
}
|
||||
tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||
tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||
for( k = 0; k <= n; k++ ) {
|
||||
CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
|
||||
CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
|
||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
|
||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
|
||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
|
||||
for( k = 0; k < n; k++ ) {
|
||||
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
|
||||
tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||
}
|
||||
tmp1 = -tmp1; /* Q17 */
|
||||
tmp2 = -tmp2; /* Q17 */
|
||||
for( k = 0; k <= n; k++ ) {
|
||||
CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
|
||||
silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||
CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
|
||||
silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
||||
tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
|
||||
tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
|
||||
num = 0; /* Q( -rshifts ) */
|
||||
nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
|
||||
for( k = 0; k < n; k++ ) {
|
||||
Atmp_QA = Af_QA[ k ];
|
||||
lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
|
||||
lz = silk_min( 32 - QA, lz );
|
||||
Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
|
||||
|
||||
tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
|
||||
Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
|
||||
}
|
||||
CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
|
||||
CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
|
||||
num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
|
||||
num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
|
||||
|
||||
/* Calculate the next order reflection (parcor) coefficient */
|
||||
if( silk_abs( num ) < nrg ) {
|
||||
rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
|
||||
} else {
|
||||
rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
|
||||
}
|
||||
|
||||
/* Update inverse prediction gain */
|
||||
tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
|
||||
if( tmp1 <= minInvGain_Q30 ) {
|
||||
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
|
||||
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
|
||||
/* Newton-Raphson iteration */
|
||||
rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
|
||||
rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
|
||||
if( num < 0 ) {
|
||||
/* Ensure adjusted reflection coefficients has the original sign */
|
||||
rc_Q31 = -rc_Q31;
|
||||
}
|
||||
invGain_Q30 = minInvGain_Q30;
|
||||
reached_max_gain = 1;
|
||||
} else {
|
||||
invGain_Q30 = tmp1;
|
||||
}
|
||||
|
||||
/* Update the AR coefficients */
|
||||
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||
tmp1 = Af_QA[ k ]; /* QA */
|
||||
tmp2 = Af_QA[ n - k - 1 ]; /* QA */
|
||||
Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
|
||||
Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
|
||||
}
|
||||
Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||
for( k = n + 1; k < D; k++ ) {
|
||||
Af_QA[ k ] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update C * Af and C * Ab */
|
||||
for( k = 0; k <= n + 1; k++ ) {
|
||||
tmp1 = CAf[ k ]; /* Q( -rshifts ) */
|
||||
tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
|
||||
CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||
CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||
}
|
||||
}
|
||||
|
||||
if( reached_max_gain ) {
|
||||
for( k = 0; k < D; k++ ) {
|
||||
/* Scale coefficients */
|
||||
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
|
||||
}
|
||||
/* Subtract energy of preceding samples from C0 */
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);
|
||||
}
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
*res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
|
||||
*res_nrg_Q = -rshifts;
|
||||
} else {
|
||||
/* Return residual energy */
|
||||
nrg = CAf[ 0 ]; /* Q( -rshifts ) */
|
||||
tmp1 = (opus_int32)1 << 16; /* Q16 */
|
||||
for( k = 0; k < D; k++ ) {
|
||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
|
||||
nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
|
||||
tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
|
||||
A_Q16[ k ] = -Atmp1;
|
||||
}
|
||||
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||
*res_nrg_Q = -rshifts;
|
||||
}
|
||||
}
|
158
node_modules/node-opus/deps/opus/silk/fixed/corrMatrix_FIX.c
generated
vendored
Normal file
158
node_modules/node-opus/deps/opus/silk/fixed/corrMatrix_FIX.c
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/**********************************************************************
|
||||
* Correlation Matrix Computations for LS estimate.
|
||||
**********************************************************************/
|
||||
|
||||
#include "main_FIX.h"
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
void silk_corrVector_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int16 *t, /* I Target vector [L] */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int lag, i;
|
||||
const opus_int16 *ptr1, *ptr2;
|
||||
opus_int32 inner_prod;
|
||||
|
||||
ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
|
||||
ptr2 = t;
|
||||
/* Calculate X'*t */
|
||||
if( rshifts > 0 ) {
|
||||
/* Right shifting used */
|
||||
for( lag = 0; lag < order; lag++ ) {
|
||||
inner_prod = 0;
|
||||
for( i = 0; i < L; i++ ) {
|
||||
inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
|
||||
}
|
||||
Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
}
|
||||
} else {
|
||||
silk_assert( rshifts == 0 );
|
||||
for( lag = 0; lag < order; lag++ ) {
|
||||
Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates correlation matrix X'*X */
|
||||
void silk_corrMatrix_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
const opus_int head_room, /* I Desired headroom */
|
||||
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
|
||||
opus_int *rshifts, /* I/O Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, j, lag, rshifts_local, head_room_rshifts;
|
||||
opus_int32 energy;
|
||||
const opus_int16 *ptr1, *ptr2;
|
||||
|
||||
/* Calculate energy to find shift used to fit in 32 bits */
|
||||
silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
|
||||
/* Add shifts to get the desired head room */
|
||||
head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 );
|
||||
|
||||
energy = silk_RSHIFT32( energy, head_room_rshifts );
|
||||
rshifts_local += head_room_rshifts;
|
||||
|
||||
/* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
|
||||
/* Remove contribution of first order - 1 samples */
|
||||
for( i = 0; i < order - 1; i++ ) {
|
||||
energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local );
|
||||
}
|
||||
if( rshifts_local < *rshifts ) {
|
||||
/* Adjust energy */
|
||||
energy = silk_RSHIFT32( energy, *rshifts - rshifts_local );
|
||||
rshifts_local = *rshifts;
|
||||
}
|
||||
|
||||
/* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
|
||||
/* Fill out the diagonal of the correlation matrix */
|
||||
matrix_ptr( XX, 0, 0, order ) = energy;
|
||||
ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
|
||||
for( j = 1; j < order; j++ ) {
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
|
||||
matrix_ptr( XX, j, j, order ) = energy;
|
||||
}
|
||||
|
||||
ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
|
||||
/* Calculate the remaining elements of the correlation matrix */
|
||||
if( rshifts_local > 0 ) {
|
||||
/* Right shifting used */
|
||||
for( lag = 1; lag < order; lag++ ) {
|
||||
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||
energy = 0;
|
||||
for( i = 0; i < L; i++ ) {
|
||||
energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
|
||||
}
|
||||
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||
for( j = 1; j < ( order - lag ); j++ ) {
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
|
||||
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||
}
|
||||
ptr2--; /* Update pointer to first sample of next column (lag) in X */
|
||||
}
|
||||
} else {
|
||||
for( lag = 1; lag < order; lag++ ) {
|
||||
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
|
||||
energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch );
|
||||
matrix_ptr( XX, lag, 0, order ) = energy;
|
||||
matrix_ptr( XX, 0, lag, order ) = energy;
|
||||
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
|
||||
for( j = 1; j < ( order - lag ); j++ ) {
|
||||
energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
|
||||
energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
|
||||
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||
}
|
||||
ptr2--;/* Update pointer to first sample of next column (lag) in X */
|
||||
}
|
||||
}
|
||||
*rshifts = rshifts_local;
|
||||
}
|
||||
|
387
node_modules/node-opus/deps/opus/silk/fixed/encode_frame_FIX.c
generated
vendored
Normal file
387
node_modules/node-opus/deps/opus/silk/fixed/encode_frame_FIX.c
generated
vendored
Normal file
@ -0,0 +1,387 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||
const opus_int32 xfw_Q3[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
);
|
||||
|
||||
void silk_encode_do_VAD_FIX(
|
||||
silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
|
||||
)
|
||||
{
|
||||
/****************************/
|
||||
/* Voice Activity Detection */
|
||||
/****************************/
|
||||
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
|
||||
|
||||
/**************************************************/
|
||||
/* Convert speech activity into VAD and DTX flags */
|
||||
/**************************************************/
|
||||
if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
|
||||
psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
psEnc->sCmn.noSpeechCounter++;
|
||||
if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
} else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
}
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
|
||||
} else {
|
||||
psEnc->sCmn.noSpeechCounter = 0;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode frame */
|
||||
/****************/
|
||||
opus_int silk_encode_frame_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
opus_int maxBits, /* I If > 0: maximum number of output bits */
|
||||
opus_int useCBR /* I Flag to force constant-bitrate operation */
|
||||
)
|
||||
{
|
||||
silk_encoder_control_FIX sEncCtrl;
|
||||
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
||||
opus_int16 *x_frame;
|
||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||
opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
|
||||
opus_int32 gainsID, gainsID_lower, gainsID_upper;
|
||||
opus_int16 gainMult_Q8;
|
||||
opus_int16 ec_prevLagIndex_copy;
|
||||
opus_int ec_prevSignalType_copy;
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
SAVE_STACK;
|
||||
|
||||
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
|
||||
LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
|
||||
|
||||
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||
|
||||
/**************************************************************/
|
||||
/* Set up Input Pointers, and insert frame in input buffer */
|
||||
/*************************************************************/
|
||||
/* start of frame to encode */
|
||||
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/***************************************/
|
||||
/* Ensure smooth bandwidth transitions */
|
||||
/***************************************/
|
||||
silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
|
||||
|
||||
/*******************************************/
|
||||
/* Copy new frame to front of input buffer */
|
||||
/*******************************************/
|
||||
silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
|
||||
|
||||
if( !psEnc->sCmn.prefillFlag ) {
|
||||
VARDECL( opus_int32, xfw_Q3 );
|
||||
VARDECL( opus_int16, res_pitch );
|
||||
VARDECL( opus_uint8, ec_buf_copy );
|
||||
opus_int16 *res_pitch_frame;
|
||||
|
||||
ALLOC( res_pitch,
|
||||
psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
|
||||
+ psEnc->sCmn.ltp_mem_length, opus_int16 );
|
||||
/* start of pitch LPC residual frame */
|
||||
res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/*****************************************/
|
||||
/* Find pitch lags, initial LPC analysis */
|
||||
/*****************************************/
|
||||
silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
|
||||
|
||||
/************************/
|
||||
/* Noise shape analysis */
|
||||
/************************/
|
||||
silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
|
||||
|
||||
/***************************************************/
|
||||
/* Find linear prediction coefficients (LPC + LTP) */
|
||||
/***************************************************/
|
||||
silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Process gains */
|
||||
/****************************************/
|
||||
silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
|
||||
|
||||
/*****************************************/
|
||||
/* Prefiltering for noise shaper */
|
||||
/*****************************************/
|
||||
ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );
|
||||
silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );
|
||||
|
||||
/****************************************/
|
||||
/* Low Bitrate Redundant Encoding */
|
||||
/****************************************/
|
||||
silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding );
|
||||
|
||||
/* Loop over quantizer and entropy coding to control bitrate */
|
||||
maxIter = 6;
|
||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||
found_lower = 0;
|
||||
found_upper = 0;
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
gainsID_lower = -1;
|
||||
gainsID_upper = -1;
|
||||
/* Copy part of the input state */
|
||||
silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
seed_copy = psEnc->sCmn.indices.Seed;
|
||||
ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
|
||||
ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
|
||||
ALLOC( ec_buf_copy, 1275, opus_uint8 );
|
||||
for( iter = 0; ; iter++ ) {
|
||||
if( gainsID == gainsID_lower ) {
|
||||
nBits = nBits_lower;
|
||||
} else if( gainsID == gainsID_upper ) {
|
||||
nBits = nBits_upper;
|
||||
} else {
|
||||
/* Restore part of the input state */
|
||||
if( iter > 0 ) {
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
|
||||
psEnc->sCmn.indices.Seed = seed_copy;
|
||||
psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
|
||||
psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
|
||||
psEnc->sCmn.arch );
|
||||
} else {
|
||||
silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
|
||||
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
|
||||
psEnc->sCmn.arch);
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Encode Parameters */
|
||||
/****************************************/
|
||||
silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Encode Excitation Signal */
|
||||
/****************************************/
|
||||
silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
|
||||
psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
|
||||
|
||||
nBits = ec_tell( psRangeEnc );
|
||||
|
||||
if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( iter == maxIter ) {
|
||||
if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
|
||||
/* Restore output state from earlier iteration that did meet the bitrate budget */
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
|
||||
silk_assert( sRangeEnc_copy2.offs <= 1275 );
|
||||
silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
|
||||
psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( nBits > maxBits ) {
|
||||
if( found_lower == 0 && iter >= 2 ) {
|
||||
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
|
||||
sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
|
||||
found_upper = 0;
|
||||
gainsID_upper = -1;
|
||||
} else {
|
||||
found_upper = 1;
|
||||
nBits_upper = nBits;
|
||||
gainMult_upper = gainMult_Q8;
|
||||
gainsID_upper = gainsID;
|
||||
}
|
||||
} else if( nBits < maxBits - 5 ) {
|
||||
found_lower = 1;
|
||||
nBits_lower = nBits;
|
||||
gainMult_lower = gainMult_Q8;
|
||||
if( gainsID != gainsID_lower ) {
|
||||
gainsID_lower = gainsID;
|
||||
/* Copy part of the output state */
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_assert( psRangeEnc->offs <= 1275 );
|
||||
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
|
||||
silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
|
||||
}
|
||||
} else {
|
||||
/* Within 5 bits of budget: close enough */
|
||||
break;
|
||||
}
|
||||
|
||||
if( ( found_lower & found_upper ) == 0 ) {
|
||||
/* Adjust gain according to high-rate rate/distortion curve */
|
||||
opus_int32 gain_factor_Q16;
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
|
||||
if( nBits > maxBits ) {
|
||||
gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
|
||||
}
|
||||
gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
|
||||
} else {
|
||||
/* Adjust gain by interpolating */
|
||||
gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
|
||||
/* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
|
||||
if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
|
||||
} else
|
||||
if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
|
||||
}
|
||||
|
||||
/* Quantize gains */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
|
||||
&psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Unique identifier of gains vector */
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
}
|
||||
}
|
||||
|
||||
/* Update input buffer */
|
||||
silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
|
||||
( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
|
||||
|
||||
/* Exit without entropy coding */
|
||||
if( psEnc->sCmn.prefillFlag ) {
|
||||
/* No payload */
|
||||
*pnBytesOut = 0;
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parameters needed for next frame */
|
||||
psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||
psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
|
||||
|
||||
/****************************************/
|
||||
/* Finalize payload */
|
||||
/****************************************/
|
||||
psEnc->sCmn.first_frame_after_reset = 0;
|
||||
/* Payload size */
|
||||
*pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
|
||||
|
||||
RESTORE_STACK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
|
||||
const opus_int32 xfw_Q3[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
)
|
||||
{
|
||||
opus_int32 TempGains_Q16[ MAX_NB_SUBFR ];
|
||||
SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
|
||||
silk_nsq_state sNSQ_LBRR;
|
||||
|
||||
/*******************************************/
|
||||
/* Control use of inband LBRR */
|
||||
/*******************************************/
|
||||
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
|
||||
psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
|
||||
/* Copy noise shaping quantizer state and quantization indices from regular encoding */
|
||||
silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
|
||||
|
||||
/* Save original gains */
|
||||
silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
|
||||
if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
|
||||
/* First frame in packet or previous frame not LBRR coded */
|
||||
psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
|
||||
|
||||
/* Increase Gains to get target LBRR rate */
|
||||
psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
|
||||
psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
|
||||
}
|
||||
|
||||
/* Decode to get gains in sync with decoder */
|
||||
/* Overwrite unquantized gains with quantized gains */
|
||||
silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
|
||||
&psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
|
||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
} else {
|
||||
silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
|
||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
|
||||
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
}
|
||||
|
||||
/* Restore original gains */
|
||||
silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
}
|
||||
}
|
151
node_modules/node-opus/deps/opus/silk/fixed/find_LPC_FIX.c
generated
vendored
Normal file
151
node_modules/node-opus/deps/opus/silk/fixed/find_LPC_FIX.c
generated
vendored
Normal file
@ -0,0 +1,151 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Finds LPC vector from correlations, and converts to NLSF */
|
||||
void silk_find_LPC_FIX(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||
)
|
||||
{
|
||||
opus_int k, subfr_length;
|
||||
opus_int32 a_Q16[ MAX_LPC_ORDER ];
|
||||
opus_int isInterpLower, shift;
|
||||
opus_int32 res_nrg0, res_nrg1;
|
||||
opus_int rshift0, rshift1;
|
||||
|
||||
/* Used only for LSF interpolation */
|
||||
opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
|
||||
opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
|
||||
opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
|
||||
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||
SAVE_STACK;
|
||||
|
||||
subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
|
||||
|
||||
/* Default: no interpolation */
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = 4;
|
||||
|
||||
/* Burg AR analysis for the full frame */
|
||||
silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||
VARDECL( opus_int16, LPC_res );
|
||||
|
||||
/* Optimal solution for last 10 ms */
|
||||
silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
/* subtract residual energy here, as that's easier than adding it to the */
|
||||
/* residual energy of the first 10 ms in each iteration of the search below */
|
||||
shift = res_tmp_nrg_Q - res_nrg_Q;
|
||||
if( shift >= 0 ) {
|
||||
if( shift < 32 ) {
|
||||
res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );
|
||||
}
|
||||
} else {
|
||||
silk_assert( shift > -32 );
|
||||
res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
|
||||
res_nrg_Q = res_tmp_nrg_Q;
|
||||
}
|
||||
|
||||
/* Convert to NLSFs */
|
||||
silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
|
||||
|
||||
ALLOC( LPC_res, 2 * subfr_length, opus_int16 );
|
||||
|
||||
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||
for( k = 3; k >= 0; k-- ) {
|
||||
/* Interpolate NLSFs for first half */
|
||||
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||
|
||||
/* Convert to LPC for residual energy evaluation */
|
||||
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );
|
||||
|
||||
/* Calculate residual energy with NLSF interpolation */
|
||||
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder );
|
||||
silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );
|
||||
|
||||
/* Add subframe energies from first half frame */
|
||||
shift = rshift0 - rshift1;
|
||||
if( shift >= 0 ) {
|
||||
res_nrg1 = silk_RSHIFT( res_nrg1, shift );
|
||||
res_nrg_interp_Q = -rshift0;
|
||||
} else {
|
||||
res_nrg0 = silk_RSHIFT( res_nrg0, -shift );
|
||||
res_nrg_interp_Q = -rshift1;
|
||||
}
|
||||
res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );
|
||||
|
||||
/* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
|
||||
shift = res_nrg_interp_Q - res_nrg_Q;
|
||||
if( shift >= 0 ) {
|
||||
if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
|
||||
isInterpLower = silk_TRUE;
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
} else {
|
||||
if( -shift < 32 ) {
|
||||
if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {
|
||||
isInterpLower = silk_TRUE;
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
} else {
|
||||
isInterpLower = silk_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether current interpolated NLSFs are best so far */
|
||||
if( isInterpLower == silk_TRUE ) {
|
||||
/* Interpolation has lower residual energy */
|
||||
res_nrg = res_nrg_interp;
|
||||
res_nrg_Q = res_nrg_interp_Q;
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
|
||||
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||
silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
|
||||
}
|
||||
|
||||
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||
RESTORE_STACK;
|
||||
}
|
245
node_modules/node-opus/deps/opus/silk/fixed/find_LTP_FIX.c
generated
vendored
Normal file
245
node_modules/node-opus/deps/opus/silk/fixed/find_LTP_FIX.c
generated
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Head room for correlations */
|
||||
#define LTP_CORRS_HEAD_ROOM 2
|
||||
|
||||
void silk_fit_LTP(
|
||||
opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
|
||||
opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
|
||||
);
|
||||
|
||||
void silk_find_LTP_FIX(
|
||||
opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
|
||||
opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
opus_int *LTPredCodGain_Q7, /* O LTP coding gain */
|
||||
const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */
|
||||
const opus_int subfr_length, /* I subframe length */
|
||||
const opus_int nb_subfr, /* I number of subframes */
|
||||
const opus_int mem_offset, /* I number of samples in LTP memory */
|
||||
opus_int corr_rshifts[ MAX_NB_SUBFR ], /* O right shifts applied to correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, k, lshift;
|
||||
const opus_int16 *r_ptr, *lag_ptr;
|
||||
opus_int16 *b_Q14_ptr;
|
||||
|
||||
opus_int32 regu;
|
||||
opus_int32 *WLTP_ptr;
|
||||
opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;
|
||||
opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
|
||||
|
||||
opus_int32 temp32, denom32;
|
||||
opus_int extra_shifts;
|
||||
opus_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
|
||||
opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
|
||||
opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
|
||||
opus_int32 wd, m_Q12;
|
||||
|
||||
b_Q14_ptr = b_Q14;
|
||||
WLTP_ptr = WLTP;
|
||||
r_ptr = &r_lpc[ mem_offset ];
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
|
||||
|
||||
silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
|
||||
|
||||
/* Assure headroom */
|
||||
LZs = silk_CLZ32( rr[k] );
|
||||
if( LZs < LTP_CORRS_HEAD_ROOM ) {
|
||||
rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
|
||||
rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
|
||||
}
|
||||
corr_rshifts[ k ] = rr_shifts;
|
||||
silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ], arch ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
|
||||
|
||||
/* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
|
||||
silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ], arch ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */
|
||||
if( corr_rshifts[ k ] > rr_shifts ) {
|
||||
rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
|
||||
}
|
||||
silk_assert( rr[ k ] >= 0 );
|
||||
|
||||
regu = 1;
|
||||
regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||
regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||
regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
|
||||
silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
|
||||
|
||||
silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
|
||||
|
||||
/* Limit and store in Q14 */
|
||||
silk_fit_LTP( b_Q16, b_Q14_ptr );
|
||||
|
||||
/* Calculate residual energy */
|
||||
nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
|
||||
|
||||
/* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
|
||||
extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
|
||||
denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
||||
silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
|
||||
denom32 = silk_max( denom32, 1 );
|
||||
silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */
|
||||
temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
|
||||
temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
|
||||
|
||||
/* Limit temp such that the below scaling never wraps around */
|
||||
WLTP_max = 0;
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max );
|
||||
}
|
||||
lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
|
||||
silk_assert( 26 - 18 + lshift >= 0 );
|
||||
if( 26 - 18 + lshift < 31 ) {
|
||||
temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) );
|
||||
}
|
||||
|
||||
silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
|
||||
|
||||
w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
|
||||
silk_assert( w[k] >= 0 );
|
||||
|
||||
r_ptr += subfr_length;
|
||||
b_Q14_ptr += LTP_ORDER;
|
||||
WLTP_ptr += LTP_ORDER * LTP_ORDER;
|
||||
}
|
||||
|
||||
maxRshifts = 0;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts );
|
||||
}
|
||||
|
||||
/* Compute LTP coding gain */
|
||||
if( LTPredCodGain_Q7 != NULL ) {
|
||||
LPC_LTP_res_nrg = 0;
|
||||
LPC_res_nrg = 0;
|
||||
silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
LPC_res_nrg = silk_ADD32( LPC_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
|
||||
LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
|
||||
}
|
||||
LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
|
||||
|
||||
div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
|
||||
*LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
|
||||
|
||||
silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
|
||||
}
|
||||
|
||||
/* smoothing */
|
||||
/* d = sum( B, 1 ); */
|
||||
b_Q14_ptr = b_Q14;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
d_Q14[ k ] = 0;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
d_Q14[ k ] += b_Q14_ptr[ i ];
|
||||
}
|
||||
b_Q14_ptr += LTP_ORDER;
|
||||
}
|
||||
|
||||
/* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
|
||||
|
||||
/* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
|
||||
max_abs_d_Q14 = 0;
|
||||
max_w_bits = 0;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) );
|
||||
/* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
|
||||
/* Find bits needed in Q( 18 - maxRshifts ) */
|
||||
max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
|
||||
}
|
||||
|
||||
/* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */
|
||||
silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
|
||||
|
||||
/* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
|
||||
extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;
|
||||
|
||||
/* Subtract what we got available; bits in output var plus maxRshifts */
|
||||
extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
|
||||
extra_shifts = silk_max_int( extra_shifts, 0 );
|
||||
|
||||
maxRshifts_wxtra = maxRshifts + extra_shifts;
|
||||
|
||||
temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
|
||||
wd = 0;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
/* w has at least 2 bits of headroom so no overflow should happen */
|
||||
temp32 = silk_ADD32( temp32, silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */
|
||||
wd = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
|
||||
}
|
||||
m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );
|
||||
|
||||
b_Q14_ptr = b_Q14;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
/* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
|
||||
if( 2 - corr_rshifts[k] > 0 ) {
|
||||
temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
|
||||
} else {
|
||||
temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
|
||||
}
|
||||
|
||||
g_Q26 = silk_MUL(
|
||||
silk_DIV32(
|
||||
SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
|
||||
silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
|
||||
silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
|
||||
|
||||
temp32 = 0;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
|
||||
temp32 += delta_b_Q14[ i ]; /* Q14 */
|
||||
}
|
||||
temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14 -> Q12 */
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
|
||||
}
|
||||
b_Q14_ptr += LTP_ORDER;
|
||||
}
|
||||
}
|
||||
|
||||
void silk_fit_LTP(
|
||||
opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
|
||||
opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
|
||||
}
|
||||
}
|
145
node_modules/node-opus/deps/opus/silk/fixed/find_pitch_lags_FIX.c
generated
vendored
Normal file
145
node_modules/node-opus/deps/opus/silk/fixed/find_pitch_lags_FIX.c
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Find pitch lags */
|
||||
void silk_find_pitch_lags_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int16 res[], /* O residual */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int buf_len, i, scale;
|
||||
opus_int32 thrhld_Q13, res_nrg;
|
||||
const opus_int16 *x_buf, *x_buf_ptr;
|
||||
VARDECL( opus_int16, Wsig );
|
||||
opus_int16 *Wsig_ptr;
|
||||
opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
|
||||
opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
|
||||
SAVE_STACK;
|
||||
|
||||
/******************************************/
|
||||
/* Set up buffer lengths etc based on Fs */
|
||||
/******************************************/
|
||||
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/* Safety check */
|
||||
silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
|
||||
|
||||
x_buf = x - psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/*************************************/
|
||||
/* Estimate LPC AR coefficients */
|
||||
/*************************************/
|
||||
|
||||
/* Calculate windowed signal */
|
||||
|
||||
ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
|
||||
|
||||
/* First LA_LTP samples */
|
||||
x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
|
||||
Wsig_ptr = Wsig;
|
||||
silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
|
||||
|
||||
/* Middle un - windowed samples */
|
||||
Wsig_ptr += psEnc->sCmn.la_pitch;
|
||||
x_buf_ptr += psEnc->sCmn.la_pitch;
|
||||
silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
|
||||
|
||||
/* Last LA_LTP samples */
|
||||
Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||
x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||
silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
|
||||
|
||||
/* Calculate autocorrelation sequence */
|
||||
silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
|
||||
|
||||
/* Add white noise, as fraction of energy */
|
||||
auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
|
||||
/* Prediction gain */
|
||||
psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
|
||||
/* Convert From 32 bit Q24 to 16 bit Q12 coefs */
|
||||
for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
|
||||
A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
|
||||
}
|
||||
|
||||
/* Do BWE */
|
||||
silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
|
||||
|
||||
/*****************************************/
|
||||
/* LPC analysis filtering */
|
||||
/*****************************************/
|
||||
silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
|
||||
|
||||
if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
|
||||
/* Threshold for pitch estimator */
|
||||
thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 );
|
||||
thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 );
|
||||
thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );
|
||||
thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 );
|
||||
thrhld_Q13 = silk_SAT16( thrhld_Q13 );
|
||||
|
||||
/*****************************************/
|
||||
/* Call pitch estimator */
|
||||
/*****************************************/
|
||||
if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
|
||||
&psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
|
||||
(opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr,
|
||||
psEnc->sCmn.arch) == 0 )
|
||||
{
|
||||
psEnc->sCmn.indices.signalType = TYPE_VOICED;
|
||||
} else {
|
||||
psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
|
||||
}
|
||||
} else {
|
||||
silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
|
||||
psEnc->sCmn.indices.lagIndex = 0;
|
||||
psEnc->sCmn.indices.contourIndex = 0;
|
||||
psEnc->LTPCorr_Q15 = 0;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
148
node_modules/node-opus/deps/opus/silk/fixed/find_pred_coefs_FIX.c
generated
vendored
Normal file
148
node_modules/node-opus/deps/opus/silk/fixed/find_pred_coefs_FIX.c
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
void silk_find_pred_coefs_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
const opus_int16 res_pitch[], /* I Residual from pitch analysis */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
|
||||
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int16 *x_pre_ptr;
|
||||
VARDECL( opus_int16, LPC_in_pre );
|
||||
opus_int32 tmp, min_gain_Q16, minInvGain_Q30;
|
||||
opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ];
|
||||
SAVE_STACK;
|
||||
|
||||
/* weighting for weighted least squares */
|
||||
min_gain_Q16 = silk_int32_MAX >> 6;
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
|
||||
}
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
/* Divide to Q16 */
|
||||
silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
|
||||
/* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
|
||||
invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
|
||||
|
||||
/* Ensure Wght_Q15 a minimum value 1 */
|
||||
invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 );
|
||||
|
||||
/* Square the inverted gains */
|
||||
silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
|
||||
tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );
|
||||
Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 );
|
||||
|
||||
/* Invert the inverted and normalized gains */
|
||||
local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
|
||||
}
|
||||
|
||||
ALLOC( LPC_in_pre,
|
||||
psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
|
||||
+ psEnc->sCmn.frame_length, opus_int16 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
VARDECL( opus_int32, WLTP );
|
||||
|
||||
/**********/
|
||||
/* VOICED */
|
||||
/**********/
|
||||
silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
|
||||
|
||||
ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
|
||||
|
||||
/* LTP analysis */
|
||||
silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,
|
||||
res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,
|
||||
psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift, psEnc->sCmn.arch );
|
||||
|
||||
/* Quantize LTP gain parameters */
|
||||
silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
|
||||
&psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
|
||||
psEnc->sCmn.arch);
|
||||
|
||||
/* Control LTP scaling */
|
||||
silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
|
||||
|
||||
/* Create LTP residual */
|
||||
silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,
|
||||
psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
|
||||
|
||||
} else {
|
||||
/************/
|
||||
/* UNVOICED */
|
||||
/************/
|
||||
/* Create signal with prepended subframes, scaled by inverse gains */
|
||||
x_ptr = x - psEnc->sCmn.predictLPCOrder;
|
||||
x_pre_ptr = LPC_in_pre;
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
|
||||
psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
|
||||
x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
}
|
||||
|
||||
silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
|
||||
psEncCtrl->LTPredCodGain_Q7 = 0;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
}
|
||||
|
||||
/* Limit on total predictive coding gain */
|
||||
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||
minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
|
||||
} else {
|
||||
minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
|
||||
minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
|
||||
silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
|
||||
silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
|
||||
}
|
||||
|
||||
/* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
|
||||
silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );
|
||||
|
||||
/* Quantize LSFs */
|
||||
silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
|
||||
|
||||
/* Calculate residual energy using quantized LPC coefficients */
|
||||
silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
|
||||
psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch );
|
||||
|
||||
/* Copy to prediction struct for use in next frame for interpolation */
|
||||
silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
|
||||
RESTORE_STACK;
|
||||
}
|
53
node_modules/node-opus/deps/opus/silk/fixed/k2a_FIX.c
generated
vendored
Normal file
53
node_modules/node-opus/deps/opus/silk/fixed/k2a_FIX.c
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||
void silk_k2a(
|
||||
opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
|
||||
const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */
|
||||
const opus_int32 order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Atmp[ n ] = A_Q24[ n ];
|
||||
}
|
||||
for( n = 0; n < k; n++ ) {
|
||||
A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
|
||||
}
|
||||
A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
|
||||
}
|
||||
}
|
53
node_modules/node-opus/deps/opus/silk/fixed/k2a_Q16_FIX.c
generated
vendored
Normal file
53
node_modules/node-opus/deps/opus/silk/fixed/k2a_Q16_FIX.c
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Step up function, converts reflection coefficients to prediction coefficients */
|
||||
void silk_k2a_Q16(
|
||||
opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
|
||||
const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */
|
||||
const opus_int32 order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Atmp[ n ] = A_Q24[ n ];
|
||||
}
|
||||
for( n = 0; n < k; n++ ) {
|
||||
A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
|
||||
}
|
||||
A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );
|
||||
}
|
||||
}
|
272
node_modules/node-opus/deps/opus/silk/fixed/main_FIX.h
generated
vendored
Normal file
272
node_modules/node-opus/deps/opus/silk/fixed/main_FIX.h
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_MAIN_FIX_H
|
||||
#define SILK_MAIN_FIX_H
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "structs_FIX.h"
|
||||
#include "control.h"
|
||||
#include "main.h"
|
||||
#include "PLC.h"
|
||||
#include "debug.h"
|
||||
#include "entenc.h"
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define silk_encoder_state_Fxx silk_encoder_state_FIX
|
||||
#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
|
||||
#define silk_encode_frame_Fxx silk_encode_frame_FIX
|
||||
|
||||
/*********************/
|
||||
/* Encoder Functions */
|
||||
/*********************/
|
||||
|
||||
/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
|
||||
void silk_HP_variable_cutoff(
|
||||
silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
|
||||
);
|
||||
|
||||
/* Encoder main function */
|
||||
void silk_encode_do_VAD_FIX(
|
||||
silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
|
||||
);
|
||||
|
||||
/* Encoder main function */
|
||||
opus_int silk_encode_frame_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
opus_int maxBits, /* I If > 0: maximum number of output bits */
|
||||
opus_int useCBR /* I Flag to force constant-bitrate operation */
|
||||
);
|
||||
|
||||
/* Initializes the Silk encoder state */
|
||||
opus_int silk_init_encoder(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Control the Silk encoder */
|
||||
opus_int silk_control_encoder(
|
||||
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
|
||||
silk_EncControlStruct *encControl, /* I Control structure */
|
||||
const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
|
||||
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
|
||||
const opus_int channelNb, /* I Channel number */
|
||||
const opus_int force_fs_kHz
|
||||
);
|
||||
|
||||
/****************/
|
||||
/* Prefiltering */
|
||||
/****************/
|
||||
void silk_prefilter_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
||||
opus_int32 xw_Q10[], /* O Weighted signal */
|
||||
const opus_int16 x[] /* I Speech signal */
|
||||
);
|
||||
|
||||
void silk_warped_LPC_analysis_filter_FIX_c(
|
||||
opus_int32 state[], /* I/O State [order + 1] */
|
||||
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||
const opus_int16 input[], /* I Input signal [length] */
|
||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order /* I Filter order (even) */
|
||||
);
|
||||
|
||||
|
||||
/**************************/
|
||||
/* Noise shaping analysis */
|
||||
/**************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
void silk_warped_autocorrelation_FIX(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
);
|
||||
|
||||
/* Calculation of LTP state scaling */
|
||||
void silk_LTP_scale_ctrl_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/**********************************************/
|
||||
/* Prediction Analysis */
|
||||
/**********************************************/
|
||||
/* Find pitch lags */
|
||||
void silk_find_pitch_lags_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
opus_int16 res[], /* O residual */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Find LPC and LTP coefficients */
|
||||
void silk_find_pred_coefs_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
|
||||
const opus_int16 res_pitch[], /* I Residual from pitch analysis */
|
||||
const opus_int16 x[], /* I Speech signal */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/* LPC analysis */
|
||||
void silk_find_LPC_FIX(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
|
||||
);
|
||||
|
||||
/* LTP analysis */
|
||||
void silk_find_LTP_FIX(
|
||||
opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
|
||||
opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
opus_int *LTPredCodGain_Q7, /* O LTP coding gain */
|
||||
const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */
|
||||
const opus_int subfr_length, /* I subframe length */
|
||||
const opus_int nb_subfr, /* I number of subframes */
|
||||
const opus_int mem_offset, /* I number of samples in LTP memory */
|
||||
opus_int corr_rshifts[ MAX_NB_SUBFR ], /* O right shifts applied to correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_LTP_analysis_filter_FIX(
|
||||
opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
|
||||
const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
|
||||
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
|
||||
const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
|
||||
const opus_int subfr_length, /* I Length of each subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
|
||||
);
|
||||
|
||||
/* Calculates residual energies of input subframes where all subframes have LPC_order */
|
||||
/* of preceding samples */
|
||||
void silk_residual_energy_FIX(
|
||||
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
|
||||
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
|
||||
const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
|
||||
opus_int32 silk_residual_energy16_covar_FIX(
|
||||
const opus_int16 *c, /* I Prediction vector */
|
||||
const opus_int32 *wXX, /* I Correlation matrix */
|
||||
const opus_int32 *wXx, /* I Correlation vector */
|
||||
opus_int32 wxx, /* I Signal energy */
|
||||
opus_int D, /* I Dimension */
|
||||
opus_int cQ /* I Q value for c vector 0 - 15 */
|
||||
);
|
||||
|
||||
/* Processing of gains */
|
||||
void silk_process_gains_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Linear Algebra */
|
||||
/******************/
|
||||
/* Calculates correlation matrix X'*X */
|
||||
void silk_corrMatrix_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
const opus_int head_room, /* I Desired headroom */
|
||||
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
|
||||
opus_int *rshifts, /* I/O Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
void silk_corrVector_FIX(
|
||||
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
|
||||
const opus_int16 *t, /* I Target vector [L] */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int order, /* I Max lag for correlation */
|
||||
opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Add noise to matrix diagonal */
|
||||
void silk_regularize_correlations_FIX(
|
||||
opus_int32 *XX, /* I/O Correlation matrices */
|
||||
opus_int32 *xx, /* I/O Correlation values */
|
||||
opus_int32 noise, /* I Noise to add */
|
||||
opus_int D /* I Dimension of XX */
|
||||
);
|
||||
|
||||
/* Solves Ax = b, assuming A is symmetric */
|
||||
void silk_solve_LDL_FIX(
|
||||
opus_int32 *A, /* I Pointer to symetric square matrix A */
|
||||
opus_int M, /* I Size of matrix */
|
||||
const opus_int32 *b, /* I Pointer to b vector */
|
||||
opus_int32 *x_Q16 /* O Pointer to x solution vector */
|
||||
);
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* FORCE_CPP_BUILD */
|
||||
#endif /* SILK_MAIN_FIX_H */
|
336
node_modules/node-opus/deps/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
generated
vendored
Normal file
336
node_modules/node-opus/deps/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
generated
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/**************************************************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
/**************************************************************/
|
||||
#define OVERRIDE_silk_noise_shape_analysis_FIX
|
||||
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
|
||||
opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
|
||||
opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
|
||||
opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
|
||||
opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
VARDECL( opus_int16, x_windowed );
|
||||
const opus_int16 *x_ptr, *pitch_res_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Point to start of first LPC analysis block */
|
||||
x_ptr = x - psEnc->sCmn.la_shape;
|
||||
|
||||
/****************/
|
||||
/* GAIN CONTROL */
|
||||
/****************/
|
||||
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
||||
|
||||
/* Input quality is the average of the quality in the lowest two VAD bands */
|
||||
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
||||
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
||||
|
||||
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
||||
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
||||
SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
|
||||
|
||||
/* Reduce coding SNR during low speech activity */
|
||||
if( psEnc->sCmn.useCBR == 0 ) {
|
||||
b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
|
||||
b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
|
||||
}
|
||||
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce gains for periodic signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
|
||||
} else {
|
||||
/* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
|
||||
SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* SPARSENESS PROCESSING */
|
||||
/*************************/
|
||||
/* Set quantizer offset */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Initially set to 0; may be overruled in process_gains(..) */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
psEncCtrl->sparseness_Q8 = 0;
|
||||
} else {
|
||||
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
|
||||
nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
|
||||
energy_variation_Q7 = 0;
|
||||
log_energy_prev_Q7 = 0;
|
||||
pitch_res_ptr = pitch_res;
|
||||
for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
|
||||
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
|
||||
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
|
||||
|
||||
log_energy_Q7 = silk_lin2log( nrg );
|
||||
if( k > 0 ) {
|
||||
energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
|
||||
}
|
||||
log_energy_prev_Q7 = log_energy_Q7;
|
||||
pitch_res_ptr += nSamples;
|
||||
}
|
||||
|
||||
psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
|
||||
SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
|
||||
|
||||
/* Set quantization offset depending on sparseness measure */
|
||||
if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
|
||||
/* Increase coding SNR for sparse signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Control bandwidth expansion */
|
||||
/*******************************/
|
||||
/* More BWE for signals with high prediction gain */
|
||||
strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
|
||||
BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
|
||||
silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
|
||||
delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
|
||||
SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
|
||||
BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
|
||||
BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
|
||||
/* BWExp1 will be applied after BWExp2, so make it relative */
|
||||
BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
|
||||
} else {
|
||||
warping_Q16 = 0;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
/* Compute noise shaping AR coefs and gains */
|
||||
/********************************************/
|
||||
ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Apply window: sine slope followed by flat part followed by cosine slope */
|
||||
opus_int shift, slope_part, flat_part;
|
||||
flat_part = psEnc->sCmn.fs_kHz * 3;
|
||||
slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
|
||||
|
||||
silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
|
||||
shift = slope_part;
|
||||
silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
|
||||
shift += flat_part;
|
||||
silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
|
||||
|
||||
/* Update pointer: next LPC analysis block */
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Calculate warped auto correlation */
|
||||
silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
|
||||
} else {
|
||||
/* Calculate regular auto correlation */
|
||||
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
|
||||
}
|
||||
|
||||
/* Add white noise, as a fraction of energy */
|
||||
auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
|
||||
SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( nrg >= 0 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
Qnrg = -scale; /* range: -12...30*/
|
||||
silk_assert( Qnrg >= -12 );
|
||||
silk_assert( Qnrg <= 30 );
|
||||
|
||||
/* Make sure that Qnrg is an even number */
|
||||
if( Qnrg & 1 ) {
|
||||
Qnrg -= 1;
|
||||
nrg >>= 1;
|
||||
}
|
||||
|
||||
tmp32 = silk_SQRT_APPROX( nrg );
|
||||
Qnrg >>= 1; /* range: -6...15*/
|
||||
|
||||
psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \
|
||||
silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) ));
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Adjust gain for warping */
|
||||
gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Bandwidth expansion for synthesis filter shaping */
|
||||
silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
|
||||
|
||||
/* Compute noise shaping filter coefficients */
|
||||
silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
|
||||
|
||||
/* Bandwidth expansion for analysis filter shaping */
|
||||
silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
|
||||
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
|
||||
|
||||
/* Ratio of prediction gains, in energy domain */
|
||||
pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||
nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
|
||||
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
|
||||
psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
|
||||
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* Convert from Q24 to Q13 and store in int16 */
|
||||
for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
|
||||
psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
|
||||
psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/* Gain tweaking */
|
||||
/*****************/
|
||||
/* Increase gains during low speech activity and put lower limit on gains */
|
||||
gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
silk_assert( gain_mult_Q16 > 0 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
|
||||
}
|
||||
|
||||
gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
|
||||
psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Control low-frequency shaping and noise tilt */
|
||||
/************************************************/
|
||||
/* Less low frequency shaping for noisy inputs */
|
||||
strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
|
||||
SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
|
||||
strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
|
||||
/*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
|
||||
opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
}
|
||||
silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/
|
||||
Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
|
||||
silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
|
||||
} else {
|
||||
b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
|
||||
silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
|
||||
}
|
||||
Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* HARMONIC SHAPING CONTROL */
|
||||
/****************************/
|
||||
/* Control boosting of harmonic frequencies */
|
||||
HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
|
||||
psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
/* More harmonic boost for noisy input signals */
|
||||
HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* More harmonic noise shaping for high bitrates or noisy input */
|
||||
HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
|
||||
psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
|
||||
|
||||
/* Less harmonic noise shaping for less periodic signals */
|
||||
HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
|
||||
silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
|
||||
} else {
|
||||
HarmShapeGain_Q16 = 0;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Smooth over subframes */
|
||||
/*************************/
|
||||
for( k = 0; k < MAX_NB_SUBFR; k++ ) {
|
||||
psShapeSt->HarmBoost_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->HarmShapeGain_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->Tilt_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
|
||||
psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
|
||||
psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
|
||||
psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
184
node_modules/node-opus/deps/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h
generated
vendored
Normal file
184
node_modules/node-opus/deps/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
#ifndef __PREFILTER_FIX_MIPSR1_H__
|
||||
#define __PREFILTER_FIX_MIPSR1_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
#define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
|
||||
void silk_warped_LPC_analysis_filter_FIX(
|
||||
opus_int32 state[], /* I/O State [order + 1] */
|
||||
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||
const opus_int16 input[], /* I Input signal [length] */
|
||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order, /* I Filter order (even) */
|
||||
int arch
|
||||
)
|
||||
{
|
||||
opus_int n, i;
|
||||
opus_int32 acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4;
|
||||
opus_int32 state_cur, state_next;
|
||||
|
||||
(void)arch;
|
||||
|
||||
/* Order must be even */
|
||||
/* Length must be even */
|
||||
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( ( length & 1 ) == 0 );
|
||||
|
||||
for( n = 0; n < length; n+=2 ) {
|
||||
/* Output of lowpass section */
|
||||
tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
|
||||
state_cur = silk_LSHIFT( input[ n ], 14 );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
|
||||
state_next = tmp2;
|
||||
acc_Q11 = silk_RSHIFT( order, 1 );
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
|
||||
|
||||
|
||||
/* Output of lowpass section */
|
||||
tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 );
|
||||
state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 );
|
||||
/* Output of allpass section */
|
||||
tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
|
||||
state[ 1 ] = tmp4;
|
||||
acc_Q22 = silk_RSHIFT( order, 1 );
|
||||
acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] );
|
||||
|
||||
/* Loop over allpass sections */
|
||||
for( i = 2; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
|
||||
state_cur = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
|
||||
state_next = tmp2;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
|
||||
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 );
|
||||
state[ i ] = tmp3;
|
||||
acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
|
||||
state[ i + 1 ] = tmp4;
|
||||
acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] );
|
||||
}
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
|
||||
|
||||
state[ order ] = tmp3;
|
||||
acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] );
|
||||
res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Prefilter for finding Quantizer input signal */
|
||||
#define OVERRIDE_silk_prefilt_FIX
|
||||
static inline void silk_prefilt_FIX(
|
||||
silk_prefilter_state_FIX *P, /* I/O state */
|
||||
opus_int32 st_res_Q12[], /* I short term residual signal */
|
||||
opus_int32 xw_Q3[], /* O prefiltered signal */
|
||||
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
||||
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
||||
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
||||
opus_int lag, /* I Lag for harmonic shaping */
|
||||
opus_int length /* I Length of signals */
|
||||
)
|
||||
{
|
||||
opus_int i, idx, LTP_shp_buf_idx;
|
||||
opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
|
||||
opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
|
||||
opus_int16 *LTP_shp_buf;
|
||||
|
||||
/* To speed up use temp variables instead of using the struct */
|
||||
LTP_shp_buf = P->sLTP_shp;
|
||||
LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
|
||||
sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
|
||||
sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
|
||||
|
||||
if( lag > 0 ) {
|
||||
for( i = 0; i < length; i++ ) {
|
||||
/* unrolled loop */
|
||||
silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
|
||||
idx = lag + LTP_shp_buf_idx;
|
||||
n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
|
||||
n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
|
||||
n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
|
||||
|
||||
sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
|
||||
sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
|
||||
|
||||
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
||||
LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
|
||||
|
||||
xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < length; i++ ) {
|
||||
|
||||
n_LTP_Q12 = 0;
|
||||
|
||||
n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
|
||||
n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
|
||||
|
||||
sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
|
||||
sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
|
||||
|
||||
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
||||
LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
|
||||
|
||||
xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy temp variable back to state */
|
||||
P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
|
||||
P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
|
||||
P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
|
||||
}
|
||||
|
||||
#endif /* __PREFILTER_FIX_MIPSR1_H__ */
|
165
node_modules/node-opus/deps/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
generated
vendored
Normal file
165
node_modules/node-opus/deps/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
generated
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
|
||||
#define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "main_FIX.h"
|
||||
|
||||
#undef QC
|
||||
#define QC 10
|
||||
|
||||
#undef QS
|
||||
#define QS 14
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
#define OVERRIDE_silk_warped_autocorrelation_FIX
|
||||
void silk_warped_autocorrelation_FIX(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i, lsh;
|
||||
opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0;
|
||||
opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 temp64;
|
||||
|
||||
opus_int32 val;
|
||||
val = 2 * QS - QC;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( 2 * QS - QC >= 0 );
|
||||
|
||||
/* Loop over samples */
|
||||
for( n = 0; n < length; n=n+4 ) {
|
||||
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
start_1 = tmp1_QS;
|
||||
tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS );
|
||||
start_2 = tmp3_QS;
|
||||
tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS );
|
||||
start_3 = tmp5_QS;
|
||||
tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS );
|
||||
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1);
|
||||
|
||||
tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2);
|
||||
|
||||
tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 );
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3);
|
||||
|
||||
tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp7_QS;
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]);
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1);
|
||||
|
||||
tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2);
|
||||
|
||||
tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 );
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3);
|
||||
|
||||
tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp8_QS;
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]);
|
||||
|
||||
}
|
||||
state_QS[ order ] = tmp7_QS;
|
||||
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3);
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]);
|
||||
}
|
||||
|
||||
for(;n< length; n++ ) {
|
||||
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp1_QS;
|
||||
corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]);
|
||||
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp2_QS;
|
||||
corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]);
|
||||
}
|
||||
state_QS[ order ] = tmp1_QS;
|
||||
corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]);
|
||||
}
|
||||
|
||||
temp64 = corr_QC[ 0 ];
|
||||
temp64 = __builtin_mips_shilo(temp64, val);
|
||||
|
||||
lsh = silk_CLZ64( temp64 ) - 35;
|
||||
lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
|
||||
*scale = -( QC + lsh );
|
||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||
if( lsh >= 0 ) {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
temp64 = corr_QC[ i ];
|
||||
//temp64 = __builtin_mips_shilo(temp64, val);
|
||||
temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
temp64 = corr_QC[ i ];
|
||||
//temp64 = __builtin_mips_shilo(temp64, val);
|
||||
temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
|
||||
}
|
||||
}
|
||||
|
||||
corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val);
|
||||
|
||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||
}
|
||||
#endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */
|
451
node_modules/node-opus/deps/opus/silk/fixed/noise_shape_analysis_FIX.c
generated
vendored
Normal file
451
node_modules/node-opus/deps/opus/silk/fixed/noise_shape_analysis_FIX.c
generated
vendored
Normal file
@ -0,0 +1,451 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
|
||||
/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
|
||||
/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
|
||||
/* coefficient in an array of coefficients, for monic filters. */
|
||||
static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
|
||||
const opus_int32 *coefs_Q24,
|
||||
opus_int lambda_Q16,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i;
|
||||
opus_int32 gain_Q24;
|
||||
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
gain_Q24 = coefs_Q24[ order - 1 ];
|
||||
for( i = order - 2; i >= 0; i-- ) {
|
||||
gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
|
||||
}
|
||||
gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
|
||||
return silk_INVERSE32_varQ( gain_Q24, 40 );
|
||||
}
|
||||
|
||||
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
|
||||
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
|
||||
static OPUS_INLINE void limit_warped_coefs(
|
||||
opus_int32 *coefs_syn_Q24,
|
||||
opus_int32 *coefs_ana_Q24,
|
||||
opus_int lambda_Q16,
|
||||
opus_int32 limit_Q24,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i, iter, ind = 0;
|
||||
opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;
|
||||
opus_int32 nom_Q16, den_Q24;
|
||||
|
||||
/* Convert to monic coefficients */
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
|
||||
coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
|
||||
gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
|
||||
gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
|
||||
coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
|
||||
}
|
||||
|
||||
for( iter = 0; iter < 10; iter++ ) {
|
||||
/* Find maximum absolute value */
|
||||
maxabs_Q24 = -1;
|
||||
for( i = 0; i < order; i++ ) {
|
||||
tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) );
|
||||
if( tmp > maxabs_Q24 ) {
|
||||
maxabs_Q24 = tmp;
|
||||
ind = i;
|
||||
}
|
||||
}
|
||||
if( maxabs_Q24 <= limit_Q24 ) {
|
||||
/* Coefficients are within range - done */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert back to true warped coefficients */
|
||||
for( i = 1; i < order; i++ ) {
|
||||
coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
|
||||
coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );
|
||||
gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
|
||||
coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
|
||||
}
|
||||
|
||||
/* Apply bandwidth expansion */
|
||||
chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
|
||||
silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
|
||||
silk_MUL( maxabs_Q24, ind + 1 ), 22 );
|
||||
silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );
|
||||
silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );
|
||||
|
||||
/* Convert to monic warped coefficients */
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
|
||||
coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
lambda_Q16 = -lambda_Q16;
|
||||
nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
|
||||
gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
|
||||
gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
|
||||
coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
|
||||
}
|
||||
}
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/noise_shape_analysis_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
/**************************************************************/
|
||||
#ifndef OVERRIDE_silk_noise_shape_analysis_FIX
|
||||
void silk_noise_shape_analysis_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
|
||||
const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
|
||||
const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
|
||||
opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
|
||||
opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
|
||||
opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
|
||||
opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
VARDECL( opus_int16, x_windowed );
|
||||
const opus_int16 *x_ptr, *pitch_res_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
/* Point to start of first LPC analysis block */
|
||||
x_ptr = x - psEnc->sCmn.la_shape;
|
||||
|
||||
/****************/
|
||||
/* GAIN CONTROL */
|
||||
/****************/
|
||||
SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
|
||||
|
||||
/* Input quality is the average of the quality in the lowest two VAD bands */
|
||||
psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
|
||||
+ psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
|
||||
|
||||
/* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
|
||||
psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
|
||||
SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
|
||||
|
||||
/* Reduce coding SNR during low speech activity */
|
||||
if( psEnc->sCmn.useCBR == 0 ) {
|
||||
b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
|
||||
b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
|
||||
}
|
||||
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce gains for periodic signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
|
||||
} else {
|
||||
/* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
|
||||
silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
|
||||
SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* SPARSENESS PROCESSING */
|
||||
/*************************/
|
||||
/* Set quantizer offset */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Initially set to 0; may be overruled in process_gains(..) */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
psEncCtrl->sparseness_Q8 = 0;
|
||||
} else {
|
||||
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
|
||||
nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
|
||||
energy_variation_Q7 = 0;
|
||||
log_energy_prev_Q7 = 0;
|
||||
pitch_res_ptr = pitch_res;
|
||||
for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
|
||||
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
|
||||
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
|
||||
|
||||
log_energy_Q7 = silk_lin2log( nrg );
|
||||
if( k > 0 ) {
|
||||
energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
|
||||
}
|
||||
log_energy_prev_Q7 = log_energy_Q7;
|
||||
pitch_res_ptr += nSamples;
|
||||
}
|
||||
|
||||
psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
|
||||
SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
|
||||
|
||||
/* Set quantization offset depending on sparseness measure */
|
||||
if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
|
||||
/* Increase coding SNR for sparse signals */
|
||||
SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Control bandwidth expansion */
|
||||
/*******************************/
|
||||
/* More BWE for signals with high prediction gain */
|
||||
strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
|
||||
BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
|
||||
silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
|
||||
delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
|
||||
SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
|
||||
BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
|
||||
BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
|
||||
/* BWExp1 will be applied after BWExp2, so make it relative */
|
||||
BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
|
||||
} else {
|
||||
warping_Q16 = 0;
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
/* Compute noise shaping AR coefs and gains */
|
||||
/********************************************/
|
||||
ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Apply window: sine slope followed by flat part followed by cosine slope */
|
||||
opus_int shift, slope_part, flat_part;
|
||||
flat_part = psEnc->sCmn.fs_kHz * 3;
|
||||
slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
|
||||
|
||||
silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
|
||||
shift = slope_part;
|
||||
silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
|
||||
shift += flat_part;
|
||||
silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
|
||||
|
||||
/* Update pointer: next LPC analysis block */
|
||||
x_ptr += psEnc->sCmn.subfr_length;
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Calculate warped auto correlation */
|
||||
silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
|
||||
} else {
|
||||
/* Calculate regular auto correlation */
|
||||
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
|
||||
}
|
||||
|
||||
/* Add white noise, as a fraction of energy */
|
||||
auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
|
||||
SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
|
||||
|
||||
/* Calculate the reflection coefficients using schur */
|
||||
nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( nrg >= 0 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
Qnrg = -scale; /* range: -12...30*/
|
||||
silk_assert( Qnrg >= -12 );
|
||||
silk_assert( Qnrg <= 30 );
|
||||
|
||||
/* Make sure that Qnrg is an even number */
|
||||
if( Qnrg & 1 ) {
|
||||
Qnrg -= 1;
|
||||
nrg >>= 1;
|
||||
}
|
||||
|
||||
tmp32 = silk_SQRT_APPROX( nrg );
|
||||
Qnrg >>= 1; /* range: -6...15*/
|
||||
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Adjust gain for warping */
|
||||
gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Bandwidth expansion for synthesis filter shaping */
|
||||
silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
|
||||
|
||||
/* Compute noise shaping filter coefficients */
|
||||
silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
|
||||
|
||||
/* Bandwidth expansion for analysis filter shaping */
|
||||
silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
|
||||
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
|
||||
|
||||
/* Ratio of prediction gains, in energy domain */
|
||||
pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||
nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
|
||||
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
|
||||
psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
|
||||
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* Convert from Q24 to Q13 and store in int16 */
|
||||
for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
|
||||
psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
|
||||
psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
/* Gain tweaking */
|
||||
/*****************/
|
||||
/* Increase gains during low speech activity and put lower limit on gains */
|
||||
gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
|
||||
silk_assert( gain_mult_Q16 > 0 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
|
||||
}
|
||||
|
||||
gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
|
||||
psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Control low-frequency shaping and noise tilt */
|
||||
/************************************************/
|
||||
/* Less low frequency shaping for noisy inputs */
|
||||
strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
|
||||
SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
|
||||
strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
|
||||
/*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
|
||||
opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
}
|
||||
silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/
|
||||
Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
|
||||
silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
|
||||
silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
|
||||
} else {
|
||||
b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
|
||||
/* Pack two coefficients in one int32 */
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
|
||||
silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
|
||||
psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
|
||||
for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
|
||||
}
|
||||
Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* HARMONIC SHAPING CONTROL */
|
||||
/****************************/
|
||||
/* Control boosting of harmonic frequencies */
|
||||
HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
|
||||
psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
/* More harmonic boost for noisy input signals */
|
||||
HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
|
||||
|
||||
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* More harmonic noise shaping for high bitrates or noisy input */
|
||||
HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
|
||||
SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
|
||||
psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
|
||||
|
||||
/* Less harmonic noise shaping for less periodic signals */
|
||||
HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
|
||||
silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
|
||||
} else {
|
||||
HarmShapeGain_Q16 = 0;
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Smooth over subframes */
|
||||
/*************************/
|
||||
for( k = 0; k < MAX_NB_SUBFR; k++ ) {
|
||||
psShapeSt->HarmBoost_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->HarmShapeGain_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
psShapeSt->Tilt_smth_Q16 =
|
||||
silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
|
||||
|
||||
psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
|
||||
psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
|
||||
psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */
|
746
node_modules/node-opus/deps/opus/silk/fixed/pitch_analysis_core_FIX.c
generated
vendored
Normal file
746
node_modules/node-opus/deps/opus/silk/fixed/pitch_analysis_core_FIX.c
generated
vendored
Normal file
@ -0,0 +1,746 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/***********************************************************
|
||||
* Pitch analyser function
|
||||
********************************************************** */
|
||||
#include "SigProc_FIX.h"
|
||||
#include "pitch_est_defines.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "debug.h"
|
||||
#include "pitch.h"
|
||||
|
||||
#define SCRATCH_SIZE 22
|
||||
#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 )
|
||||
#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 )
|
||||
#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 )
|
||||
#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 )
|
||||
#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 )
|
||||
#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 )
|
||||
#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )
|
||||
#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )
|
||||
#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 )
|
||||
#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 )
|
||||
#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN )
|
||||
|
||||
typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];
|
||||
|
||||
/************************************************************/
|
||||
/* Internally used functions */
|
||||
/************************************************************/
|
||||
static void silk_P_Ana_calc_corr_st3(
|
||||
silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
|
||||
const opus_int16 frame[], /* I vector to correlate */
|
||||
opus_int start_lag, /* I lag offset to search around */
|
||||
opus_int sf_length, /* I length of a 5 ms subframe */
|
||||
opus_int nb_subfr, /* I number of subframes */
|
||||
opus_int complexity, /* I Complexity setting */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
static void silk_P_Ana_calc_energy_st3(
|
||||
silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
|
||||
const opus_int16 frame[], /* I vector to calc energy in */
|
||||
opus_int start_lag, /* I lag offset to search around */
|
||||
opus_int sf_length, /* I length of one 5 ms subframe */
|
||||
opus_int nb_subfr, /* I number of subframes */
|
||||
opus_int complexity, /* I Complexity setting */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/*************************************************************/
|
||||
/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
|
||||
/*************************************************************/
|
||||
opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
|
||||
const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
|
||||
opus_int *pitch_out, /* O 4 pitch lag values */
|
||||
opus_int16 *lagIndex, /* O Lag Index */
|
||||
opus_int8 *contourIndex, /* O Pitch contour Index */
|
||||
opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
|
||||
opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
|
||||
const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
|
||||
const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */
|
||||
const opus_int Fs_kHz, /* I Sample frequency (kHz) */
|
||||
const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
|
||||
const opus_int nb_subfr, /* I number of 5 ms subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
VARDECL( opus_int16, frame_8kHz );
|
||||
VARDECL( opus_int16, frame_4kHz );
|
||||
opus_int32 filt_state[ 6 ];
|
||||
const opus_int16 *input_frame_ptr;
|
||||
opus_int i, k, d, j;
|
||||
VARDECL( opus_int16, C );
|
||||
VARDECL( opus_int32, xcorr32 );
|
||||
const opus_int16 *target_ptr, *basis_ptr;
|
||||
opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
|
||||
opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
|
||||
VARDECL( opus_int16, d_comp );
|
||||
opus_int32 sum, threshold, lag_counter;
|
||||
opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
|
||||
opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
|
||||
VARDECL( silk_pe_stage3_vals, energies_st3 );
|
||||
VARDECL( silk_pe_stage3_vals, cross_corr_st3 );
|
||||
opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
|
||||
opus_int sf_length;
|
||||
opus_int min_lag;
|
||||
opus_int max_lag;
|
||||
opus_int32 contour_bias_Q15, diff;
|
||||
opus_int nb_cbk_search, cbk_size;
|
||||
opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
|
||||
const opus_int8 *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
/* Check for valid sampling frequency */
|
||||
silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
|
||||
|
||||
/* Check for valid complexity setting */
|
||||
silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
|
||||
|
||||
silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
|
||||
silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
|
||||
|
||||
/* Set up frame lengths max / min lag for the sampling frequency */
|
||||
frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
|
||||
frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
|
||||
frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
|
||||
sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
|
||||
min_lag = PE_MIN_LAG_MS * Fs_kHz;
|
||||
max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
|
||||
|
||||
/* Resample from input sampled at Fs_kHz to 8 kHz */
|
||||
ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 );
|
||||
if( Fs_kHz == 16 ) {
|
||||
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
|
||||
silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
|
||||
} else if( Fs_kHz == 12 ) {
|
||||
silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
|
||||
silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );
|
||||
} else {
|
||||
silk_assert( Fs_kHz == 8 );
|
||||
silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
|
||||
}
|
||||
|
||||
/* Decimate again to 4 kHz */
|
||||
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
|
||||
ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );
|
||||
silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
|
||||
|
||||
/* Low-pass filter */
|
||||
for( i = frame_length_4kHz - 1; i > 0; i-- ) {
|
||||
frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Scale 4 kHz signal down to prevent correlations measures from overflowing
|
||||
** find scaling as max scaling for each 8kHz(?) subframe
|
||||
*******************************************************************************/
|
||||
|
||||
/* Inner product is calculated with different lengths, so scale for the worst case */
|
||||
silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz );
|
||||
if( shift > 0 ) {
|
||||
shift = silk_RSHIFT( shift, 1 );
|
||||
for( i = 0; i < frame_length_4kHz; i++ ) {
|
||||
frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FIRST STAGE, operating in 4 khz
|
||||
******************************************************************************/
|
||||
ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );
|
||||
ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 );
|
||||
silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );
|
||||
target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];
|
||||
for( k = 0; k < nb_subfr >> 1; k++ ) {
|
||||
/* Check that we are within range of the array */
|
||||
silk_assert( target_ptr >= frame_4kHz );
|
||||
silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
|
||||
|
||||
basis_ptr = target_ptr - MIN_LAG_4KHZ;
|
||||
|
||||
/* Check that we are within range of the array */
|
||||
silk_assert( basis_ptr >= frame_4kHz );
|
||||
silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
|
||||
|
||||
celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
|
||||
|
||||
/* Calculate first vector products before loop */
|
||||
cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ];
|
||||
normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch );
|
||||
normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) );
|
||||
normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );
|
||||
|
||||
matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
|
||||
|
||||
/* From now on normalizer is computed recursively */
|
||||
for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) {
|
||||
basis_ptr--;
|
||||
|
||||
/* Check that we are within range of the array */
|
||||
silk_assert( basis_ptr >= frame_4kHz );
|
||||
silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
|
||||
|
||||
cross_corr = xcorr32[ MAX_LAG_4KHZ - d ];
|
||||
|
||||
/* Add contribution of new sample and remove contribution from oldest sample */
|
||||
normalizer = silk_ADD32( normalizer,
|
||||
silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
|
||||
silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );
|
||||
|
||||
matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
|
||||
}
|
||||
/* Update target pointer */
|
||||
target_ptr += SF_LENGTH_8KHZ;
|
||||
}
|
||||
|
||||
/* Combine two subframes into single correlation measure and apply short-lag bias */
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
|
||||
sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )
|
||||
+ (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */
|
||||
sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
|
||||
C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
|
||||
}
|
||||
} else {
|
||||
/* Only short-lag bias */
|
||||
for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
|
||||
sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */
|
||||
sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
|
||||
C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
|
||||
silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
|
||||
silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
|
||||
length_d_srch );
|
||||
|
||||
/* Escape if correlation is very low already here */
|
||||
Cmax = (opus_int)C[ 0 ]; /* Q14 */
|
||||
if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {
|
||||
silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
|
||||
*LTPCorr_Q15 = 0;
|
||||
*lagIndex = 0;
|
||||
*contourIndex = 0;
|
||||
RESTORE_STACK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
threshold = silk_SMULWB( search_thres1_Q16, Cmax );
|
||||
for( i = 0; i < length_d_srch; i++ ) {
|
||||
/* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
|
||||
if( C[ i ] > threshold ) {
|
||||
d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );
|
||||
} else {
|
||||
length_d_srch = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
silk_assert( length_d_srch > 0 );
|
||||
|
||||
ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
|
||||
for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
|
||||
d_comp[ i - D_COMP_MIN ] = 0;
|
||||
}
|
||||
for( i = 0; i < length_d_srch; i++ ) {
|
||||
d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;
|
||||
}
|
||||
|
||||
/* Convolution */
|
||||
for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
|
||||
d_comp[ i - D_COMP_MIN ] +=
|
||||
d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];
|
||||
}
|
||||
|
||||
length_d_srch = 0;
|
||||
for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {
|
||||
if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {
|
||||
d_srch[ length_d_srch ] = i;
|
||||
length_d_srch++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convolution */
|
||||
for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
|
||||
d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]
|
||||
+ d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];
|
||||
}
|
||||
|
||||
length_d_comp = 0;
|
||||
for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {
|
||||
if( d_comp[ i - D_COMP_MIN ] > 0 ) {
|
||||
d_comp[ length_d_comp ] = i - 2;
|
||||
length_d_comp++;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************************
|
||||
** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
|
||||
*************************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
** Scale signal down to avoid correlations measures from overflowing
|
||||
*******************************************************************************/
|
||||
/* find scaling as max scaling for each subframe */
|
||||
silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz );
|
||||
if( shift > 0 ) {
|
||||
shift = silk_RSHIFT( shift, 1 );
|
||||
for( i = 0; i < frame_length_8kHz; i++ ) {
|
||||
frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* Find energy of each subframe projected onto its history, for a range of delays
|
||||
*********************************************************************************/
|
||||
silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) );
|
||||
|
||||
target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
|
||||
/* Check that we are within range of the array */
|
||||
silk_assert( target_ptr >= frame_8kHz );
|
||||
silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
|
||||
|
||||
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
|
||||
for( j = 0; j < length_d_comp; j++ ) {
|
||||
d = d_comp[ j ];
|
||||
basis_ptr = target_ptr - d;
|
||||
|
||||
/* Check that we are within range of the array */
|
||||
silk_assert( basis_ptr >= frame_8kHz );
|
||||
silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
|
||||
|
||||
cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
|
||||
if( cross_corr > 0 ) {
|
||||
energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
|
||||
matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =
|
||||
(opus_int16)silk_DIV32_varQ( cross_corr,
|
||||
silk_ADD32( energy_target,
|
||||
energy_basis ),
|
||||
13 + 1 ); /* Q13 */
|
||||
} else {
|
||||
matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0;
|
||||
}
|
||||
}
|
||||
target_ptr += SF_LENGTH_8KHZ;
|
||||
}
|
||||
|
||||
/* search over lag range and lags codebook */
|
||||
/* scale factor for lag codebook, as a function of center lag */
|
||||
|
||||
CCmax = silk_int32_MIN;
|
||||
CCmax_b = silk_int32_MIN;
|
||||
|
||||
CBimax = 0; /* To avoid returning undefined lag values */
|
||||
lag = -1; /* To check if lag with strong enough correlation has been found */
|
||||
|
||||
if( prevLag > 0 ) {
|
||||
if( Fs_kHz == 12 ) {
|
||||
prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );
|
||||
} else if( Fs_kHz == 16 ) {
|
||||
prevLag = silk_RSHIFT( prevLag, 1 );
|
||||
}
|
||||
prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );
|
||||
} else {
|
||||
prevLag_log2_Q7 = 0;
|
||||
}
|
||||
silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) );
|
||||
/* Set up stage 2 codebook based on number of subframes */
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
cbk_size = PE_NB_CBKS_STAGE2_EXT;
|
||||
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
|
||||
if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
|
||||
/* If input is 8 khz use a larger codebook here because it is last stage */
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
|
||||
} else {
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE2;
|
||||
}
|
||||
} else {
|
||||
cbk_size = PE_NB_CBKS_STAGE2_10MS;
|
||||
Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
|
||||
}
|
||||
|
||||
for( k = 0; k < length_d_srch; k++ ) {
|
||||
d = d_srch[ k ];
|
||||
for( j = 0; j < nb_cbk_search; j++ ) {
|
||||
CC[ j ] = 0;
|
||||
for( i = 0; i < nb_subfr; i++ ) {
|
||||
opus_int d_subfr;
|
||||
/* Try all codebooks */
|
||||
d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );
|
||||
CC[ j ] = CC[ j ]
|
||||
+ (opus_int32)matrix_ptr( C, i,
|
||||
d_subfr - ( MIN_LAG_8KHZ - 2 ),
|
||||
CSTRIDE_8KHZ );
|
||||
}
|
||||
}
|
||||
/* Find best codebook */
|
||||
CCmax_new = silk_int32_MIN;
|
||||
CBimax_new = 0;
|
||||
for( i = 0; i < nb_cbk_search; i++ ) {
|
||||
if( CC[ i ] > CCmax_new ) {
|
||||
CCmax_new = CC[ i ];
|
||||
CBimax_new = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Bias towards shorter lags */
|
||||
lag_log2_Q7 = silk_lin2log( d ); /* Q7 */
|
||||
silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
|
||||
silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) );
|
||||
CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */
|
||||
|
||||
/* Bias towards previous lag */
|
||||
silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) );
|
||||
if( prevLag > 0 ) {
|
||||
delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
|
||||
silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );
|
||||
delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
|
||||
prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */
|
||||
prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) );
|
||||
CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */
|
||||
}
|
||||
|
||||
if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
|
||||
CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */
|
||||
silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */
|
||||
) {
|
||||
CCmax_b = CCmax_new_b;
|
||||
CCmax = CCmax_new;
|
||||
lag = d;
|
||||
CBimax = CBimax_new;
|
||||
}
|
||||
}
|
||||
|
||||
if( lag == -1 ) {
|
||||
/* No suitable candidate found */
|
||||
silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
|
||||
*LTPCorr_Q15 = 0;
|
||||
*lagIndex = 0;
|
||||
*contourIndex = 0;
|
||||
RESTORE_STACK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Output normalized correlation */
|
||||
*LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 );
|
||||
silk_assert( *LTPCorr_Q15 >= 0 );
|
||||
|
||||
if( Fs_kHz > 8 ) {
|
||||
VARDECL( opus_int16, scratch_mem );
|
||||
/***************************************************************************/
|
||||
/* Scale input signal down to avoid correlations measures from overflowing */
|
||||
/***************************************************************************/
|
||||
/* find scaling as max scaling for each subframe */
|
||||
silk_sum_sqr_shift( &energy, &shift, frame, frame_length );
|
||||
ALLOC( scratch_mem, shift > 0 ? frame_length : ALLOC_NONE, opus_int16 );
|
||||
if( shift > 0 ) {
|
||||
/* Move signal to scratch mem because the input signal should be unchanged */
|
||||
shift = silk_RSHIFT( shift, 1 );
|
||||
for( i = 0; i < frame_length; i++ ) {
|
||||
scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift );
|
||||
}
|
||||
input_frame_ptr = scratch_mem;
|
||||
} else {
|
||||
input_frame_ptr = frame;
|
||||
}
|
||||
|
||||
/* Search in original signal */
|
||||
|
||||
CBimax_old = CBimax;
|
||||
/* Compensate for decimation */
|
||||
silk_assert( lag == silk_SAT16( lag ) );
|
||||
if( Fs_kHz == 12 ) {
|
||||
lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );
|
||||
} else if( Fs_kHz == 16 ) {
|
||||
lag = silk_LSHIFT( lag, 1 );
|
||||
} else {
|
||||
lag = silk_SMULBB( lag, 3 );
|
||||
}
|
||||
|
||||
lag = silk_LIMIT_int( lag, min_lag, max_lag );
|
||||
start_lag = silk_max_int( lag - 2, min_lag );
|
||||
end_lag = silk_min_int( lag + 2, max_lag );
|
||||
lag_new = lag; /* to avoid undefined lag */
|
||||
CBimax = 0; /* to avoid undefined lag */
|
||||
|
||||
CCmax = silk_int32_MIN;
|
||||
/* pitch lags according to second stage */
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
|
||||
}
|
||||
|
||||
/* Set up codebook parameters according to complexity setting and frame length */
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
|
||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
|
||||
} else {
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
|
||||
cbk_size = PE_NB_CBKS_STAGE3_10MS;
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
|
||||
}
|
||||
|
||||
/* Calculate the correlations and energies needed in stage 3 */
|
||||
ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
|
||||
ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
|
||||
silk_P_Ana_calc_corr_st3( cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
|
||||
silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
|
||||
|
||||
lag_counter = 0;
|
||||
silk_assert( lag == silk_SAT16( lag ) );
|
||||
contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
|
||||
|
||||
target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
|
||||
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
|
||||
for( d = start_lag; d <= end_lag; d++ ) {
|
||||
for( j = 0; j < nb_cbk_search; j++ ) {
|
||||
cross_corr = 0;
|
||||
energy = energy_target;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
cross_corr = silk_ADD32( cross_corr,
|
||||
matrix_ptr( cross_corr_st3, k, j,
|
||||
nb_cbk_search )[ lag_counter ] );
|
||||
energy = silk_ADD32( energy,
|
||||
matrix_ptr( energies_st3, k, j,
|
||||
nb_cbk_search )[ lag_counter ] );
|
||||
silk_assert( energy >= 0 );
|
||||
}
|
||||
if( cross_corr > 0 ) {
|
||||
CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */
|
||||
/* Reduce depending on flatness of contour */
|
||||
diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */
|
||||
silk_assert( diff == silk_SAT16( diff ) );
|
||||
CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */
|
||||
} else {
|
||||
CCmax_new = 0;
|
||||
}
|
||||
|
||||
if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
|
||||
CCmax = CCmax_new;
|
||||
lag_new = d;
|
||||
CBimax = j;
|
||||
}
|
||||
}
|
||||
lag_counter++;
|
||||
}
|
||||
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
|
||||
pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
|
||||
}
|
||||
*lagIndex = (opus_int16)( lag_new - min_lag);
|
||||
*contourIndex = (opus_int8)CBimax;
|
||||
} else { /* Fs_kHz == 8 */
|
||||
/* Save Lags */
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
|
||||
pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 );
|
||||
}
|
||||
*lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
|
||||
*contourIndex = (opus_int8)CBimax;
|
||||
}
|
||||
silk_assert( *lagIndex >= 0 );
|
||||
/* return as voiced */
|
||||
RESTORE_STACK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Calculates the correlations used in stage 3 search. In order to cover
|
||||
* the whole lag codebook for all the searched offset lags (lag +- 2),
|
||||
* the following correlations are needed in each sub frame:
|
||||
*
|
||||
* sf1: lag range [-8,...,7] total 16 correlations
|
||||
* sf2: lag range [-4,...,4] total 9 correlations
|
||||
* sf3: lag range [-3,....4] total 8 correltions
|
||||
* sf4: lag range [-6,....8] total 15 correlations
|
||||
*
|
||||
* In total 48 correlations. The direct implementation computed in worst
|
||||
* case 4*12*5 = 240 correlations, but more likely around 120.
|
||||
***********************************************************************/
|
||||
static void silk_P_Ana_calc_corr_st3(
|
||||
silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
|
||||
const opus_int16 frame[], /* I vector to correlate */
|
||||
opus_int start_lag, /* I lag offset to search around */
|
||||
opus_int sf_length, /* I length of a 5 ms subframe */
|
||||
opus_int nb_subfr, /* I number of subframes */
|
||||
opus_int complexity, /* I Complexity setting */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
const opus_int16 *target_ptr;
|
||||
opus_int i, j, k, lag_counter, lag_low, lag_high;
|
||||
opus_int nb_cbk_search, delta, idx, cbk_size;
|
||||
VARDECL( opus_int32, scratch_mem );
|
||||
VARDECL( opus_int32, xcorr32 );
|
||||
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
|
||||
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
|
||||
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
|
||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||
} else {
|
||||
silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
|
||||
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
|
||||
cbk_size = PE_NB_CBKS_STAGE3_10MS;
|
||||
}
|
||||
ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
|
||||
ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 );
|
||||
|
||||
target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
lag_counter = 0;
|
||||
|
||||
/* Calculate the correlations for each subframe */
|
||||
lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
|
||||
lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
|
||||
silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
|
||||
celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
|
||||
for( j = lag_low; j <= lag_high; j++ ) {
|
||||
silk_assert( lag_counter < SCRATCH_SIZE );
|
||||
scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ];
|
||||
lag_counter++;
|
||||
}
|
||||
|
||||
delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
|
||||
for( i = 0; i < nb_cbk_search; i++ ) {
|
||||
/* Fill out the 3 dim array that stores the correlations for */
|
||||
/* each code_book vector for each start lag */
|
||||
idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
|
||||
for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
|
||||
silk_assert( idx + j < SCRATCH_SIZE );
|
||||
silk_assert( idx + j < lag_counter );
|
||||
matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =
|
||||
scratch_mem[ idx + j ];
|
||||
}
|
||||
}
|
||||
target_ptr += sf_length;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Calculate the energies for first two subframes. The energies are */
|
||||
/* calculated recursively. */
|
||||
/********************************************************************/
|
||||
static void silk_P_Ana_calc_energy_st3(
|
||||
silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
|
||||
const opus_int16 frame[], /* I vector to calc energy in */
|
||||
opus_int start_lag, /* I lag offset to search around */
|
||||
opus_int sf_length, /* I length of one 5 ms subframe */
|
||||
opus_int nb_subfr, /* I number of subframes */
|
||||
opus_int complexity, /* I Complexity setting */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
const opus_int16 *target_ptr, *basis_ptr;
|
||||
opus_int32 energy;
|
||||
opus_int k, i, j, lag_counter;
|
||||
opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
|
||||
VARDECL( opus_int32, scratch_mem );
|
||||
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
|
||||
silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
|
||||
|
||||
if( nb_subfr == PE_MAX_NB_SUBFR ) {
|
||||
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
|
||||
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
|
||||
cbk_size = PE_NB_CBKS_STAGE3_MAX;
|
||||
} else {
|
||||
silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
|
||||
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
|
||||
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
|
||||
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
|
||||
cbk_size = PE_NB_CBKS_STAGE3_10MS;
|
||||
}
|
||||
ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
|
||||
|
||||
target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
lag_counter = 0;
|
||||
|
||||
/* Calculate the energy for first lag */
|
||||
basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
|
||||
energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch );
|
||||
silk_assert( energy >= 0 );
|
||||
scratch_mem[ lag_counter ] = energy;
|
||||
lag_counter++;
|
||||
|
||||
lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
|
||||
for( i = 1; i < lag_diff; i++ ) {
|
||||
/* remove part outside new window */
|
||||
energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
|
||||
silk_assert( energy >= 0 );
|
||||
|
||||
/* add part that comes into window */
|
||||
energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
|
||||
silk_assert( energy >= 0 );
|
||||
silk_assert( lag_counter < SCRATCH_SIZE );
|
||||
scratch_mem[ lag_counter ] = energy;
|
||||
lag_counter++;
|
||||
}
|
||||
|
||||
delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
|
||||
for( i = 0; i < nb_cbk_search; i++ ) {
|
||||
/* Fill out the 3 dim array that stores the correlations for */
|
||||
/* each code_book vector for each start lag */
|
||||
idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
|
||||
for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
|
||||
silk_assert( idx + j < SCRATCH_SIZE );
|
||||
silk_assert( idx + j < lag_counter );
|
||||
matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =
|
||||
scratch_mem[ idx + j ];
|
||||
silk_assert(
|
||||
matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );
|
||||
}
|
||||
}
|
||||
target_ptr += sf_length;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
221
node_modules/node-opus/deps/opus/silk/fixed/prefilter_FIX.c
generated
vendored
Normal file
221
node_modules/node-opus/deps/opus/silk/fixed/prefilter_FIX.c
generated
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/prefilter_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(OVERRIDE_silk_warped_LPC_analysis_filter_FIX)
|
||||
#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
|
||||
((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
|
||||
#endif
|
||||
|
||||
/* Prefilter for finding Quantizer input signal */
|
||||
static OPUS_INLINE void silk_prefilt_FIX(
|
||||
silk_prefilter_state_FIX *P, /* I/O state */
|
||||
opus_int32 st_res_Q12[], /* I short term residual signal */
|
||||
opus_int32 xw_Q3[], /* O prefiltered signal */
|
||||
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
||||
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
||||
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
||||
opus_int lag, /* I Lag for harmonic shaping */
|
||||
opus_int length /* I Length of signals */
|
||||
);
|
||||
|
||||
void silk_warped_LPC_analysis_filter_FIX_c(
|
||||
opus_int32 state[], /* I/O State [order + 1] */
|
||||
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||
const opus_int16 input[], /* I Input signal [length] */
|
||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order /* I Filter order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i;
|
||||
opus_int32 acc_Q11, tmp1, tmp2;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
|
||||
for( n = 0; n < length; n++ ) {
|
||||
/* Output of lowpass section */
|
||||
tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
|
||||
state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
|
||||
state[ 1 ] = tmp2;
|
||||
acc_Q11 = silk_RSHIFT( order, 1 );
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
|
||||
/* Loop over allpass sections */
|
||||
for( i = 2; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
|
||||
state[ i ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
|
||||
state[ i + 1 ] = tmp2;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
|
||||
}
|
||||
state[ order ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
|
||||
}
|
||||
}
|
||||
|
||||
void silk_prefilter_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
|
||||
opus_int32 xw_Q3[], /* O Weighted signal */
|
||||
const opus_int16 x[] /* I Speech signal */
|
||||
)
|
||||
{
|
||||
silk_prefilter_state_FIX *P = &psEnc->sPrefilt;
|
||||
opus_int j, k, lag;
|
||||
opus_int32 tmp_32;
|
||||
const opus_int16 *AR1_shp_Q13;
|
||||
const opus_int16 *px;
|
||||
opus_int32 *pxw_Q3;
|
||||
opus_int HarmShapeGain_Q12, Tilt_Q14;
|
||||
opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
|
||||
VARDECL( opus_int32, x_filt_Q12 );
|
||||
VARDECL( opus_int32, st_res_Q2 );
|
||||
opus_int16 B_Q10[ 2 ];
|
||||
SAVE_STACK;
|
||||
|
||||
/* Set up pointers */
|
||||
px = x;
|
||||
pxw_Q3 = xw_Q3;
|
||||
lag = P->lagPrev;
|
||||
ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 );
|
||||
ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Update Variables that change per sub frame */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
lag = psEncCtrl->pitchL[ k ];
|
||||
}
|
||||
|
||||
/* Noise shape parameters */
|
||||
HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
|
||||
silk_assert( HarmShapeGain_Q12 >= 0 );
|
||||
HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 );
|
||||
HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
|
||||
Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ];
|
||||
LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ];
|
||||
AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ];
|
||||
|
||||
/* Short term FIR filtering*/
|
||||
silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px,
|
||||
psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder, psEnc->sCmn.arch );
|
||||
|
||||
/* Reduce (mainly) low frequencies during harmonic emphasis */
|
||||
B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 );
|
||||
tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
|
||||
tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
|
||||
tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
|
||||
tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */
|
||||
B_Q10[ 1 ]= silk_SAT16( tmp_32 );
|
||||
x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] );
|
||||
for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
|
||||
x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] );
|
||||
}
|
||||
P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ];
|
||||
|
||||
silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
|
||||
|
||||
px += psEnc->sCmn.subfr_length;
|
||||
pxw_Q3 += psEnc->sCmn.subfr_length;
|
||||
}
|
||||
|
||||
P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
#ifndef OVERRIDE_silk_prefilt_FIX
|
||||
/* Prefilter for finding Quantizer input signal */
|
||||
static OPUS_INLINE void silk_prefilt_FIX(
|
||||
silk_prefilter_state_FIX *P, /* I/O state */
|
||||
opus_int32 st_res_Q12[], /* I short term residual signal */
|
||||
opus_int32 xw_Q3[], /* O prefiltered signal */
|
||||
opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
|
||||
opus_int Tilt_Q14, /* I Tilt shaping coeficient */
|
||||
opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
|
||||
opus_int lag, /* I Lag for harmonic shaping */
|
||||
opus_int length /* I Length of signals */
|
||||
)
|
||||
{
|
||||
opus_int i, idx, LTP_shp_buf_idx;
|
||||
opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
|
||||
opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
|
||||
opus_int16 *LTP_shp_buf;
|
||||
|
||||
/* To speed up use temp variables instead of using the struct */
|
||||
LTP_shp_buf = P->sLTP_shp;
|
||||
LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
|
||||
sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
|
||||
sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
|
||||
|
||||
for( i = 0; i < length; i++ ) {
|
||||
if( lag > 0 ) {
|
||||
/* unrolled loop */
|
||||
silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
|
||||
idx = lag + LTP_shp_buf_idx;
|
||||
n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
|
||||
} else {
|
||||
n_LTP_Q12 = 0;
|
||||
}
|
||||
|
||||
n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
|
||||
n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
|
||||
|
||||
sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
|
||||
sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
|
||||
|
||||
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
||||
LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
|
||||
|
||||
xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
|
||||
}
|
||||
|
||||
/* Copy temp variable back to state */
|
||||
P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
|
||||
P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
|
||||
P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
|
||||
}
|
||||
#endif /* OVERRIDE_silk_prefilt_FIX */
|
117
node_modules/node-opus/deps/opus/silk/fixed/process_gains_FIX.c
generated
vendored
Normal file
117
node_modules/node-opus/deps/opus/silk/fixed/process_gains_FIX.c
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Processing of gains */
|
||||
void silk_process_gains_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
|
||||
silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
|
||||
opus_int k;
|
||||
opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
|
||||
|
||||
/* Gain reduction when LTP coding gain is high */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
|
||||
s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Limit the quantized signal */
|
||||
/* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
|
||||
InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin(
|
||||
silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length );
|
||||
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
/* Soft limit on ratio residual energy and squared gains */
|
||||
ResNrg = psEncCtrl->ResNrg[ k ];
|
||||
ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
|
||||
if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
|
||||
ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
|
||||
} else {
|
||||
if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
|
||||
ResNrgPart = silk_int32_MAX;
|
||||
} else {
|
||||
ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
|
||||
}
|
||||
}
|
||||
gain = psEncCtrl->Gains_Q16[ k ];
|
||||
gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) );
|
||||
if( gain_squared < silk_int16_MAX ) {
|
||||
/* recalculate with higher precision */
|
||||
gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain );
|
||||
silk_assert( gain_squared > 0 );
|
||||
gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */
|
||||
gain = silk_min( gain, silk_int32_MAX >> 8 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */
|
||||
} else {
|
||||
gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */
|
||||
gain = silk_min( gain, silk_int32_MAX >> 16 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */
|
||||
}
|
||||
}
|
||||
|
||||
/* Save unquantized gains and gain Index */
|
||||
silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
|
||||
psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
|
||||
|
||||
/* Quantize gains */
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,
|
||||
&psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quantizer boundary adjustment */
|
||||
quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];
|
||||
psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )
|
||||
+ silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 )
|
||||
+ silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 );
|
||||
|
||||
silk_assert( psEncCtrl->Lambda_Q10 > 0 );
|
||||
silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );
|
||||
}
|
47
node_modules/node-opus/deps/opus/silk/fixed/regularize_correlations_FIX.c
generated
vendored
Normal file
47
node_modules/node-opus/deps/opus/silk/fixed/regularize_correlations_FIX.c
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
|
||||
/* Add noise to matrix diagonal */
|
||||
void silk_regularize_correlations_FIX(
|
||||
opus_int32 *XX, /* I/O Correlation matrices */
|
||||
opus_int32 *xx, /* I/O Correlation values */
|
||||
opus_int32 noise, /* I Noise to add */
|
||||
opus_int D /* I Dimension of XX */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
|
||||
}
|
||||
xx[ 0 ] += noise;
|
||||
}
|
103
node_modules/node-opus/deps/opus/silk/fixed/residual_energy16_FIX.c
generated
vendored
Normal file
103
node_modules/node-opus/deps/opus/silk/fixed/residual_energy16_FIX.c
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
|
||||
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
|
||||
opus_int32 silk_residual_energy16_covar_FIX(
|
||||
const opus_int16 *c, /* I Prediction vector */
|
||||
const opus_int32 *wXX, /* I Correlation matrix */
|
||||
const opus_int32 *wXx, /* I Correlation vector */
|
||||
opus_int32 wxx, /* I Signal energy */
|
||||
opus_int D, /* I Dimension */
|
||||
opus_int cQ /* I Q value for c vector 0 - 15 */
|
||||
)
|
||||
{
|
||||
opus_int i, j, lshifts, Qxtra;
|
||||
opus_int32 c_max, w_max, tmp, tmp2, nrg;
|
||||
opus_int cn[ MAX_MATRIX_SIZE ];
|
||||
const opus_int32 *pRow;
|
||||
|
||||
/* Safety checks */
|
||||
silk_assert( D >= 0 );
|
||||
silk_assert( D <= 16 );
|
||||
silk_assert( cQ > 0 );
|
||||
silk_assert( cQ < 16 );
|
||||
|
||||
lshifts = 16 - cQ;
|
||||
Qxtra = lshifts;
|
||||
|
||||
c_max = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );
|
||||
}
|
||||
Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
|
||||
|
||||
w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
|
||||
Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
|
||||
Qxtra = silk_max_int( Qxtra, 0 );
|
||||
for( i = 0; i < D; i++ ) {
|
||||
cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra );
|
||||
silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */
|
||||
}
|
||||
lshifts -= Qxtra;
|
||||
|
||||
/* Compute wxx - 2 * wXx * c */
|
||||
tmp = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] );
|
||||
}
|
||||
nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */
|
||||
|
||||
/* Add c' * wXX * c, assuming wXX is symmetric */
|
||||
tmp2 = 0;
|
||||
for( i = 0; i < D; i++ ) {
|
||||
tmp = 0;
|
||||
pRow = &wXX[ i * D ];
|
||||
for( j = i + 1; j < D; j++ ) {
|
||||
tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] );
|
||||
}
|
||||
tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
|
||||
tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] );
|
||||
}
|
||||
nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */
|
||||
|
||||
/* Keep one bit free always, because we add them for LSF interpolation */
|
||||
if( nrg < 1 ) {
|
||||
nrg = 1;
|
||||
} else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) {
|
||||
nrg = silk_int32_MAX >> 1;
|
||||
} else {
|
||||
nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */
|
||||
}
|
||||
return nrg;
|
||||
|
||||
}
|
98
node_modules/node-opus/deps/opus/silk/fixed/residual_energy_FIX.c
generated
vendored
Normal file
98
node_modules/node-opus/deps/opus/silk/fixed/residual_energy_FIX.c
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
|
||||
/* Calculates residual energies of input subframes where all subframes have LPC_order */
|
||||
/* of preceding samples */
|
||||
void silk_residual_energy_FIX(
|
||||
opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
|
||||
opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
|
||||
const opus_int16 x[], /* I Input signal */
|
||||
opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
|
||||
const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int offset, i, j, rshift, lz1, lz2;
|
||||
opus_int16 *LPC_res_ptr;
|
||||
VARDECL( opus_int16, LPC_res );
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int32 tmp32;
|
||||
SAVE_STACK;
|
||||
|
||||
x_ptr = x;
|
||||
offset = LPC_order + subfr_length;
|
||||
|
||||
/* Filter input to create the LPC residual for each frame half, and measure subframe energies */
|
||||
ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
|
||||
silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
|
||||
for( i = 0; i < nb_subfr >> 1; i++ ) {
|
||||
/* Calculate half frame LPC residual signal including preceding samples */
|
||||
silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
|
||||
|
||||
/* Point to first subframe of the just calculated LPC residual signal */
|
||||
LPC_res_ptr = LPC_res + LPC_order;
|
||||
for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {
|
||||
/* Measure subframe energy */
|
||||
silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );
|
||||
|
||||
/* Set Q values for the measured energy */
|
||||
nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;
|
||||
|
||||
/* Move to next subframe */
|
||||
LPC_res_ptr += offset;
|
||||
}
|
||||
/* Move to next frame half */
|
||||
x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;
|
||||
}
|
||||
|
||||
/* Apply the squared subframe gains */
|
||||
for( i = 0; i < nb_subfr; i++ ) {
|
||||
/* Fully upscale gains and energies */
|
||||
lz1 = silk_CLZ32( nrgs[ i ] ) - 1;
|
||||
lz2 = silk_CLZ32( gains[ i ] ) - 1;
|
||||
|
||||
tmp32 = silk_LSHIFT32( gains[ i ], lz2 );
|
||||
|
||||
/* Find squared gains */
|
||||
tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/
|
||||
|
||||
/* Scale energies */
|
||||
nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/
|
||||
nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
|
||||
}
|
||||
RESTORE_STACK;
|
||||
}
|
92
node_modules/node-opus/deps/opus/silk/fixed/schur64_FIX.c
generated
vendored
Normal file
92
node_modules/node-opus/deps/opus/silk/fixed/schur64_FIX.c
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Slower than schur(), but more accurate. */
|
||||
/* Uses SMULL(), available on armv4 */
|
||||
opus_int32 silk_schur64( /* O returns residual energy */
|
||||
opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */
|
||||
const opus_int32 c[], /* I Correlations [order+1] */
|
||||
opus_int32 order /* I Prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
|
||||
opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
|
||||
|
||||
silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
|
||||
|
||||
/* Check for invalid input */
|
||||
if( c[ 0 ] <= 0 ) {
|
||||
silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
}
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Check that we won't be getting an unstable rc, otherwise stop here. */
|
||||
if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
|
||||
if ( C[ k + 1 ][ 0 ] > 0 ) {
|
||||
rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 );
|
||||
} else {
|
||||
rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 );
|
||||
}
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get reflection coefficient: divide two Q30 values and get result in Q31 */
|
||||
rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
|
||||
|
||||
/* Save the output */
|
||||
rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );
|
||||
|
||||
/* Update correlations */
|
||||
for( n = 0; n < order - k; n++ ) {
|
||||
Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
|
||||
Ctmp2_Q30 = C[ n ][ 1 ];
|
||||
|
||||
/* Multiply and add the highest int32 */
|
||||
C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
|
||||
C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
|
||||
}
|
||||
}
|
||||
|
||||
for(; k < order; k++ ) {
|
||||
rc_Q16[ k ] = 0;
|
||||
}
|
||||
|
||||
return silk_max_32( 1, C[ 0 ][ 1 ] );
|
||||
}
|
106
node_modules/node-opus/deps/opus/silk/fixed/schur_FIX.c
generated
vendored
Normal file
106
node_modules/node-opus/deps/opus/silk/fixed/schur_FIX.c
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
|
||||
/* Faster than schur64(), but much less accurate. */
|
||||
/* uses SMLAWB(), requiring armv5E and higher. */
|
||||
opus_int32 silk_schur( /* O Returns residual energy */
|
||||
opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */
|
||||
const opus_int32 *c, /* I correlations [order+1] */
|
||||
const opus_int32 order /* I prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n, lz;
|
||||
opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
|
||||
opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
|
||||
|
||||
silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
|
||||
|
||||
/* Get number of leading zeros */
|
||||
lz = silk_CLZ32( c[ 0 ] );
|
||||
|
||||
/* Copy correlations and adjust level to Q30 */
|
||||
if( lz < 2 ) {
|
||||
/* lz must be 1, so shift one to the right */
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
|
||||
}
|
||||
} else if( lz > 2 ) {
|
||||
/* Shift to the left */
|
||||
lz -= 2;
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
|
||||
}
|
||||
} else {
|
||||
/* No need to shift */
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
}
|
||||
}
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Check that we won't be getting an unstable rc, otherwise stop here. */
|
||||
if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
|
||||
if ( C[ k + 1 ][ 0 ] > 0 ) {
|
||||
rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 );
|
||||
} else {
|
||||
rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 );
|
||||
}
|
||||
k++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get reflection coefficient */
|
||||
rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
|
||||
|
||||
/* Clip (shouldn't happen for properly conditioned inputs) */
|
||||
rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
|
||||
|
||||
/* Store */
|
||||
rc_Q15[ k ] = (opus_int16)rc_tmp_Q15;
|
||||
|
||||
/* Update correlations */
|
||||
for( n = 0; n < order - k; n++ ) {
|
||||
Ctmp1 = C[ n + k + 1 ][ 0 ];
|
||||
Ctmp2 = C[ n ][ 1 ];
|
||||
C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
|
||||
C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
|
||||
}
|
||||
}
|
||||
|
||||
for(; k < order; k++ ) {
|
||||
rc_Q15[ k ] = 0;
|
||||
}
|
||||
|
||||
/* return residual energy */
|
||||
return silk_max_32( 1, C[ 0 ][ 1 ] );
|
||||
}
|
249
node_modules/node-opus/deps/opus/silk/fixed/solve_LS_FIX.c
generated
vendored
Normal file
249
node_modules/node-opus/deps/opus/silk/fixed/solve_LS_FIX.c
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/*****************************/
|
||||
/* Internal function headers */
|
||||
/*****************************/
|
||||
|
||||
typedef struct {
|
||||
opus_int32 Q36_part;
|
||||
opus_int32 Q48_part;
|
||||
} inv_D_t;
|
||||
|
||||
/* Factorize square matrix A into LDL form */
|
||||
static OPUS_INLINE void silk_LDL_factorize_FIX(
|
||||
opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */
|
||||
opus_int M, /* I Size of Matrix */
|
||||
opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
|
||||
inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
|
||||
);
|
||||
|
||||
/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
|
||||
static OPUS_INLINE void silk_LS_SolveFirst_FIX(
|
||||
const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const opus_int32 *b, /* I b Vector */
|
||||
opus_int32 *x_Q16 /* O x Vector */
|
||||
);
|
||||
|
||||
/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
|
||||
static OPUS_INLINE void silk_LS_SolveLast_FIX(
|
||||
const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
|
||||
const opus_int M, /* I Dim of Matrix equation */
|
||||
const opus_int32 *b, /* I b Vector */
|
||||
opus_int32 *x_Q16 /* O x Vector */
|
||||
);
|
||||
|
||||
static OPUS_INLINE void silk_LS_divide_Q16_FIX(
|
||||
opus_int32 T[], /* I/O Numenator vector */
|
||||
inv_D_t *inv_D, /* I 1 / D vector */
|
||||
opus_int M /* I dimension */
|
||||
);
|
||||
|
||||
/* Solves Ax = b, assuming A is symmetric */
|
||||
void silk_solve_LDL_FIX(
|
||||
opus_int32 *A, /* I Pointer to symetric square matrix A */
|
||||
opus_int M, /* I Size of matrix */
|
||||
const opus_int32 *b, /* I Pointer to b vector */
|
||||
opus_int32 *x_Q16 /* O Pointer to x solution vector */
|
||||
)
|
||||
{
|
||||
VARDECL( opus_int32, L_Q16 );
|
||||
opus_int32 Y[ MAX_MATRIX_SIZE ];
|
||||
inv_D_t inv_D[ MAX_MATRIX_SIZE ];
|
||||
SAVE_STACK;
|
||||
|
||||
silk_assert( M <= MAX_MATRIX_SIZE );
|
||||
ALLOC( L_Q16, M * M, opus_int32 );
|
||||
|
||||
/***************************************************
|
||||
Factorize A by LDL such that A = L*D*L',
|
||||
where L is lower triangular with ones on diagonal
|
||||
****************************************************/
|
||||
silk_LDL_factorize_FIX( A, M, L_Q16, inv_D );
|
||||
|
||||
/****************************************************
|
||||
* substitute D*L'*x = Y. ie:
|
||||
L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b
|
||||
******************************************************/
|
||||
silk_LS_SolveFirst_FIX( L_Q16, M, b, Y );
|
||||
|
||||
/****************************************************
|
||||
D*L'*x = Y <=> L'*x = inv(D)*Y, because D is
|
||||
diagonal just multiply with 1/d_i
|
||||
****************************************************/
|
||||
silk_LS_divide_Q16_FIX( Y, inv_D, M );
|
||||
|
||||
/****************************************************
|
||||
x = inv(L') * inv(D) * Y
|
||||
*****************************************************/
|
||||
silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_LDL_factorize_FIX(
|
||||
opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */
|
||||
opus_int M, /* I Size of Matrix */
|
||||
opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
|
||||
inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
|
||||
)
|
||||
{
|
||||
opus_int i, j, k, status, loop_count;
|
||||
const opus_int32 *ptr1, *ptr2;
|
||||
opus_int32 diag_min_value, tmp_32, err;
|
||||
opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];
|
||||
opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;
|
||||
|
||||
silk_assert( M <= MAX_MATRIX_SIZE );
|
||||
|
||||
status = 1;
|
||||
diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );
|
||||
for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {
|
||||
status = 0;
|
||||
for( j = 0; j < M; j++ ) {
|
||||
ptr1 = matrix_adr( L_Q16, j, 0, M );
|
||||
tmp_32 = 0;
|
||||
for( i = 0; i < j; i++ ) {
|
||||
v_Q0[ i ] = silk_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */
|
||||
tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */
|
||||
}
|
||||
tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );
|
||||
|
||||
if( tmp_32 < diag_min_value ) {
|
||||
tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );
|
||||
/* Matrix not positive semi-definite, or ill conditioned */
|
||||
for( i = 0; i < M; i++ ) {
|
||||
matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );
|
||||
}
|
||||
status = 1;
|
||||
break;
|
||||
}
|
||||
D_Q0[ j ] = tmp_32; /* always < max(Correlation) */
|
||||
|
||||
/* two-step division */
|
||||
one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */
|
||||
one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */
|
||||
err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */
|
||||
one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 ); /* Q48 */
|
||||
|
||||
/* Save 1/Ds */
|
||||
inv_D[ j ].Q36_part = one_div_diag_Q36;
|
||||
inv_D[ j ].Q48_part = one_div_diag_Q48;
|
||||
|
||||
matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */
|
||||
ptr1 = matrix_adr( A, j, 0, M );
|
||||
ptr2 = matrix_adr( L_Q16, j + 1, 0, M );
|
||||
for( i = j + 1; i < M; i++ ) {
|
||||
tmp_32 = 0;
|
||||
for( k = 0; k < j; k++ ) {
|
||||
tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */
|
||||
}
|
||||
tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */
|
||||
|
||||
/* tmp_32 / D_Q0[j] : Divide to Q16 */
|
||||
matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ),
|
||||
silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
|
||||
|
||||
/* go to next column */
|
||||
ptr2 += M;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
silk_assert( status == 0 );
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_LS_divide_Q16_FIX(
|
||||
opus_int32 T[], /* I/O Numenator vector */
|
||||
inv_D_t *inv_D, /* I 1 / D vector */
|
||||
opus_int M /* I dimension */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 tmp_32;
|
||||
opus_int32 one_div_diag_Q36, one_div_diag_Q48;
|
||||
|
||||
for( i = 0; i < M; i++ ) {
|
||||
one_div_diag_Q36 = inv_D[ i ].Q36_part;
|
||||
one_div_diag_Q48 = inv_D[ i ].Q48_part;
|
||||
|
||||
tmp_32 = T[ i ];
|
||||
T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
|
||||
static OPUS_INLINE void silk_LS_SolveFirst_FIX(
|
||||
const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const opus_int32 *b, /* I b Vector */
|
||||
opus_int32 *x_Q16 /* O x Vector */
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
const opus_int32 *ptr32;
|
||||
opus_int32 tmp_32;
|
||||
|
||||
for( i = 0; i < M; i++ ) {
|
||||
ptr32 = matrix_adr( L_Q16, i, 0, M );
|
||||
tmp_32 = 0;
|
||||
for( j = 0; j < i; j++ ) {
|
||||
tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );
|
||||
}
|
||||
x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
|
||||
static OPUS_INLINE void silk_LS_SolveLast_FIX(
|
||||
const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
|
||||
const opus_int M, /* I Dim of Matrix equation */
|
||||
const opus_int32 *b, /* I b Vector */
|
||||
opus_int32 *x_Q16 /* O x Vector */
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
const opus_int32 *ptr32;
|
||||
opus_int32 tmp_32;
|
||||
|
||||
for( i = M - 1; i >= 0; i-- ) {
|
||||
ptr32 = matrix_adr( L_Q16, 0, i, M );
|
||||
tmp_32 = 0;
|
||||
for( j = M - 1; j > i; j-- ) {
|
||||
tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] );
|
||||
}
|
||||
x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
|
||||
}
|
||||
}
|
134
node_modules/node-opus/deps/opus/silk/fixed/structs_FIX.h
generated
vendored
Normal file
134
node_modules/node-opus/deps/opus/silk/fixed/structs_FIX.h
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_STRUCTS_FIX_H
|
||||
#define SILK_STRUCTS_FIX_H
|
||||
|
||||
#include "typedef.h"
|
||||
#include "main.h"
|
||||
#include "structs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/********************************/
|
||||
/* Noise shaping analysis state */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
opus_int8 LastGainIndex;
|
||||
opus_int32 HarmBoost_smth_Q16;
|
||||
opus_int32 HarmShapeGain_smth_Q16;
|
||||
opus_int32 Tilt_smth_Q16;
|
||||
} silk_shape_state_FIX;
|
||||
|
||||
/********************************/
|
||||
/* Prefilter state */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
opus_int16 sLTP_shp[ LTP_BUF_LENGTH ];
|
||||
opus_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int sLTP_shp_buf_idx;
|
||||
opus_int32 sLF_AR_shp_Q12;
|
||||
opus_int32 sLF_MA_shp_Q12;
|
||||
opus_int32 sHarmHP_Q2;
|
||||
opus_int32 rand_seed;
|
||||
opus_int lagPrev;
|
||||
} silk_prefilter_state_FIX;
|
||||
|
||||
/********************************/
|
||||
/* Encoder state FIX */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
|
||||
silk_shape_state_FIX sShape; /* Shape state */
|
||||
silk_prefilter_state_FIX sPrefilt; /* Prefilter State */
|
||||
|
||||
/* Buffer for find pitch and noise shape analysis */
|
||||
silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
||||
opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
|
||||
} silk_encoder_state_FIX;
|
||||
|
||||
/************************/
|
||||
/* Encoder control FIX */
|
||||
/************************/
|
||||
typedef struct {
|
||||
/* Prediction and coding parameters */
|
||||
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
||||
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
|
||||
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
|
||||
opus_int LTP_scale_Q14;
|
||||
opus_int pitchL[ MAX_NB_SUBFR ];
|
||||
|
||||
/* Noise shaping parameters */
|
||||
/* Testing */
|
||||
silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
|
||||
opus_int GainsPre_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int HarmBoost_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int Tilt_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
|
||||
opus_int Lambda_Q10;
|
||||
opus_int input_quality_Q14;
|
||||
opus_int coding_quality_Q14;
|
||||
|
||||
/* measures */
|
||||
opus_int sparseness_Q8;
|
||||
opus_int32 predGain_Q16;
|
||||
opus_int LTPredCodGain_Q7;
|
||||
opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
|
||||
opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */
|
||||
|
||||
/* Parameters for CBR mode */
|
||||
opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
|
||||
opus_int8 lastGainIndexPrev;
|
||||
} silk_encoder_control_FIX;
|
||||
|
||||
/************************/
|
||||
/* Encoder Super Struct */
|
||||
/************************/
|
||||
typedef struct {
|
||||
silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ];
|
||||
stereo_enc_state sStereo;
|
||||
opus_int32 nBitsUsedLBRR;
|
||||
opus_int32 nBitsExceeded;
|
||||
opus_int nChannelsAPI;
|
||||
opus_int nChannelsInternal;
|
||||
opus_int nPrevChannelsInternal;
|
||||
opus_int timeSinceSwitchAllowed_ms;
|
||||
opus_int allowBandwidthSwitch;
|
||||
opus_int prev_decode_only_middle;
|
||||
} silk_encoder;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
102
node_modules/node-opus/deps/opus/silk/fixed/vector_ops_FIX.c
generated
vendored
Normal file
102
node_modules/node-opus/deps/opus/silk/fixed/vector_ops_FIX.c
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
#include "pitch.h"
|
||||
|
||||
/* Copy and multiply a vector by a constant */
|
||||
void silk_scale_copy_vector16(
|
||||
opus_int16 *data_out,
|
||||
const opus_int16 *data_in,
|
||||
opus_int32 gain_Q16, /* I Gain in Q16 */
|
||||
const opus_int dataSize /* I Length */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 tmp32;
|
||||
|
||||
for( i = 0; i < dataSize; i++ ) {
|
||||
tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );
|
||||
data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply a vector by a constant */
|
||||
void silk_scale_vector32_Q26_lshift_18(
|
||||
opus_int32 *data1, /* I/O Q0/Q18 */
|
||||
opus_int32 gain_Q26, /* I Q26 */
|
||||
opus_int dataSize /* I length */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
|
||||
for( i = 0; i < dataSize; i++ ) {
|
||||
data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */
|
||||
}
|
||||
}
|
||||
|
||||
/* sum = for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */
|
||||
/* Note for ARM asm: */
|
||||
/* * inVec1 and inVec2 should be at least 2 byte aligned. */
|
||||
/* * len should be positive 16bit integer. */
|
||||
/* * only when len>6, memory access can be reduced by half. */
|
||||
opus_int32 silk_inner_prod_aligned(
|
||||
const opus_int16 *const inVec1, /* I input vector 1 */
|
||||
const opus_int16 *const inVec2, /* I input vector 2 */
|
||||
const opus_int len, /* I vector lengths */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
return celt_inner_prod(inVec1, inVec2, len, arch);
|
||||
#else
|
||||
opus_int i;
|
||||
opus_int32 sum = 0;
|
||||
for( i = 0; i < len; i++ ) {
|
||||
sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
return sum;
|
||||
#endif
|
||||
}
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_c(
|
||||
const opus_int16 *inVec1, /* I input vector 1 */
|
||||
const opus_int16 *inVec2, /* I input vector 2 */
|
||||
const opus_int len /* I vector lengths */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int64 sum = 0;
|
||||
for( i = 0; i < len; i++ ) {
|
||||
sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
return sum;
|
||||
}
|
95
node_modules/node-opus/deps/opus/silk/fixed/warped_autocorrelation_FIX.c
generated
vendored
Normal file
95
node_modules/node-opus/deps/opus/silk/fixed/warped_autocorrelation_FIX.c
generated
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FIX.h"
|
||||
|
||||
#define QC 10
|
||||
#define QS 14
|
||||
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/warped_autocorrelation_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OVERRIDE_silk_warped_autocorrelation_FIX
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
void silk_warped_autocorrelation_FIX(
|
||||
opus_int32 *corr, /* O Result [order + 1] */
|
||||
opus_int *scale, /* O Scaling of the correlation vector */
|
||||
const opus_int16 *input, /* I Input data to correlate */
|
||||
const opus_int warping_Q16, /* I Warping coefficient */
|
||||
const opus_int length, /* I Length of input */
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i, lsh;
|
||||
opus_int32 tmp1_QS, tmp2_QS;
|
||||
opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
silk_assert( 2 * QS - QC >= 0 );
|
||||
|
||||
/* Loop over samples */
|
||||
for( n = 0; n < length; n++ ) {
|
||||
tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
|
||||
/* Loop over allpass sections */
|
||||
for( i = 0; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
|
||||
state_QS[ i ] = tmp1_QS;
|
||||
corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
/* Output of allpass section */
|
||||
tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
|
||||
state_QS[ i + 1 ] = tmp2_QS;
|
||||
corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
}
|
||||
state_QS[ order ] = tmp1_QS;
|
||||
corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
|
||||
}
|
||||
|
||||
lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;
|
||||
lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
|
||||
*scale = -( QC + lsh );
|
||||
silk_assert( *scale >= -30 && *scale <= 12 );
|
||||
if( lsh >= 0 ) {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
|
||||
}
|
||||
} else {
|
||||
for( i = 0; i < order + 1; i++ ) {
|
||||
corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
|
||||
}
|
||||
}
|
||||
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
|
||||
}
|
||||
#endif /* OVERRIDE_silk_warped_autocorrelation_FIX */
|
375
node_modules/node-opus/deps/opus/silk/fixed/x86/burg_modified_FIX_sse.c
generated
vendored
Normal file
375
node_modules/node-opus/deps/opus/silk/fixed/x86/burg_modified_FIX_sse.c
generated
vendored
Normal file
@ -0,0 +1,375 @@
|
||||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
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.
|
||||
|
||||
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 COPYRIGHT OWNER
|
||||
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 <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "define.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "pitch.h"
|
||||
#include "celt/x86/x86cpu.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
|
||||
|
||||
#define QA 25
|
||||
#define N_BITS_HEAD_ROOM 2
|
||||
#define MIN_RSHIFTS -16
|
||||
#define MAX_RSHIFTS (32 - QA)
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
void silk_burg_modified_sse4_1(
|
||||
opus_int32 *res_nrg, /* O Residual energy */
|
||||
opus_int *res_nrg_Q, /* O Residual energy Q value */
|
||||
opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
|
||||
const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
|
||||
const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
|
||||
const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I Number of subframes stacked in x */
|
||||
const opus_int D, /* I Order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
|
||||
opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
|
||||
const opus_int16 *x_ptr;
|
||||
opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
__m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
|
||||
__m128i CONST1 = _mm_set1_epi32(1);
|
||||
|
||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* Compute autocorrelations, added over subframes */
|
||||
silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
|
||||
if( rshifts > MAX_RSHIFTS ) {
|
||||
C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
|
||||
silk_assert( C0 > 0 );
|
||||
rshifts = MAX_RSHIFTS;
|
||||
} else {
|
||||
lz = silk_CLZ32( C0 ) - 1;
|
||||
rshifts_extra = N_BITS_HEAD_ROOM - lz;
|
||||
if( rshifts_extra > 0 ) {
|
||||
rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
|
||||
C0 = silk_RSHIFT32( C0, rshifts_extra );
|
||||
} else {
|
||||
rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
|
||||
C0 = silk_LSHIFT32( C0, -rshifts_extra );
|
||||
}
|
||||
rshifts += rshifts_extra;
|
||||
}
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
|
||||
silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
int i;
|
||||
opus_int32 d;
|
||||
x_ptr = x + s * subfr_length;
|
||||
celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
|
||||
d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
|
||||
xcorr[ n - 1 ] += d;
|
||||
}
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
|
||||
}
|
||||
}
|
||||
}
|
||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
|
||||
/* Initialize */
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
|
||||
invGain_Q30 = (opus_int32)1 << 30;
|
||||
reached_max_gain = 0;
|
||||
for( n = 0; n < D; n++ ) {
|
||||
/* Update first row of correlation matrix (without first element) */
|
||||
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||
/* Update C * Af */
|
||||
/* Update C * flipud(Af) (stored in reversed order) */
|
||||
if( rshifts > -2 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
|
||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
|
||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
|
||||
for( k = 0; k < n; k++ ) {
|
||||
C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||
C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||
Atmp_QA = Af_QA[ k ];
|
||||
tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
|
||||
tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
|
||||
}
|
||||
tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||
tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
|
||||
for( k = 0; k <= n; k++ ) {
|
||||
CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
|
||||
CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
|
||||
x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
|
||||
tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
|
||||
tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
|
||||
|
||||
X1_3210 = _mm_set1_epi32( x1 );
|
||||
X2_3210 = _mm_set1_epi32( x2 );
|
||||
TMP1_3210 = _mm_setzero_si128();
|
||||
TMP2_3210 = _mm_setzero_si128();
|
||||
for( k = 0; k < n - 3; k += 4 ) {
|
||||
PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] );
|
||||
SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] );
|
||||
FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] );
|
||||
PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] );
|
||||
ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] );
|
||||
|
||||
T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 );
|
||||
T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 );
|
||||
|
||||
ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 );
|
||||
ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 );
|
||||
ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 );
|
||||
|
||||
FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 );
|
||||
LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 );
|
||||
|
||||
PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 );
|
||||
SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 );
|
||||
|
||||
_mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 );
|
||||
_mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 );
|
||||
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 );
|
||||
}
|
||||
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) );
|
||||
TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) );
|
||||
TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) );
|
||||
|
||||
tmp1 += _mm_cvtsi128_si32( TMP1_3210 );
|
||||
tmp2 += _mm_cvtsi128_si32( TMP2_3210 );
|
||||
|
||||
for( ; k < n; k++ ) {
|
||||
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
|
||||
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
|
||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
|
||||
tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||
}
|
||||
|
||||
tmp1 = -tmp1; /* Q17 */
|
||||
tmp2 = -tmp2; /* Q17 */
|
||||
|
||||
{
|
||||
__m128i xmm_tmp1, xmm_tmp2;
|
||||
__m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1;
|
||||
__m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1;
|
||||
|
||||
xmm_tmp1 = _mm_set1_epi32( tmp1 );
|
||||
xmm_tmp2 = _mm_set1_epi32( tmp2 );
|
||||
|
||||
for( k = 0; k <= n - 3; k += 4 ) {
|
||||
xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] );
|
||||
xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 );
|
||||
|
||||
/* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 );
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 );
|
||||
xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 );
|
||||
xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 );
|
||||
|
||||
xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC );
|
||||
xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC );
|
||||
|
||||
X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] );
|
||||
PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] );
|
||||
|
||||
X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 );
|
||||
PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 );
|
||||
|
||||
_mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 );
|
||||
_mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 );
|
||||
}
|
||||
|
||||
for( ; k <= n; k++ ) {
|
||||
CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
|
||||
silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||
CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
|
||||
silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
||||
tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
|
||||
tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
|
||||
num = 0; /* Q( -rshifts ) */
|
||||
nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
|
||||
for( k = 0; k < n; k++ ) {
|
||||
Atmp_QA = Af_QA[ k ];
|
||||
lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
|
||||
lz = silk_min( 32 - QA, lz );
|
||||
Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
|
||||
|
||||
tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
|
||||
nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
|
||||
Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
|
||||
}
|
||||
CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
|
||||
CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
|
||||
num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
|
||||
num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
|
||||
|
||||
/* Calculate the next order reflection (parcor) coefficient */
|
||||
if( silk_abs( num ) < nrg ) {
|
||||
rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
|
||||
} else {
|
||||
rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
|
||||
}
|
||||
|
||||
/* Update inverse prediction gain */
|
||||
tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
|
||||
tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
|
||||
if( tmp1 <= minInvGain_Q30 ) {
|
||||
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
|
||||
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
|
||||
/* Newton-Raphson iteration */
|
||||
rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
|
||||
rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
|
||||
if( num < 0 ) {
|
||||
/* Ensure adjusted reflection coefficients has the original sign */
|
||||
rc_Q31 = -rc_Q31;
|
||||
}
|
||||
invGain_Q30 = minInvGain_Q30;
|
||||
reached_max_gain = 1;
|
||||
} else {
|
||||
invGain_Q30 = tmp1;
|
||||
}
|
||||
|
||||
/* Update the AR coefficients */
|
||||
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||
tmp1 = Af_QA[ k ]; /* QA */
|
||||
tmp2 = Af_QA[ n - k - 1 ]; /* QA */
|
||||
Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
|
||||
Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
|
||||
}
|
||||
Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||
for( k = n + 1; k < D; k++ ) {
|
||||
Af_QA[ k ] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update C * Af and C * Ab */
|
||||
for( k = 0; k <= n + 1; k++ ) {
|
||||
tmp1 = CAf[ k ]; /* Q( -rshifts ) */
|
||||
tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
|
||||
CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||
CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
|
||||
}
|
||||
}
|
||||
|
||||
if( reached_max_gain ) {
|
||||
for( k = 0; k < D; k++ ) {
|
||||
/* Scale coefficients */
|
||||
A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
|
||||
}
|
||||
/* Subtract energy of preceding samples from C0 */
|
||||
if( rshifts > 0 ) {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
|
||||
}
|
||||
} else {
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts );
|
||||
}
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
*res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
|
||||
*res_nrg_Q = -rshifts;
|
||||
} else {
|
||||
/* Return residual energy */
|
||||
nrg = CAf[ 0 ]; /* Q( -rshifts ) */
|
||||
tmp1 = (opus_int32)1 << 16; /* Q16 */
|
||||
for( k = 0; k < D; k++ ) {
|
||||
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
|
||||
nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
|
||||
tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
|
||||
A_Q16[ k ] = -Atmp1;
|
||||
}
|
||||
*res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
|
||||
*res_nrg_Q = -rshifts;
|
||||
}
|
||||
}
|
160
node_modules/node-opus/deps/opus/silk/fixed/x86/prefilter_FIX_sse.c
generated
vendored
Normal file
160
node_modules/node-opus/deps/opus/silk/fixed/x86/prefilter_FIX_sse.c
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
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.
|
||||
|
||||
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 COPYRIGHT OWNER
|
||||
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 <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include "main.h"
|
||||
#include "celt/x86/x86cpu.h"
|
||||
|
||||
void silk_warped_LPC_analysis_filter_FIX_sse4_1(
|
||||
opus_int32 state[], /* I/O State [order + 1] */
|
||||
opus_int32 res_Q2[], /* O Residual signal [length] */
|
||||
const opus_int16 coef_Q13[], /* I Coefficients [order] */
|
||||
const opus_int16 input[], /* I Input signal [length] */
|
||||
const opus_int16 lambda_Q16, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order /* I Filter order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i;
|
||||
opus_int32 acc_Q11, tmp1, tmp2;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
|
||||
if (order == 10)
|
||||
{
|
||||
if (0 == lambda_Q16)
|
||||
{
|
||||
__m128i coef_Q13_3210, coef_Q13_7654;
|
||||
__m128i coef_Q13_0123, coef_Q13_4567;
|
||||
__m128i state_0123, state_4567;
|
||||
__m128i xmm_product1, xmm_product2;
|
||||
__m128i xmm_tempa, xmm_tempb;
|
||||
|
||||
register opus_int32 sum;
|
||||
register opus_int32 state_8, state_9, state_a;
|
||||
register opus_int64 coef_Q13_8, coef_Q13_9;
|
||||
|
||||
silk_assert( length > 0 );
|
||||
|
||||
coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
|
||||
coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
|
||||
|
||||
coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];
|
||||
coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];
|
||||
|
||||
state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );
|
||||
state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );
|
||||
|
||||
state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
state_8 = state[ 8 ];
|
||||
state_9 = state[ 9 ];
|
||||
state_a = 0;
|
||||
|
||||
for( n = 0; n < length; n++ )
|
||||
{
|
||||
xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */
|
||||
xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );
|
||||
|
||||
xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
|
||||
|
||||
xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */
|
||||
xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );
|
||||
|
||||
xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );
|
||||
xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );
|
||||
|
||||
xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );
|
||||
xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );
|
||||
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );
|
||||
xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
|
||||
|
||||
sum = (coef_Q13_8 * state_8) >> 16;
|
||||
sum += (coef_Q13_9 * state_9) >> 16;
|
||||
|
||||
xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
|
||||
sum += _mm_cvtsi128_si32( xmm_tempa);
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);
|
||||
|
||||
/* move right */
|
||||
state_a = state_9;
|
||||
state_9 = state_8;
|
||||
state_8 = _mm_cvtsi128_si32( state_4567 );
|
||||
state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );
|
||||
|
||||
state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );
|
||||
}
|
||||
|
||||
_mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
|
||||
_mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
|
||||
state[ 8 ] = state_8;
|
||||
state[ 9 ] = state_9;
|
||||
state[ 10 ] = state_a;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for( n = 0; n < length; n++ ) {
|
||||
/* Output of lowpass section */
|
||||
tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
|
||||
state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
|
||||
state[ 1 ] = tmp2;
|
||||
acc_Q11 = silk_RSHIFT( order, 1 );
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
|
||||
/* Loop over allpass sections */
|
||||
for( i = 2; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
|
||||
state[ i ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
|
||||
/* Output of allpass section */
|
||||
tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
|
||||
state[ i + 1 ] = tmp2;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
|
||||
}
|
||||
state[ order ] = tmp1;
|
||||
acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
|
||||
res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
|
||||
}
|
||||
}
|
88
node_modules/node-opus/deps/opus/silk/fixed/x86/vector_ops_FIX_sse.c
generated
vendored
Normal file
88
node_modules/node-opus/deps/opus/silk/fixed/x86/vector_ops_FIX_sse.c
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/* Copyright (c) 2014, Cisco Systems, INC
|
||||
Written by XiangMingZhu WeiZhou MinPeng YanWang
|
||||
|
||||
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.
|
||||
|
||||
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 COPYRIGHT OWNER
|
||||
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 <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include "main.h"
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "pitch.h"
|
||||
|
||||
opus_int64 silk_inner_prod16_aligned_64_sse4_1(
|
||||
const opus_int16 *inVec1, /* I input vector 1 */
|
||||
const opus_int16 *inVec2, /* I input vector 2 */
|
||||
const opus_int len /* I vector lengths */
|
||||
)
|
||||
{
|
||||
opus_int i, dataSize8;
|
||||
opus_int64 sum;
|
||||
|
||||
__m128i xmm_tempa;
|
||||
__m128i inVec1_76543210, acc1;
|
||||
__m128i inVec2_76543210, acc2;
|
||||
|
||||
sum = 0;
|
||||
dataSize8 = len & ~7;
|
||||
|
||||
acc1 = _mm_setzero_si128();
|
||||
acc2 = _mm_setzero_si128();
|
||||
|
||||
for( i = 0; i < dataSize8; i += 8 ) {
|
||||
inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );
|
||||
inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );
|
||||
|
||||
/* only when all 4 operands are -32768 (0x8000), this results in wrap around */
|
||||
inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );
|
||||
|
||||
xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
/* equal shift right 8 bytes */
|
||||
inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );
|
||||
inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, xmm_tempa );
|
||||
acc2 = _mm_add_epi64( acc2, inVec1_76543210 );
|
||||
}
|
||||
|
||||
acc1 = _mm_add_epi64( acc1, acc2 );
|
||||
|
||||
/* equal shift right 8 bytes */
|
||||
acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) );
|
||||
acc1 = _mm_add_epi64( acc1, acc2 );
|
||||
|
||||
_mm_storel_epi64( (__m128i *)&sum, acc1 );
|
||||
|
||||
for( ; i < len; i++ ) {
|
||||
sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
249
node_modules/node-opus/deps/opus/silk/float/LPC_analysis_filter_FLP.c
generated
vendored
Normal file
249
node_modules/node-opus/deps/opus/silk/float/LPC_analysis_filter_FLP.c
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 <stdlib.h>
|
||||
#include "main_FLP.h"
|
||||
|
||||
/************************************************/
|
||||
/* LPC analysis filter */
|
||||
/* NB! State is kept internally and the */
|
||||
/* filter always starts with zero state */
|
||||
/* first Order output samples are set to zero */
|
||||
/************************************************/
|
||||
|
||||
/* 16th order LPC analysis filter, does not write first 16 samples */
|
||||
static OPUS_INLINE void silk_LPC_analysis_filter16_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length /* I Length of input signal */
|
||||
)
|
||||
{
|
||||
opus_int ix;
|
||||
silk_float LPC_pred;
|
||||
const silk_float *s_ptr;
|
||||
|
||||
for( ix = 16; ix < length; ix++ ) {
|
||||
s_ptr = &s[ix - 1];
|
||||
|
||||
/* short-term prediction */
|
||||
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
|
||||
s_ptr[ -1 ] * PredCoef[ 1 ] +
|
||||
s_ptr[ -2 ] * PredCoef[ 2 ] +
|
||||
s_ptr[ -3 ] * PredCoef[ 3 ] +
|
||||
s_ptr[ -4 ] * PredCoef[ 4 ] +
|
||||
s_ptr[ -5 ] * PredCoef[ 5 ] +
|
||||
s_ptr[ -6 ] * PredCoef[ 6 ] +
|
||||
s_ptr[ -7 ] * PredCoef[ 7 ] +
|
||||
s_ptr[ -8 ] * PredCoef[ 8 ] +
|
||||
s_ptr[ -9 ] * PredCoef[ 9 ] +
|
||||
s_ptr[ -10 ] * PredCoef[ 10 ] +
|
||||
s_ptr[ -11 ] * PredCoef[ 11 ] +
|
||||
s_ptr[ -12 ] * PredCoef[ 12 ] +
|
||||
s_ptr[ -13 ] * PredCoef[ 13 ] +
|
||||
s_ptr[ -14 ] * PredCoef[ 14 ] +
|
||||
s_ptr[ -15 ] * PredCoef[ 15 ];
|
||||
|
||||
/* prediction error */
|
||||
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* 12th order LPC analysis filter, does not write first 12 samples */
|
||||
static OPUS_INLINE void silk_LPC_analysis_filter12_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length /* I Length of input signal */
|
||||
)
|
||||
{
|
||||
opus_int ix;
|
||||
silk_float LPC_pred;
|
||||
const silk_float *s_ptr;
|
||||
|
||||
for( ix = 12; ix < length; ix++ ) {
|
||||
s_ptr = &s[ix - 1];
|
||||
|
||||
/* short-term prediction */
|
||||
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
|
||||
s_ptr[ -1 ] * PredCoef[ 1 ] +
|
||||
s_ptr[ -2 ] * PredCoef[ 2 ] +
|
||||
s_ptr[ -3 ] * PredCoef[ 3 ] +
|
||||
s_ptr[ -4 ] * PredCoef[ 4 ] +
|
||||
s_ptr[ -5 ] * PredCoef[ 5 ] +
|
||||
s_ptr[ -6 ] * PredCoef[ 6 ] +
|
||||
s_ptr[ -7 ] * PredCoef[ 7 ] +
|
||||
s_ptr[ -8 ] * PredCoef[ 8 ] +
|
||||
s_ptr[ -9 ] * PredCoef[ 9 ] +
|
||||
s_ptr[ -10 ] * PredCoef[ 10 ] +
|
||||
s_ptr[ -11 ] * PredCoef[ 11 ];
|
||||
|
||||
/* prediction error */
|
||||
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* 10th order LPC analysis filter, does not write first 10 samples */
|
||||
static OPUS_INLINE void silk_LPC_analysis_filter10_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length /* I Length of input signal */
|
||||
)
|
||||
{
|
||||
opus_int ix;
|
||||
silk_float LPC_pred;
|
||||
const silk_float *s_ptr;
|
||||
|
||||
for( ix = 10; ix < length; ix++ ) {
|
||||
s_ptr = &s[ix - 1];
|
||||
|
||||
/* short-term prediction */
|
||||
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
|
||||
s_ptr[ -1 ] * PredCoef[ 1 ] +
|
||||
s_ptr[ -2 ] * PredCoef[ 2 ] +
|
||||
s_ptr[ -3 ] * PredCoef[ 3 ] +
|
||||
s_ptr[ -4 ] * PredCoef[ 4 ] +
|
||||
s_ptr[ -5 ] * PredCoef[ 5 ] +
|
||||
s_ptr[ -6 ] * PredCoef[ 6 ] +
|
||||
s_ptr[ -7 ] * PredCoef[ 7 ] +
|
||||
s_ptr[ -8 ] * PredCoef[ 8 ] +
|
||||
s_ptr[ -9 ] * PredCoef[ 9 ];
|
||||
|
||||
/* prediction error */
|
||||
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* 8th order LPC analysis filter, does not write first 8 samples */
|
||||
static OPUS_INLINE void silk_LPC_analysis_filter8_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length /* I Length of input signal */
|
||||
)
|
||||
{
|
||||
opus_int ix;
|
||||
silk_float LPC_pred;
|
||||
const silk_float *s_ptr;
|
||||
|
||||
for( ix = 8; ix < length; ix++ ) {
|
||||
s_ptr = &s[ix - 1];
|
||||
|
||||
/* short-term prediction */
|
||||
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
|
||||
s_ptr[ -1 ] * PredCoef[ 1 ] +
|
||||
s_ptr[ -2 ] * PredCoef[ 2 ] +
|
||||
s_ptr[ -3 ] * PredCoef[ 3 ] +
|
||||
s_ptr[ -4 ] * PredCoef[ 4 ] +
|
||||
s_ptr[ -5 ] * PredCoef[ 5 ] +
|
||||
s_ptr[ -6 ] * PredCoef[ 6 ] +
|
||||
s_ptr[ -7 ] * PredCoef[ 7 ];
|
||||
|
||||
/* prediction error */
|
||||
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* 6th order LPC analysis filter, does not write first 6 samples */
|
||||
static OPUS_INLINE void silk_LPC_analysis_filter6_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length /* I Length of input signal */
|
||||
)
|
||||
{
|
||||
opus_int ix;
|
||||
silk_float LPC_pred;
|
||||
const silk_float *s_ptr;
|
||||
|
||||
for( ix = 6; ix < length; ix++ ) {
|
||||
s_ptr = &s[ix - 1];
|
||||
|
||||
/* short-term prediction */
|
||||
LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
|
||||
s_ptr[ -1 ] * PredCoef[ 1 ] +
|
||||
s_ptr[ -2 ] * PredCoef[ 2 ] +
|
||||
s_ptr[ -3 ] * PredCoef[ 3 ] +
|
||||
s_ptr[ -4 ] * PredCoef[ 4 ] +
|
||||
s_ptr[ -5 ] * PredCoef[ 5 ];
|
||||
|
||||
/* prediction error */
|
||||
r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* LPC analysis filter */
|
||||
/* NB! State is kept internally and the */
|
||||
/* filter always starts with zero state */
|
||||
/* first Order output samples are set to zero */
|
||||
/************************************************/
|
||||
void silk_LPC_analysis_filter_FLP(
|
||||
silk_float r_LPC[], /* O LPC residual signal */
|
||||
const silk_float PredCoef[], /* I LPC coefficients */
|
||||
const silk_float s[], /* I Input signal */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int Order /* I LPC order */
|
||||
)
|
||||
{
|
||||
silk_assert( Order <= length );
|
||||
|
||||
switch( Order ) {
|
||||
case 6:
|
||||
silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length );
|
||||
break;
|
||||
|
||||
case 10:
|
||||
silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );
|
||||
break;
|
||||
|
||||
case 12:
|
||||
silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );
|
||||
break;
|
||||
|
||||
case 16:
|
||||
silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );
|
||||
break;
|
||||
|
||||
default:
|
||||
silk_assert( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set first Order output samples to zero */
|
||||
silk_memset( r_LPC, 0, Order * sizeof( silk_float ) );
|
||||
}
|
||||
|
76
node_modules/node-opus/deps/opus/silk/float/LPC_inv_pred_gain_FLP.c
generated
vendored
Normal file
76
node_modules/node-opus/deps/opus/silk/float/LPC_inv_pred_gain_FLP.c
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FIX.h"
|
||||
#include "SigProc_FLP.h"
|
||||
|
||||
#define RC_THRESHOLD 0.9999f
|
||||
|
||||
/* compute inverse of LPC prediction gain, and */
|
||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||
/* this code is based on silk_a2k_FLP() */
|
||||
silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
|
||||
const silk_float *A, /* I prediction coefficients [order] */
|
||||
opus_int32 order /* I prediction order */
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
double invGain, rc, rc_mult1, rc_mult2;
|
||||
silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||
silk_float *Aold, *Anew;
|
||||
|
||||
Anew = Atmp[ order & 1 ];
|
||||
silk_memcpy( Anew, A, order * sizeof(silk_float) );
|
||||
|
||||
invGain = 1.0;
|
||||
for( k = order - 1; k > 0; k-- ) {
|
||||
rc = -Anew[ k ];
|
||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||
return 0.0f;
|
||||
}
|
||||
rc_mult1 = 1.0f - rc * rc;
|
||||
rc_mult2 = 1.0f / rc_mult1;
|
||||
invGain *= rc_mult1;
|
||||
/* swap pointers */
|
||||
Aold = Anew;
|
||||
Anew = Atmp[ k & 1 ];
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );
|
||||
}
|
||||
}
|
||||
rc = -Anew[ 0 ];
|
||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||
return 0.0f;
|
||||
}
|
||||
rc_mult1 = 1.0f - rc * rc;
|
||||
invGain *= rc_mult1;
|
||||
return (silk_float)invGain;
|
||||
}
|
75
node_modules/node-opus/deps/opus/silk/float/LTP_analysis_filter_FLP.c
generated
vendored
Normal file
75
node_modules/node-opus/deps/opus/silk/float/LTP_analysis_filter_FLP.c
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FLP.h"
|
||||
|
||||
void silk_LTP_analysis_filter_FLP(
|
||||
silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
|
||||
const silk_float *x, /* I Input signal, with preceding samples */
|
||||
const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
|
||||
const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
|
||||
const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
|
||||
const opus_int subfr_length, /* I Length of each subframe */
|
||||
const opus_int nb_subfr, /* I number of subframes */
|
||||
const opus_int pre_length /* I Preceding samples for each subframe */
|
||||
)
|
||||
{
|
||||
const silk_float *x_ptr, *x_lag_ptr;
|
||||
silk_float Btmp[ LTP_ORDER ];
|
||||
silk_float *LTP_res_ptr;
|
||||
silk_float inv_gain;
|
||||
opus_int k, i, j;
|
||||
|
||||
x_ptr = x;
|
||||
LTP_res_ptr = LTP_res;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
x_lag_ptr = x_ptr - pitchL[ k ];
|
||||
inv_gain = invGains[ k ];
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
Btmp[ i ] = B[ k * LTP_ORDER + i ];
|
||||
}
|
||||
|
||||
/* LTP analysis FIR filter */
|
||||
for( i = 0; i < subfr_length + pre_length; i++ ) {
|
||||
LTP_res_ptr[ i ] = x_ptr[ i ];
|
||||
/* Subtract long-term prediction */
|
||||
for( j = 0; j < LTP_ORDER; j++ ) {
|
||||
LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ];
|
||||
}
|
||||
LTP_res_ptr[ i ] *= inv_gain;
|
||||
x_lag_ptr++;
|
||||
}
|
||||
|
||||
/* Update pointers */
|
||||
LTP_res_ptr += subfr_length + pre_length;
|
||||
x_ptr += subfr_length;
|
||||
}
|
||||
}
|
52
node_modules/node-opus/deps/opus/silk/float/LTP_scale_ctrl_FLP.c
generated
vendored
Normal file
52
node_modules/node-opus/deps/opus/silk/float/LTP_scale_ctrl_FLP.c
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FLP.h"
|
||||
|
||||
void silk_LTP_scale_ctrl_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
|
||||
opus_int condCoding /* I The type of conditional coding to use */
|
||||
)
|
||||
{
|
||||
opus_int round_loss;
|
||||
|
||||
if( condCoding == CODE_INDEPENDENTLY ) {
|
||||
/* Only scale if first frame in packet */
|
||||
round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f );
|
||||
} else {
|
||||
/* Default is minimum scaling */
|
||||
psEnc->sCmn.indices.LTP_scaleIndex = 0;
|
||||
}
|
||||
|
||||
psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
|
||||
}
|
204
node_modules/node-opus/deps/opus/silk/float/SigProc_FLP.h
generated
vendored
Normal file
204
node_modules/node-opus/deps/opus/silk/float/SigProc_FLP.h
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SILK_SIGPROC_FLP_H
|
||||
#define SILK_SIGPROC_FLP_H
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "float_cast.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/********************************************************************/
|
||||
/* SIGNAL PROCESSING FUNCTIONS */
|
||||
/********************************************************************/
|
||||
|
||||
/* Chirp (bw expand) LP AR filter */
|
||||
void silk_bwexpander_FLP(
|
||||
silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I length of ar */
|
||||
const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
|
||||
);
|
||||
|
||||
/* compute inverse of LPC prediction gain, and */
|
||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||
/* this code is based on silk_FLP_a2k() */
|
||||
silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
|
||||
const silk_float *A, /* I prediction coefficients [order] */
|
||||
opus_int32 order /* I prediction order */
|
||||
);
|
||||
|
||||
silk_float silk_schur_FLP( /* O returns residual energy */
|
||||
silk_float refl_coef[], /* O reflection coefficients (length order) */
|
||||
const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */
|
||||
opus_int order /* I order */
|
||||
);
|
||||
|
||||
void silk_k2a_FLP(
|
||||
silk_float *A, /* O prediction coefficients [order] */
|
||||
const silk_float *rc, /* I reflection coefficients [order] */
|
||||
opus_int32 order /* I prediction order */
|
||||
);
|
||||
|
||||
/* Solve the normal equations using the Levinson-Durbin recursion */
|
||||
silk_float silk_levinsondurbin_FLP( /* O prediction error energy */
|
||||
silk_float A[], /* O prediction coefficients [order] */
|
||||
const silk_float corr[], /* I input auto-correlations [order + 1] */
|
||||
const opus_int order /* I prediction order */
|
||||
);
|
||||
|
||||
/* compute autocorrelation */
|
||||
void silk_autocorrelation_FLP(
|
||||
silk_float *results, /* O result (length correlationCount) */
|
||||
const silk_float *inputData, /* I input data to correlate */
|
||||
opus_int inputDataSize, /* I length of input */
|
||||
opus_int correlationCount /* I number of correlation taps to compute */
|
||||
);
|
||||
|
||||
opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
|
||||
const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
|
||||
opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
|
||||
opus_int16 *lagIndex, /* O Lag Index */
|
||||
opus_int8 *contourIndex, /* O Pitch contour Index */
|
||||
silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
|
||||
opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
|
||||
const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
|
||||
const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
|
||||
const opus_int Fs_kHz, /* I sample frequency (kHz) */
|
||||
const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
|
||||
const opus_int nb_subfr, /* I Number of 5 ms subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_insertion_sort_decreasing_FLP(
|
||||
silk_float *a, /* I/O Unsorted / Sorted vector */
|
||||
opus_int *idx, /* O Index vector for the sorted elements */
|
||||
const opus_int L, /* I Vector length */
|
||||
const opus_int K /* I Number of correctly sorted positions */
|
||||
);
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
||||
silk_float A[], /* O prediction coefficients (length order) */
|
||||
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
||||
const silk_float minInvGain, /* I minimum inverse prediction gain */
|
||||
const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
||||
const opus_int D /* I order */
|
||||
);
|
||||
|
||||
/* multiply a vector by a constant */
|
||||
void silk_scale_vector_FLP(
|
||||
silk_float *data1,
|
||||
silk_float gain,
|
||||
opus_int dataSize
|
||||
);
|
||||
|
||||
/* copy and multiply a vector by a constant */
|
||||
void silk_scale_copy_vector_FLP(
|
||||
silk_float *data_out,
|
||||
const silk_float *data_in,
|
||||
silk_float gain,
|
||||
opus_int dataSize
|
||||
);
|
||||
|
||||
/* inner product of two silk_float arrays, with result as double */
|
||||
double silk_inner_product_FLP(
|
||||
const silk_float *data1,
|
||||
const silk_float *data2,
|
||||
opus_int dataSize
|
||||
);
|
||||
|
||||
/* sum of squares of a silk_float array, with result as double */
|
||||
double silk_energy_FLP(
|
||||
const silk_float *data,
|
||||
opus_int dataSize
|
||||
);
|
||||
|
||||
/********************************************************************/
|
||||
/* MACROS */
|
||||
/********************************************************************/
|
||||
|
||||
#define PI (3.1415926536f)
|
||||
|
||||
#define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b))
|
||||
#define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b))
|
||||
#define silk_abs_float( a ) ((silk_float)fabs(a))
|
||||
|
||||
/* sigmoid function */
|
||||
static OPUS_INLINE silk_float silk_sigmoid( silk_float x )
|
||||
{
|
||||
return (silk_float)(1.0 / (1.0 + exp(-x)));
|
||||
}
|
||||
|
||||
/* floating-point to integer conversion (rounding) */
|
||||
static OPUS_INLINE opus_int32 silk_float2int( silk_float x )
|
||||
{
|
||||
return (opus_int32)float2int( x );
|
||||
}
|
||||
|
||||
/* floating-point to integer conversion (rounding) */
|
||||
static OPUS_INLINE void silk_float2short_array(
|
||||
opus_int16 *out,
|
||||
const silk_float *in,
|
||||
opus_int32 length
|
||||
)
|
||||
{
|
||||
opus_int32 k;
|
||||
for( k = length - 1; k >= 0; k-- ) {
|
||||
out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* integer to floating-point conversion */
|
||||
static OPUS_INLINE void silk_short2float_array(
|
||||
silk_float *out,
|
||||
const opus_int16 *in,
|
||||
opus_int32 length
|
||||
)
|
||||
{
|
||||
opus_int32 k;
|
||||
for( k = length - 1; k >= 0; k-- ) {
|
||||
out[k] = (silk_float)in[k];
|
||||
}
|
||||
}
|
||||
|
||||
/* using log2() helps the fixed-point conversion */
|
||||
static OPUS_INLINE silk_float silk_log2( double x )
|
||||
{
|
||||
return ( silk_float )( 3.32192809488736 * log10( x ) );
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SILK_SIGPROC_FLP_H */
|
81
node_modules/node-opus/deps/opus/silk/float/apply_sine_window_FLP.c
generated
vendored
Normal file
81
node_modules/node-opus/deps/opus/silk/float/apply_sine_window_FLP.c
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FLP.h"
|
||||
|
||||
/* Apply sine window to signal vector */
|
||||
/* Window types: */
|
||||
/* 1 -> sine window from 0 to pi/2 */
|
||||
/* 2 -> sine window from pi/2 to pi */
|
||||
void silk_apply_sine_window_FLP(
|
||||
silk_float px_win[], /* O Pointer to windowed signal */
|
||||
const silk_float px[], /* I Pointer to input signal */
|
||||
const opus_int win_type, /* I Selects a window type */
|
||||
const opus_int length /* I Window length, multiple of 4 */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
silk_float freq, c, S0, S1;
|
||||
|
||||
silk_assert( win_type == 1 || win_type == 2 );
|
||||
|
||||
/* Length must be multiple of 4 */
|
||||
silk_assert( ( length & 3 ) == 0 );
|
||||
|
||||
freq = PI / ( length + 1 );
|
||||
|
||||
/* Approximation of 2 * cos(f) */
|
||||
c = 2.0f - freq * freq;
|
||||
|
||||
/* Initialize state */
|
||||
if( win_type < 2 ) {
|
||||
/* Start from 0 */
|
||||
S0 = 0.0f;
|
||||
/* Approximation of sin(f) */
|
||||
S1 = freq;
|
||||
} else {
|
||||
/* Start from 1 */
|
||||
S0 = 1.0f;
|
||||
/* Approximation of cos(f) */
|
||||
S1 = 0.5f * c;
|
||||
}
|
||||
|
||||
/* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
|
||||
/* 4 samples at a time */
|
||||
for( k = 0; k < length; k += 4 ) {
|
||||
px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );
|
||||
px_win[ k + 1 ] = px[ k + 1 ] * S1;
|
||||
S0 = c * S1 - S0;
|
||||
px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );
|
||||
px_win[ k + 3 ] = px[ k + 3 ] * S0;
|
||||
S1 = c * S0 - S1;
|
||||
}
|
||||
}
|
52
node_modules/node-opus/deps/opus/silk/float/autocorrelation_FLP.c
generated
vendored
Normal file
52
node_modules/node-opus/deps/opus/silk/float/autocorrelation_FLP.c
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "typedef.h"
|
||||
#include "SigProc_FLP.h"
|
||||
|
||||
/* compute autocorrelation */
|
||||
void silk_autocorrelation_FLP(
|
||||
silk_float *results, /* O result (length correlationCount) */
|
||||
const silk_float *inputData, /* I input data to correlate */
|
||||
opus_int inputDataSize, /* I length of input */
|
||||
opus_int correlationCount /* I number of correlation taps to compute */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
|
||||
if( correlationCount > inputDataSize ) {
|
||||
correlationCount = inputDataSize;
|
||||
}
|
||||
|
||||
for( i = 0; i < correlationCount; i++ ) {
|
||||
results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i );
|
||||
}
|
||||
}
|
186
node_modules/node-opus/deps/opus/silk/float/burg_modified_FLP.c
generated
vendored
Normal file
186
node_modules/node-opus/deps/opus/silk/float/burg_modified_FLP.c
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
#include "define.h"
|
||||
|
||||
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
silk_float silk_burg_modified_FLP( /* O returns residual energy */
|
||||
silk_float A[], /* O prediction coefficients (length order) */
|
||||
const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
|
||||
const silk_float minInvGain, /* I minimum inverse prediction gain */
|
||||
const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
|
||||
const opus_int nb_subfr, /* I number of subframes stacked in x */
|
||||
const opus_int D /* I order */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, reached_max_gain;
|
||||
double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
|
||||
const silk_float *x_ptr;
|
||||
double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
|
||||
double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
|
||||
double Af[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
|
||||
|
||||
/* Compute autocorrelations, added over subframes */
|
||||
C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
|
||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) );
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
for( n = 1; n < D + 1; n++ ) {
|
||||
C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n );
|
||||
}
|
||||
}
|
||||
silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
|
||||
|
||||
/* Initialize */
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;
|
||||
invGain = 1.0f;
|
||||
reached_max_gain = 0;
|
||||
for( n = 0; n < D; n++ ) {
|
||||
/* Update first row of correlation matrix (without first element) */
|
||||
/* Update last row of correlation matrix (without last element, stored in reversed order) */
|
||||
/* Update C * Af */
|
||||
/* Update C * flipud(Af) (stored in reversed order) */
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
x_ptr = x + s * subfr_length;
|
||||
tmp1 = x_ptr[ n ];
|
||||
tmp2 = x_ptr[ subfr_length - n - 1 ];
|
||||
for( k = 0; k < n; k++ ) {
|
||||
C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];
|
||||
C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];
|
||||
Atmp = Af[ k ];
|
||||
tmp1 += x_ptr[ n - k - 1 ] * Atmp;
|
||||
tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;
|
||||
}
|
||||
for( k = 0; k <= n; k++ ) {
|
||||
CAf[ k ] -= tmp1 * x_ptr[ n - k ];
|
||||
CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];
|
||||
}
|
||||
}
|
||||
tmp1 = C_first_row[ n ];
|
||||
tmp2 = C_last_row[ n ];
|
||||
for( k = 0; k < n; k++ ) {
|
||||
Atmp = Af[ k ];
|
||||
tmp1 += C_last_row[ n - k - 1 ] * Atmp;
|
||||
tmp2 += C_first_row[ n - k - 1 ] * Atmp;
|
||||
}
|
||||
CAf[ n + 1 ] = tmp1;
|
||||
CAb[ n + 1 ] = tmp2;
|
||||
|
||||
/* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
|
||||
num = CAb[ n + 1 ];
|
||||
nrg_b = CAb[ 0 ];
|
||||
nrg_f = CAf[ 0 ];
|
||||
for( k = 0; k < n; k++ ) {
|
||||
Atmp = Af[ k ];
|
||||
num += CAb[ n - k ] * Atmp;
|
||||
nrg_b += CAb[ k + 1 ] * Atmp;
|
||||
nrg_f += CAf[ k + 1 ] * Atmp;
|
||||
}
|
||||
silk_assert( nrg_f > 0.0 );
|
||||
silk_assert( nrg_b > 0.0 );
|
||||
|
||||
/* Calculate the next order reflection (parcor) coefficient */
|
||||
rc = -2.0 * num / ( nrg_f + nrg_b );
|
||||
silk_assert( rc > -1.0 && rc < 1.0 );
|
||||
|
||||
/* Update inverse prediction gain */
|
||||
tmp1 = invGain * ( 1.0 - rc * rc );
|
||||
if( tmp1 <= minInvGain ) {
|
||||
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
|
||||
rc = sqrt( 1.0 - minInvGain / invGain );
|
||||
if( num > 0 ) {
|
||||
/* Ensure adjusted reflection coefficients has the original sign */
|
||||
rc = -rc;
|
||||
}
|
||||
invGain = minInvGain;
|
||||
reached_max_gain = 1;
|
||||
} else {
|
||||
invGain = tmp1;
|
||||
}
|
||||
|
||||
/* Update the AR coefficients */
|
||||
for( k = 0; k < (n + 1) >> 1; k++ ) {
|
||||
tmp1 = Af[ k ];
|
||||
tmp2 = Af[ n - k - 1 ];
|
||||
Af[ k ] = tmp1 + rc * tmp2;
|
||||
Af[ n - k - 1 ] = tmp2 + rc * tmp1;
|
||||
}
|
||||
Af[ n ] = rc;
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Reached max prediction gain; set remaining coefficients to zero and exit loop */
|
||||
for( k = n + 1; k < D; k++ ) {
|
||||
Af[ k ] = 0.0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update C * Af and C * Ab */
|
||||
for( k = 0; k <= n + 1; k++ ) {
|
||||
tmp1 = CAf[ k ];
|
||||
CAf[ k ] += rc * CAb[ n - k + 1 ];
|
||||
CAb[ n - k + 1 ] += rc * tmp1;
|
||||
}
|
||||
}
|
||||
|
||||
if( reached_max_gain ) {
|
||||
/* Convert to silk_float */
|
||||
for( k = 0; k < D; k++ ) {
|
||||
A[ k ] = (silk_float)( -Af[ k ] );
|
||||
}
|
||||
/* Subtract energy of preceding samples from C0 */
|
||||
for( s = 0; s < nb_subfr; s++ ) {
|
||||
C0 -= silk_energy_FLP( x + s * subfr_length, D );
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
nrg_f = C0 * invGain;
|
||||
} else {
|
||||
/* Compute residual energy and store coefficients as silk_float */
|
||||
nrg_f = CAf[ 0 ];
|
||||
tmp1 = 1.0;
|
||||
for( k = 0; k < D; k++ ) {
|
||||
Atmp = Af[ k ];
|
||||
nrg_f += CAf[ k + 1 ] * Atmp;
|
||||
tmp1 += Atmp * Atmp;
|
||||
A[ k ] = (silk_float)(-Atmp);
|
||||
}
|
||||
nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;
|
||||
}
|
||||
|
||||
/* Return residual energy */
|
||||
return (silk_float)nrg_f;
|
||||
}
|
49
node_modules/node-opus/deps/opus/silk/float/bwexpander_FLP.c
generated
vendored
Normal file
49
node_modules/node-opus/deps/opus/silk/float/bwexpander_FLP.c
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FLP.h"
|
||||
|
||||
/* Chirp (bw expand) LP AR filter */
|
||||
void silk_bwexpander_FLP(
|
||||
silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||
const opus_int d, /* I length of ar */
|
||||
const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
silk_float cfac = chirp;
|
||||
|
||||
for( i = 0; i < d - 1; i++ ) {
|
||||
ar[ i ] *= cfac;
|
||||
cfac *= chirp;
|
||||
}
|
||||
ar[ d - 1 ] *= cfac;
|
||||
}
|
93
node_modules/node-opus/deps/opus/silk/float/corrMatrix_FLP.c
generated
vendored
Normal file
93
node_modules/node-opus/deps/opus/silk/float/corrMatrix_FLP.c
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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
|
||||
|
||||
/**********************************************************************
|
||||
* Correlation matrix computations for LS estimate.
|
||||
**********************************************************************/
|
||||
|
||||
#include "main_FLP.h"
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
void silk_corrVector_FLP(
|
||||
const silk_float *x, /* I x vector [L+order-1] used to create X */
|
||||
const silk_float *t, /* I Target vector [L] */
|
||||
const opus_int L, /* I Length of vecors */
|
||||
const opus_int Order, /* I Max lag for correlation */
|
||||
silk_float *Xt /* O X'*t correlation vector [order] */
|
||||
)
|
||||
{
|
||||
opus_int lag;
|
||||
const silk_float *ptr1;
|
||||
|
||||
ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
|
||||
for( lag = 0; lag < Order; lag++ ) {
|
||||
/* Calculate X[:,lag]'*t */
|
||||
Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L );
|
||||
ptr1--; /* Next column of X */
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates correlation matrix X'*X */
|
||||
void silk_corrMatrix_FLP(
|
||||
const silk_float *x, /* I x vector [ L+order-1 ] used to create X */
|
||||
const opus_int L, /* I Length of vectors */
|
||||
const opus_int Order, /* I Max lag for correlation */
|
||||
silk_float *XX /* O X'*X correlation matrix [order x order] */
|
||||
)
|
||||
{
|
||||
opus_int j, lag;
|
||||
double energy;
|
||||
const silk_float *ptr1, *ptr2;
|
||||
|
||||
ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */
|
||||
energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */
|
||||
matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy;
|
||||
for( j = 1; j < Order; j++ ) {
|
||||
/* Calculate X[:,j]'*X[:,j] */
|
||||
energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ];
|
||||
matrix_ptr( XX, j, j, Order ) = ( silk_float )energy;
|
||||
}
|
||||
|
||||
ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */
|
||||
for( lag = 1; lag < Order; lag++ ) {
|
||||
/* Calculate X[:,0]'*X[:,lag] */
|
||||
energy = silk_inner_product_FLP( ptr1, ptr2, L );
|
||||
matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy;
|
||||
matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy;
|
||||
/* Calculate X[:,j]'*X[:,j + lag] */
|
||||
for( j = 1; j < ( Order - lag ); j++ ) {
|
||||
energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ];
|
||||
matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy;
|
||||
matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy;
|
||||
}
|
||||
ptr2--; /* Next column of X */
|
||||
}
|
||||
}
|
372
node_modules/node-opus/deps/opus/silk/float/encode_frame_FLP.c
generated
vendored
Normal file
372
node_modules/node-opus/deps/opus/silk/float/encode_frame_FLP.c
generated
vendored
Normal file
@ -0,0 +1,372 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "main_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
|
||||
const silk_float xfw[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
);
|
||||
|
||||
void silk_encode_do_VAD_FLP(
|
||||
silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */
|
||||
)
|
||||
{
|
||||
/****************************/
|
||||
/* Voice Activity Detection */
|
||||
/****************************/
|
||||
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
|
||||
|
||||
/**************************************************/
|
||||
/* Convert speech activity into VAD and DTX flags */
|
||||
/**************************************************/
|
||||
if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
|
||||
psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
|
||||
psEnc->sCmn.noSpeechCounter++;
|
||||
if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
} else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
|
||||
psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
}
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
|
||||
} else {
|
||||
psEnc->sCmn.noSpeechCounter = 0;
|
||||
psEnc->sCmn.inDTX = 0;
|
||||
psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
|
||||
psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/****************/
|
||||
/* Encode frame */
|
||||
/****************/
|
||||
opus_int silk_encode_frame_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
opus_int32 *pnBytesOut, /* O Number of payload bytes; */
|
||||
ec_enc *psRangeEnc, /* I/O compressor data structure */
|
||||
opus_int condCoding, /* I The type of conditional coding to use */
|
||||
opus_int maxBits, /* I If > 0: maximum number of output bits */
|
||||
opus_int useCBR /* I Flag to force constant-bitrate operation */
|
||||
)
|
||||
{
|
||||
silk_encoder_control_FLP sEncCtrl;
|
||||
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
||||
silk_float *x_frame, *res_pitch_frame;
|
||||
silk_float xfw[ MAX_FRAME_LENGTH ];
|
||||
silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||
opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
|
||||
opus_int32 gainsID, gainsID_lower, gainsID_upper;
|
||||
opus_int16 gainMult_Q8;
|
||||
opus_int16 ec_prevLagIndex_copy;
|
||||
opus_int ec_prevSignalType_copy;
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
|
||||
opus_uint8 ec_buf_copy[ 1275 ];
|
||||
|
||||
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
|
||||
LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
|
||||
|
||||
psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
|
||||
|
||||
/**************************************************************/
|
||||
/* Set up Input Pointers, and insert frame in input buffer */
|
||||
/**************************************************************/
|
||||
/* pointers aligned with start of frame to encode */
|
||||
x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
|
||||
res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
|
||||
|
||||
/***************************************/
|
||||
/* Ensure smooth bandwidth transitions */
|
||||
/***************************************/
|
||||
silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
|
||||
|
||||
/*******************************************/
|
||||
/* Copy new frame to front of input buffer */
|
||||
/*******************************************/
|
||||
silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
|
||||
|
||||
/* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
|
||||
for( i = 0; i < 8; i++ ) {
|
||||
x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;
|
||||
}
|
||||
|
||||
if( !psEnc->sCmn.prefillFlag ) {
|
||||
/*****************************************/
|
||||
/* Find pitch lags, initial LPC analysis */
|
||||
/*****************************************/
|
||||
silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
|
||||
|
||||
/************************/
|
||||
/* Noise shape analysis */
|
||||
/************************/
|
||||
silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
|
||||
|
||||
/***************************************************/
|
||||
/* Find linear prediction coefficients (LPC + LTP) */
|
||||
/***************************************************/
|
||||
silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Process gains */
|
||||
/****************************************/
|
||||
silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
|
||||
|
||||
/*****************************************/
|
||||
/* Prefiltering for noise shaper */
|
||||
/*****************************************/
|
||||
silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );
|
||||
|
||||
/****************************************/
|
||||
/* Low Bitrate Redundant Encoding */
|
||||
/****************************************/
|
||||
silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
|
||||
|
||||
/* Loop over quantizer and entroy coding to control bitrate */
|
||||
maxIter = 6;
|
||||
gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
|
||||
found_lower = 0;
|
||||
found_upper = 0;
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
gainsID_lower = -1;
|
||||
gainsID_upper = -1;
|
||||
/* Copy part of the input state */
|
||||
silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
seed_copy = psEnc->sCmn.indices.Seed;
|
||||
ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
|
||||
ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
|
||||
for( iter = 0; ; iter++ ) {
|
||||
if( gainsID == gainsID_lower ) {
|
||||
nBits = nBits_lower;
|
||||
} else if( gainsID == gainsID_upper ) {
|
||||
nBits = nBits_upper;
|
||||
} else {
|
||||
/* Restore part of the input state */
|
||||
if( iter > 0 ) {
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
|
||||
psEnc->sCmn.indices.Seed = seed_copy;
|
||||
psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
|
||||
psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );
|
||||
|
||||
/****************************************/
|
||||
/* Encode Parameters */
|
||||
/****************************************/
|
||||
silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Encode Excitation Signal */
|
||||
/****************************************/
|
||||
silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
|
||||
psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
|
||||
|
||||
nBits = ec_tell( psRangeEnc );
|
||||
|
||||
if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( iter == maxIter ) {
|
||||
if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
|
||||
/* Restore output state from earlier iteration that did meet the bitrate budget */
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
|
||||
silk_assert( sRangeEnc_copy2.offs <= 1275 );
|
||||
silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
|
||||
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
|
||||
psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( nBits > maxBits ) {
|
||||
if( found_lower == 0 && iter >= 2 ) {
|
||||
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
|
||||
sEncCtrl.Lambda *= 1.5f;
|
||||
found_upper = 0;
|
||||
gainsID_upper = -1;
|
||||
} else {
|
||||
found_upper = 1;
|
||||
nBits_upper = nBits;
|
||||
gainMult_upper = gainMult_Q8;
|
||||
gainsID_upper = gainsID;
|
||||
}
|
||||
} else if( nBits < maxBits - 5 ) {
|
||||
found_lower = 1;
|
||||
nBits_lower = nBits;
|
||||
gainMult_lower = gainMult_Q8;
|
||||
if( gainsID != gainsID_lower ) {
|
||||
gainsID_lower = gainsID;
|
||||
/* Copy part of the output state */
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
silk_assert( psRangeEnc->offs <= 1275 );
|
||||
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
|
||||
silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
|
||||
}
|
||||
} else {
|
||||
/* Within 5 bits of budget: close enough */
|
||||
break;
|
||||
}
|
||||
|
||||
if( ( found_lower & found_upper ) == 0 ) {
|
||||
/* Adjust gain according to high-rate rate/distortion curve */
|
||||
opus_int32 gain_factor_Q16;
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
|
||||
if( nBits > maxBits ) {
|
||||
gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
|
||||
}
|
||||
gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
|
||||
} else {
|
||||
/* Adjust gain by interpolating */
|
||||
gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
|
||||
/* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
|
||||
if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
|
||||
} else
|
||||
if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
|
||||
gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
|
||||
}
|
||||
|
||||
/* Quantize gains */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
|
||||
&psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Unique identifier of gains vector */
|
||||
gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update input buffer */
|
||||
silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
|
||||
( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );
|
||||
|
||||
/* Exit without entropy coding */
|
||||
if( psEnc->sCmn.prefillFlag ) {
|
||||
/* No payload */
|
||||
*pnBytesOut = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parameters needed for next frame */
|
||||
psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||
psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
|
||||
|
||||
/****************************************/
|
||||
/* Finalize payload */
|
||||
/****************************************/
|
||||
psEnc->sCmn.first_frame_after_reset = 0;
|
||||
/* Payload size */
|
||||
*pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
|
||||
static OPUS_INLINE void silk_LBRR_encode_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
|
||||
const silk_float xfw[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
)
|
||||
{
|
||||
opus_int k;
|
||||
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
||||
silk_float TempGains[ MAX_NB_SUBFR ];
|
||||
SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
|
||||
silk_nsq_state sNSQ_LBRR;
|
||||
|
||||
/*******************************************/
|
||||
/* Control use of inband LBRR */
|
||||
/*******************************************/
|
||||
if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
|
||||
psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
|
||||
|
||||
/* Copy noise shaping quantizer state and quantization indices from regular encoding */
|
||||
silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
|
||||
silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
|
||||
|
||||
/* Save original gains */
|
||||
silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
|
||||
|
||||
if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
|
||||
/* First frame in packet or previous frame not LBRR coded */
|
||||
psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
|
||||
|
||||
/* Increase Gains to get target LBRR rate */
|
||||
psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;
|
||||
psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
|
||||
}
|
||||
|
||||
/* Decode to get gains in sync with decoder */
|
||||
silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices,
|
||||
&psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );
|
||||
}
|
||||
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR,
|
||||
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );
|
||||
|
||||
/* Restore original gains */
|
||||
silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
|
||||
}
|
||||
}
|
60
node_modules/node-opus/deps/opus/silk/float/energy_FLP.c
generated
vendored
Normal file
60
node_modules/node-opus/deps/opus/silk/float/energy_FLP.c
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "SigProc_FLP.h"
|
||||
|
||||
/* sum of squares of a silk_float array, with result as double */
|
||||
double silk_energy_FLP(
|
||||
const silk_float *data,
|
||||
opus_int dataSize
|
||||
)
|
||||
{
|
||||
opus_int i, dataSize4;
|
||||
double result;
|
||||
|
||||
/* 4x unrolled loop */
|
||||
result = 0.0;
|
||||
dataSize4 = dataSize & 0xFFFC;
|
||||
for( i = 0; i < dataSize4; i += 4 ) {
|
||||
result += data[ i + 0 ] * (double)data[ i + 0 ] +
|
||||
data[ i + 1 ] * (double)data[ i + 1 ] +
|
||||
data[ i + 2 ] * (double)data[ i + 2 ] +
|
||||
data[ i + 3 ] * (double)data[ i + 3 ];
|
||||
}
|
||||
|
||||
/* add any remaining products */
|
||||
for( ; i < dataSize; i++ ) {
|
||||
result += data[ i ] * (double)data[ i ];
|
||||
}
|
||||
|
||||
silk_assert( result >= 0.0 );
|
||||
return result;
|
||||
}
|
104
node_modules/node-opus/deps/opus/silk/float/find_LPC_FLP.c
generated
vendored
Normal file
104
node_modules/node-opus/deps/opus/silk/float/find_LPC_FLP.c
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
||||
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 Internet Society, IETF or IETF Trust, nor the
|
||||
names of specific 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 COPYRIGHT OWNER 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 "define.h"
|
||||
#include "main_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/* LPC analysis */
|
||||
void silk_find_LPC_FLP(
|
||||
silk_encoder_state *psEncC, /* I/O Encoder state */
|
||||
opus_int16 NLSF_Q15[], /* O NLSFs */
|
||||
const silk_float x[], /* I Input signal */
|
||||
const silk_float minInvGain /* I Inverse of max prediction gain */
|
||||
)
|
||||
{
|
||||
opus_int k, subfr_length;
|
||||
silk_float a[ MAX_LPC_ORDER ];
|
||||
|
||||
/* Used only for NLSF interpolation */
|
||||
silk_float res_nrg, res_nrg_2nd, res_nrg_interp;
|
||||
opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
|
||||
silk_float a_tmp[ MAX_LPC_ORDER ];
|
||||
silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
|
||||
|
||||
subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
|
||||
|
||||
/* Default: No interpolation */
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = 4;
|
||||
|
||||
/* Burg AR analysis for the full frame */
|
||||
res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
|
||||
|
||||
if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
|
||||
/* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
|
||||
/* adding it to the residual energy of the first 10 ms in each iteration of the search below */
|
||||
res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );
|
||||
|
||||
/* Convert to NLSFs */
|
||||
silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );
|
||||
|
||||
/* Search over interpolation indices to find the one with lowest residual energy */
|
||||
res_nrg_2nd = silk_float_MAX;
|
||||
for( k = 3; k >= 0; k-- ) {
|
||||
/* Interpolate NLSFs for first half */
|
||||
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||
|
||||
/* Convert to LPC for residual energy evaluation */
|
||||
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );
|
||||
|
||||
/* Calculate residual energy with LSF interpolation */
|
||||
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
|
||||
res_nrg_interp = (silk_float)(
|
||||
silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) +
|
||||
silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );
|
||||
|
||||
/* Determine whether current interpolated NLSFs are best so far */
|
||||
if( res_nrg_interp < res_nrg ) {
|
||||
/* Interpolation has lower residual energy */
|
||||
res_nrg = res_nrg_interp;
|
||||
psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
|
||||
} else if( res_nrg_interp > res_nrg_2nd ) {
|
||||
/* No reason to continue iterating - residual energies will continue to climb */
|
||||
break;
|
||||
}
|
||||
res_nrg_2nd = res_nrg_interp;
|
||||
}
|
||||
}
|
||||
|
||||
if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
|
||||
/* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
|
||||
silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
|
||||
}
|
||||
|
||||
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
|
||||
( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user