mirror of
https://github.com/xiph/opus.git
synced 2025-06-06 15:30:48 +00:00
Addressing multiple LSF-related issues
- Merged the LPC stabilization from NLSF2A_stable.c into NLSF2A.c - The bandwidth expansion in NLSF2A() now operates on int32 LPC coefficients in Q17 domain (instead of int16 Q12 coefficients) - The function bwexpander_32() has a more precise way of updating the chirp variable (round to nearest, instead of round down) - Changed a few variables in NLSF_stabilize() from int16 to int32 to avoid signed wrap-around (no difference in results as the wrap-around would always be reversed later) - The LSF codebook for WB speech has a quantization stepsize of 0.15 (was 0.16). This doesn't break the bitstream, although it slightly limits quality of signals encoded with the old version and decoded with the new one (I can't really hear it and PESQ gives high scores as well). I does improve handling of tonal signals. - As discussed: the Q-domain of the poly function is now in Q16 (was Q20) - As discussed: limiting the LSFs in NLSF_decode() to 0...32767 - The silk_NLSF_DELTA_MIN values were lowered to deal with a possible future situation with less or no input HP filtering.
This commit is contained in:
parent
8019e4e32e
commit
f6e781ab8b
39 changed files with 204 additions and 666 deletions
|
@ -97,7 +97,7 @@ void silk_find_LPC_FIX(
|
||||||
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
||||||
|
|
||||||
/* Convert to LPC for residual energy evaluation */
|
/* Convert to LPC for residual energy evaluation */
|
||||||
silk_NLSF2A_stable( a_tmp_Q12, NLSF0_Q15, LPC_order );
|
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, LPC_order );
|
||||||
|
|
||||||
/* Calculate residual energy with NLSF interpolation */
|
/* Calculate residual energy with NLSF interpolation */
|
||||||
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order );
|
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, LPC_order );
|
||||||
|
|
|
@ -79,7 +79,7 @@ void silk_find_LPC_FLP(
|
||||||
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
silk_interpolate( NLSF0_Q15, prev_NLSFq_Q15, NLSF_Q15, k, LPC_order );
|
||||||
|
|
||||||
/* Convert to LPC for residual energy evaluation */
|
/* Convert to LPC for residual energy evaluation */
|
||||||
silk_NLSF2A_stable_FLP( a_tmp, NLSF0_Q15, LPC_order );
|
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, LPC_order );
|
||||||
|
|
||||||
/* Calculate residual energy with LSF interpolation */
|
/* Calculate residual energy with LSF interpolation */
|
||||||
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order );
|
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, LPC_order );
|
||||||
|
|
|
@ -291,7 +291,7 @@ void silk_apply_sine_window_FLP(
|
||||||
const SKP_int length /* I Window length, multiple of 4 */
|
const SKP_int length /* I Window length, multiple of 4 */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Wrappers. Calls flp / fix code */
|
/* Wrapper functions. Call flp / fix code */
|
||||||
|
|
||||||
/* Convert AR filter coefficients to NLSF parameters */
|
/* Convert AR filter coefficients to NLSF parameters */
|
||||||
void silk_A2NLSF_FLP(
|
void silk_A2NLSF_FLP(
|
||||||
|
@ -301,7 +301,7 @@ void silk_A2NLSF_FLP(
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Convert NLSF parameters to AR prediction filter coefficients */
|
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||||
void silk_NLSF2A_stable_FLP(
|
void silk_NLSF2A_FLP(
|
||||||
SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
||||||
const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
||||||
const SKP_int LPC_order /* I LPC order */
|
const SKP_int LPC_order /* I LPC order */
|
||||||
|
|
|
@ -47,7 +47,7 @@ void silk_A2NLSF_FLP(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert LSF parameters to AR prediction filter coefficients */
|
/* Convert LSF parameters to AR prediction filter coefficients */
|
||||||
void silk_NLSF2A_stable_FLP(
|
void silk_NLSF2A_FLP(
|
||||||
SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
||||||
const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
const SKP_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
||||||
const SKP_int LPC_order /* I LPC order */
|
const SKP_int LPC_order /* I LPC order */
|
||||||
|
@ -56,7 +56,7 @@ void silk_NLSF2A_stable_FLP(
|
||||||
SKP_int i;
|
SKP_int i;
|
||||||
SKP_int16 a_fix_Q12[ MAX_LPC_ORDER ];
|
SKP_int16 a_fix_Q12[ MAX_LPC_ORDER ];
|
||||||
|
|
||||||
silk_NLSF2A_stable( a_fix_Q12, NLSF_Q15, LPC_order );
|
silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );
|
||||||
|
|
||||||
for( i = 0; i < LPC_order; i++ ) {
|
for( i = 0; i < LPC_order; i++ ) {
|
||||||
pAR[ i ] = ( SKP_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
|
pAR[ i ] = ( SKP_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
|
||||||
|
|
|
@ -29,7 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/* Generates excitation for CNG LPC synthesis */
|
/* Generates excitation for CNG LPC synthesis */
|
||||||
SKP_INLINE void silk_CNG_exc(
|
SKP_INLINE void silk_CNG_exc(
|
||||||
SKP_int16 residual[], /* O CNG residual signal Q0 */
|
SKP_int32 residual_Q10[], /* O CNG residual signal Q10 */
|
||||||
SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */
|
SKP_int32 exc_buf_Q10[], /* I Random samples buffer Q10 */
|
||||||
SKP_int32 Gain_Q16, /* I Gain to apply */
|
SKP_int32 Gain_Q16, /* I Gain to apply */
|
||||||
SKP_int length, /* I Length */
|
SKP_int length, /* I Length */
|
||||||
|
@ -50,7 +50,7 @@ SKP_INLINE void silk_CNG_exc(
|
||||||
idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
|
idx = ( SKP_int )( SKP_RSHIFT( seed, 24 ) & exc_mask );
|
||||||
SKP_assert( idx >= 0 );
|
SKP_assert( idx >= 0 );
|
||||||
SKP_assert( idx <= CNG_BUF_MASK_MAX );
|
SKP_assert( idx <= CNG_BUF_MASK_MAX );
|
||||||
residual[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ), 10 ) );
|
residual_Q10[ i ] = ( SKP_int16 )SKP_SAT16( SKP_SMULWW( exc_buf_Q10[ idx ], Gain_Q16 ) );
|
||||||
}
|
}
|
||||||
*rand_seed = seed;
|
*rand_seed = seed;
|
||||||
}
|
}
|
||||||
|
@ -79,12 +79,11 @@ void silk_CNG(
|
||||||
SKP_int length /* I Length of residual */
|
SKP_int length /* I Length of residual */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int i, subfr;
|
SKP_int i, j, subfr;
|
||||||
SKP_int32 tmp_32, Gain_Q26, max_Gain_Q16;
|
SKP_int32 sum_Q6, max_Gain_Q16;
|
||||||
SKP_int16 LPC_buf[ MAX_LPC_ORDER ];
|
SKP_int16 A_Q12[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 CNG_sig[ MAX_FRAME_LENGTH ];
|
SKP_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||||
silk_CNG_struct *psCNG;
|
silk_CNG_struct *psCNG = &psDec->sCNG;
|
||||||
psCNG = &psDec->sCNG;
|
|
||||||
|
|
||||||
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
||||||
/* Reset state */
|
/* Reset state */
|
||||||
|
@ -118,31 +117,39 @@ void silk_CNG(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add CNG when packet is lost and / or when low speech activity */
|
/* Add CNG when packet is lost or during DTX */
|
||||||
if( psDec->lossCnt ) {
|
if( psDec->lossCnt ) {
|
||||||
|
|
||||||
/* Generate CNG excitation */
|
/* Generate CNG excitation */
|
||||||
silk_CNG_exc( CNG_sig, psCNG->CNG_exc_buf_Q10,
|
silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q10, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
|
||||||
psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
|
|
||||||
|
|
||||||
/* Convert CNG NLSF to filter representation */
|
/* Convert CNG NLSF to filter representation */
|
||||||
silk_NLSF2A_stable( LPC_buf, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
|
silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
|
||||||
|
|
||||||
Gain_Q26 = ( SKP_int32 )1 << 26; /* 1.0 */
|
|
||||||
|
|
||||||
/* Generate CNG signal, by synthesis filtering */
|
/* Generate CNG signal, by synthesis filtering */
|
||||||
if( psDec->LPC_order == 16 ) {
|
SKP_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( SKP_int32 ) );
|
||||||
silk_LPC_synthesis_order16( CNG_sig, LPC_buf,
|
|
||||||
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length );
|
|
||||||
} else {
|
|
||||||
silk_LPC_synthesis_filter( CNG_sig, LPC_buf,
|
|
||||||
Gain_Q26, psCNG->CNG_synth_state, CNG_sig, length, psDec->LPC_order );
|
|
||||||
}
|
|
||||||
/* Mix with signal */
|
|
||||||
for( i = 0; i < length; i++ ) {
|
for( i = 0; i < length; i++ ) {
|
||||||
tmp_32 = signal[ i ] + CNG_sig[ i ];
|
/* Partially unrolled */
|
||||||
signal[ i ] = SKP_SAT16( tmp_32 );
|
sum_Q6 = SKP_SMULWB( CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
|
||||||
|
for( j = 10; j < psDec->LPC_order; j++ ) {
|
||||||
|
sum_Q6 = SKP_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update states */
|
||||||
|
CNG_sig_Q10[ MAX_LPC_ORDER + i ] = SKP_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 );
|
||||||
|
|
||||||
|
signal[ i ] = SKP_ADD_SAT16( signal[ i ], SKP_RSHIFT_ROUND( sum_Q6, 6 ) );
|
||||||
|
}
|
||||||
|
SKP_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
|
||||||
} else {
|
} else {
|
||||||
SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) );
|
SKP_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( SKP_int32 ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,27 +123,6 @@ SKP_int silk_LPC_inverse_pred_gain( /* O: Returns 1 if unstable, otherwi
|
||||||
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For input in Q13 domain */
|
|
||||||
SKP_int silk_LPC_inverse_pred_gain_Q13( /* O: Returns 1 if unstable, otherwise 0 */
|
|
||||||
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
|
||||||
const SKP_int16 *A_Q13, /* I: Prediction coefficients, Q13 [order] */
|
|
||||||
const SKP_int order /* I: Prediction order */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int k;
|
|
||||||
SKP_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
|
|
||||||
SKP_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 ] = SKP_LSHIFT( (SKP_int32)A_Q13[ k ], QA - 13 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For input in Q24 domain */
|
/* For input in Q24 domain */
|
||||||
SKP_int silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
|
SKP_int silk_LPC_inverse_pred_gain_Q24( /* O: Returns 1 if unstable, otherwise 0 */
|
||||||
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
SKP_int32 *invGain_Q30, /* O: Inverse prediction gain, Q30 energy domain */
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, (subject to the limitations in the disclaimer below)
|
|
||||||
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 Skype Limited, nor the names of specific
|
|
||||||
contributors, may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
|
||||||
BY THIS LICENSE. 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.
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include "silk_typedef.h"
|
|
||||||
#include "silk_SigProc_FIX.h"
|
|
||||||
|
|
||||||
#define LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16 ( ( (SKP_int32)SKP_int16_MAX ) << 4 )
|
|
||||||
|
|
||||||
/* LPC stabilizer, for a single input data vector */
|
|
||||||
void silk_LPC_stabilize(
|
|
||||||
SKP_int16 *a_Q12, /* O stabilized LPC vector [L] */
|
|
||||||
SKP_int32 *a_Q16, /* I LPC vector [L] */
|
|
||||||
const SKP_int32 bwe_Q16, /* I Bandwidth expansion factor */
|
|
||||||
const SKP_int L /* I Number of LPC parameters in the input vector */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int32 maxabs, absval, sc_Q16;
|
|
||||||
SKP_int i, idx = 0;
|
|
||||||
SKP_int32 invGain_Q30;
|
|
||||||
|
|
||||||
silk_bwexpander_32( a_Q16, L, bwe_Q16 );
|
|
||||||
|
|
||||||
/***************************/
|
|
||||||
/* Limit range of the LPCs */
|
|
||||||
/***************************/
|
|
||||||
/* Limit the maximum absolute value of the prediction coefficients */
|
|
||||||
while( SKP_TRUE ) {
|
|
||||||
/* Find maximum absolute value and its index */
|
|
||||||
maxabs = SKP_int32_MIN;
|
|
||||||
for( i = 0; i < L; i++ ) {
|
|
||||||
absval = SKP_abs( a_Q16[ i ] );
|
|
||||||
if( absval > maxabs ) {
|
|
||||||
maxabs = absval;
|
|
||||||
idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( maxabs >= LPC_STABILIZE_LPC_MAX_ABS_VALUE_Q16 ) {
|
|
||||||
/* Reduce magnitude of prediction coefficients */
|
|
||||||
sc_Q16 = SKP_DIV32( SKP_int32_MAX, SKP_RSHIFT( maxabs, 4 ) );
|
|
||||||
sc_Q16 = 65536 - sc_Q16;
|
|
||||||
sc_Q16 = SKP_DIV32( sc_Q16, idx + 1 );
|
|
||||||
sc_Q16 = 65536 - sc_Q16;
|
|
||||||
sc_Q16 = SKP_LSHIFT( SKP_SMULWB( sc_Q16, 32604 ), 1 ); // 0.995 in Q16
|
|
||||||
silk_bwexpander_32( a_Q16, L, sc_Q16 );
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to 16 bit Q12 */
|
|
||||||
for( i = 0; i < L; i++ ) {
|
|
||||||
a_Q12[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( a_Q16[ i ], 4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************/
|
|
||||||
/* Ensure stable LPCs */
|
|
||||||
/**********************/
|
|
||||||
while( silk_LPC_inverse_pred_gain( &invGain_Q30, a_Q12, L ) == 1 ) {
|
|
||||||
silk_bwexpander( a_Q12, L, 65339 ); // 0.997 in Q16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void silk_LPC_fit(
|
|
||||||
SKP_int16 *a_QQ, /* O Stabilized LPC vector, Q(24-rshift) [L] */
|
|
||||||
SKP_int32 *a_Q24, /* I LPC vector [L] */
|
|
||||||
const SKP_int QQ, /* I Q domain of output LPC vector */
|
|
||||||
const SKP_int L /* I Number of LPC parameters in the input vector */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int i, rshift, idx = 0;
|
|
||||||
SKP_int32 maxabs, absval, sc_Q16;
|
|
||||||
|
|
||||||
rshift = 24 - QQ;
|
|
||||||
|
|
||||||
/***************************/
|
|
||||||
/* Limit range of the LPCs */
|
|
||||||
/***************************/
|
|
||||||
/* Limit the maximum absolute value of the prediction coefficients */
|
|
||||||
while( SKP_TRUE ) {
|
|
||||||
/* Find maximum absolute value and its index; assumes stable coefficients */
|
|
||||||
/* so that only the first half need to be tested */
|
|
||||||
maxabs = SKP_int32_MIN;
|
|
||||||
for( i = 1; i < L / 2; i++ ) {
|
|
||||||
absval = SKP_abs( a_Q24[ i ] );
|
|
||||||
if( absval > maxabs ) {
|
|
||||||
maxabs = absval;
|
|
||||||
idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maxabs = SKP_RSHIFT( maxabs, rshift );
|
|
||||||
if( maxabs >= SKP_int16_MAX ) {
|
|
||||||
/* Reduce magnitude of prediction coefficients */
|
|
||||||
maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369
|
|
||||||
sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ),
|
|
||||||
SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
|
|
||||||
silk_bwexpander_32( a_Q24, L, sc_Q16 );
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert to 16 bit Q(24-rshift) */
|
|
||||||
SKP_assert( rshift > 0 );
|
|
||||||
SKP_assert( rshift < 31 );
|
|
||||||
for( i = 0; i < L; i++ ) {
|
|
||||||
a_QQ[ i ] = (SKP_int16)SKP_RSHIFT_ROUND( a_Q24[ i ], rshift );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, (subject to the limitations in the disclaimer below)
|
|
||||||
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 Skype Limited, nor the names of specific
|
|
||||||
contributors, may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
|
||||||
BY THIS LICENSE. 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_LPC_synthesis_filter.c *
|
|
||||||
* Coefficients are in Q12 *
|
|
||||||
* *
|
|
||||||
* even order AR filter *
|
|
||||||
* */
|
|
||||||
#include "silk_SigProc_FIX.h"
|
|
||||||
|
|
||||||
/* even order AR filter */
|
|
||||||
void silk_LPC_synthesis_filter(
|
|
||||||
const SKP_int16 *in, /* I: excitation signal */
|
|
||||||
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
|
|
||||||
const SKP_int32 Gain_Q26, /* I: gain */
|
|
||||||
SKP_int32 *S, /* I/O: state vector [Order] */
|
|
||||||
SKP_int16 *out, /* O: output signal */
|
|
||||||
const SKP_int32 len, /* I: signal length */
|
|
||||||
const SKP_int Order /* I: filter order, must be even */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
|
|
||||||
SKP_int32 SA, SB, out32_Q10, out32;
|
|
||||||
|
|
||||||
/* Order must be even */
|
|
||||||
SKP_assert( 2 * Order_half == Order );
|
|
||||||
|
|
||||||
/* S[] values are in Q14 */
|
|
||||||
for( k = 0; k < len; k++ ) {
|
|
||||||
SA = S[ Order - 1 ];
|
|
||||||
out32_Q10 = 0;
|
|
||||||
for( j = 0; j < ( Order_half - 1 ); j++ ) {
|
|
||||||
idx = SKP_SMULBB( 2, j ) + 1;
|
|
||||||
SB = S[ Order - 1 - idx ];
|
|
||||||
S[ Order - 1 - idx ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
|
|
||||||
SA = S[ Order - 2 - idx ];
|
|
||||||
S[ Order - 2 - idx ] = SB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unrolled loop: epilog */
|
|
||||||
SB = S[ 0 ];
|
|
||||||
S[ 0 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
|
|
||||||
/* apply gain to excitation signal and add to prediction */
|
|
||||||
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
|
|
||||||
|
|
||||||
/* scale to Q0 */
|
|
||||||
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
|
|
||||||
|
|
||||||
/* saturate output */
|
|
||||||
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
|
||||||
|
|
||||||
/* move result into delay line */
|
|
||||||
S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, (subject to the limitations in the disclaimer below)
|
|
||||||
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 Skype Limited, nor the names of specific
|
|
||||||
contributors, may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
|
||||||
BY THIS LICENSE. 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_LPC_synthesis_order16.c *
|
|
||||||
* Coefficients are in Q12 *
|
|
||||||
* *
|
|
||||||
* 16th order AR filter *
|
|
||||||
* */
|
|
||||||
#include "silk_SigProc_FIX.h"
|
|
||||||
|
|
||||||
/* 16th order AR filter */
|
|
||||||
void silk_LPC_synthesis_order16(const SKP_int16 *in, /* I: excitation signal */
|
|
||||||
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
|
|
||||||
const SKP_int32 Gain_Q26, /* I: gain */
|
|
||||||
SKP_int32 *S, /* I/O: state vector [16] */
|
|
||||||
SKP_int16 *out, /* O: output signal */
|
|
||||||
const SKP_int32 len /* I: signal length, must be multiple of 16 */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int k;
|
|
||||||
SKP_int32 SA, SB, out32_Q10, out32;
|
|
||||||
for( k = 0; k < len; k++ ) {
|
|
||||||
/* unrolled loop: prolog */
|
|
||||||
/* multiply-add two prediction coefficients per iteration */
|
|
||||||
SA = S[ 15 ];
|
|
||||||
SB = S[ 14 ];
|
|
||||||
S[ 14 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMULWB( SA, A_Q12[ 0 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 1 ] );
|
|
||||||
SA = S[ 13 ];
|
|
||||||
S[ 13 ] = SB;
|
|
||||||
|
|
||||||
/* unrolled loop: main loop */
|
|
||||||
SB = S[ 12 ];
|
|
||||||
S[ 12 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 2 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 3 ] );
|
|
||||||
SA = S[ 11 ];
|
|
||||||
S[ 11 ] = SB;
|
|
||||||
|
|
||||||
SB = S[ 10 ];
|
|
||||||
S[ 10 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 4 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 5 ] );
|
|
||||||
SA = S[ 9 ];
|
|
||||||
S[ 9 ] = SB;
|
|
||||||
|
|
||||||
SB = S[ 8 ];
|
|
||||||
S[ 8 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 6 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 7 ] );
|
|
||||||
SA = S[ 7 ];
|
|
||||||
S[ 7 ] = SB;
|
|
||||||
|
|
||||||
SB = S[ 6 ];
|
|
||||||
S[ 6 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 8 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 9 ] );
|
|
||||||
SA = S[ 5 ];
|
|
||||||
S[ 5 ] = SB;
|
|
||||||
|
|
||||||
SB = S[ 4 ];
|
|
||||||
S[ 4 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 10 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 11 ] );
|
|
||||||
SA = S[ 3 ];
|
|
||||||
S[ 3 ] = SB;
|
|
||||||
|
|
||||||
SB = S[ 2 ];
|
|
||||||
S[ 2 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 12 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 13 ] );
|
|
||||||
SA = S[ 1 ];
|
|
||||||
S[ 1 ] = SB;
|
|
||||||
|
|
||||||
/* unrolled loop: epilog */
|
|
||||||
SB = S[ 0 ];
|
|
||||||
S[ 0 ] = SA;
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SA, A_Q12[ 14 ] );
|
|
||||||
out32_Q10 = SKP_SMLAWB_ovflw( out32_Q10, SB, A_Q12[ 15 ] );
|
|
||||||
|
|
||||||
/* unrolled loop: end */
|
|
||||||
/* apply gain to excitation signal and add to prediction */
|
|
||||||
out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );
|
|
||||||
|
|
||||||
/* scale to Q0 */
|
|
||||||
out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );
|
|
||||||
|
|
||||||
/* saturate output */
|
|
||||||
out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );
|
|
||||||
|
|
||||||
/* move result into delay line */
|
|
||||||
S[ 15 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -34,23 +34,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "silk_SigProc_FIX.h"
|
#include "silk_SigProc_FIX.h"
|
||||||
#include "silk_tables.h"
|
#include "silk_tables.h"
|
||||||
|
|
||||||
|
#define QA 16
|
||||||
|
|
||||||
/* helper function for NLSF2A(..) */
|
/* helper function for NLSF2A(..) */
|
||||||
SKP_INLINE void silk_NLSF2A_find_poly(
|
SKP_INLINE void silk_NLSF2A_find_poly(
|
||||||
SKP_int32 *out, /* o intermediate polynomial, Q20 */
|
SKP_int32 *out, /* O intermediate polynomial, QA [dd+1] */
|
||||||
const SKP_int32 *cLSF, /* i vector of interleaved 2*cos(LSFs), Q20 */
|
const SKP_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */
|
||||||
SKP_int dd /* i polynomial order (= 1/2 * filter order) */
|
SKP_int dd /* I polynomial order (= 1/2 * filter order) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int k, n;
|
SKP_int k, n;
|
||||||
SKP_int32 ftmp;
|
SKP_int32 ftmp;
|
||||||
|
|
||||||
out[0] = SKP_LSHIFT( 1, 20 );
|
out[0] = SKP_LSHIFT( 1, QA );
|
||||||
out[1] = -cLSF[0];
|
out[1] = -cLSF[0];
|
||||||
for( k = 1; k < dd; k++ ) {
|
for( k = 1; k < dd; k++ ) {
|
||||||
ftmp = cLSF[2*k]; // Q20
|
ftmp = cLSF[2*k]; // QA
|
||||||
out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );
|
out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), QA );
|
||||||
for( n = k; n > 1; n-- ) {
|
for( n = k; n > 1; n-- ) {
|
||||||
out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );
|
out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), QA );
|
||||||
}
|
}
|
||||||
out[1] -= ftmp;
|
out[1] -= ftmp;
|
||||||
}
|
}
|
||||||
|
@ -58,24 +60,21 @@ SKP_INLINE void silk_NLSF2A_find_poly(
|
||||||
|
|
||||||
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||||
void silk_NLSF2A(
|
void silk_NLSF2A(
|
||||||
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
|
SKP_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
|
||||||
const SKP_int16 *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
|
const SKP_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
|
||||||
const SKP_int d /* i filter order (should be even) */
|
const SKP_int d /* I filter order (should be even) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int k, i, dd;
|
SKP_int k, i, dd;
|
||||||
SKP_int32 cos_LSF_Q20[SILK_MAX_ORDER_LPC];
|
SKP_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ];
|
||||||
SKP_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
SKP_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
|
||||||
SKP_int32 Ptmp, Qtmp;
|
SKP_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
|
||||||
SKP_int32 f_int;
|
SKP_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
|
||||||
SKP_int32 f_frac;
|
SKP_int32 maxabs, absval, idx=0, sc_Q16, invGain_Q30;
|
||||||
SKP_int32 cos_val, delta;
|
|
||||||
SKP_int32 a_int32[SILK_MAX_ORDER_LPC];
|
|
||||||
SKP_int32 maxabs, absval, idx=0, sc_Q16;
|
|
||||||
|
|
||||||
SKP_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
SKP_assert( LSF_COS_TAB_SZ_FIX == 128 );
|
||||||
|
|
||||||
/* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */
|
/* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
|
||||||
for( k = 0; k < d; k++ ) {
|
for( k = 0; k < d; k++ ) {
|
||||||
SKP_assert(NLSF[k] >= 0 );
|
SKP_assert(NLSF[k] >= 0 );
|
||||||
SKP_assert(NLSF[k] <= 32767 );
|
SKP_assert(NLSF[k] <= 32767 );
|
||||||
|
@ -94,14 +93,14 @@ void silk_NLSF2A(
|
||||||
delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
|
delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */
|
||||||
|
|
||||||
/* Linear interpolation */
|
/* Linear interpolation */
|
||||||
cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */
|
cos_LSF_QA[k] = SKP_RSHIFT_ROUND( SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ), 20 - QA ); /* QA */
|
||||||
}
|
}
|
||||||
|
|
||||||
dd = SKP_RSHIFT( d, 1 );
|
dd = SKP_RSHIFT( d, 1 );
|
||||||
|
|
||||||
/* generate even and odd polynomials using convolution */
|
/* generate even and odd polynomials using convolution */
|
||||||
silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );
|
silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd );
|
||||||
silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );
|
silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd );
|
||||||
|
|
||||||
/* convert even and odd polynomials to SKP_int32 Q12 filter coefs */
|
/* convert even and odd polynomials to SKP_int32 Q12 filter coefs */
|
||||||
for( k = 0; k < dd; k++ ) {
|
for( k = 0; k < dd; k++ ) {
|
||||||
|
@ -109,44 +108,64 @@ void silk_NLSF2A(
|
||||||
Qtmp = Q[ k+1 ] - Q[ k ];
|
Qtmp = Q[ k+1 ] - Q[ k ];
|
||||||
|
|
||||||
/* the Ptmp and Qtmp values at this stage need to fit in int32 */
|
/* the Ptmp and Qtmp values at this stage need to fit in int32 */
|
||||||
|
a32_QA1[ k ] = -Qtmp - Ptmp; /* QA+1 */
|
||||||
a_int32[k] = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */
|
a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */
|
||||||
a_int32[d-k-1] = SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Limit the maximum absolute value of the prediction coefficients */
|
/* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
|
||||||
for( i = 0; i < 10; i++ ) {
|
for( i = 0; i < 10; i++ ) {
|
||||||
/* Find maximum absolute value and its index */
|
/* Find maximum absolute value and its index */
|
||||||
maxabs = 0;
|
maxabs = 0;
|
||||||
for( k = 0; k < d; k++ ) {
|
for( k = 0; k < d; k++ ) {
|
||||||
absval = SKP_abs( a_int32[k] );
|
absval = SKP_abs( a32_QA1[k] );
|
||||||
if( absval > maxabs ) {
|
if( absval > maxabs ) {
|
||||||
maxabs = absval;
|
maxabs = absval;
|
||||||
idx = k;
|
idx = k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
maxabs = SKP_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||||
|
|
||||||
if( maxabs > SKP_int16_MAX ) {
|
if( maxabs > SKP_int16_MAX ) {
|
||||||
/* Reduce magnitude of prediction coefficients */
|
/* Reduce magnitude of prediction coefficients */
|
||||||
maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369
|
maxabs = SKP_min( maxabs, 163838 ); /* ( SKP_int32_MAX >> 14 ) + SKP_int16_MAX = 163838 */
|
||||||
sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ),
|
sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - SKP_DIV32( SKP_LSHIFT( maxabs - SKP_int16_MAX, 14 ),
|
||||||
SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
|
SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );
|
||||||
silk_bwexpander_32( a_int32, d, sc_Q16 );
|
silk_bwexpander_32( a32_QA1, d, sc_Q16 );
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reached the last iteration */
|
|
||||||
if( i == 10 ) {
|
if( i == 10 ) {
|
||||||
SKP_assert(0);
|
/* Reached the last iteration, clip the coefficients */
|
||||||
for( k = 0; k < d; k++ ) {
|
for( k = 0; k < d; k++ ) {
|
||||||
a_int32[k] = SKP_SAT16( a_int32[k] );
|
a_Q12[ k ] = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */
|
||||||
|
a32_QA1[ k ] = SKP_LSHIFT( (SKP_int32)a_Q12[ k ], QA + 1 - 12 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
a_Q12[ k ] = (SKP_int16)SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return as SKP_int16 Q12 coefficients */
|
for( i = 1; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
||||||
|
if( silk_LPC_inverse_pred_gain( &invGain_Q30, a_Q12, d ) == 1 ) {
|
||||||
|
/* 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 - SKP_SMULBB( 9 + i, i ) ); /* 10_Q16 = 0.00015 */
|
||||||
for( k = 0; k < d; k++ ) {
|
for( k = 0; k < d; k++ ) {
|
||||||
a[k] = (SKP_int16)a_int32[k];
|
a_Q12[ k ] = (SKP_int16)SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
|
||||||
|
/* Reached the last iteration, set coefficients to zero */
|
||||||
|
for( k = 0; k < d; k++ ) {
|
||||||
|
a_Q12[ k ] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
/***********************************************************************
|
|
||||||
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, (subject to the limitations in the disclaimer below)
|
|
||||||
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 Skype Limited, nor the names of specific
|
|
||||||
contributors, may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
|
||||||
BY THIS LICENSE. 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.
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include "silk_main.h"
|
|
||||||
|
|
||||||
/* Convert NLSF parameters to stable AR prediction filter coefficients */
|
|
||||||
void silk_NLSF2A_stable(
|
|
||||||
SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
|
|
||||||
const SKP_int16 pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
|
|
||||||
const SKP_int LPC_order /* I LPC/LSF order */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SKP_int i;
|
|
||||||
SKP_int32 invGain_Q30;
|
|
||||||
|
|
||||||
silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );
|
|
||||||
|
|
||||||
/* Ensure stable LPCs */
|
|
||||||
for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
|
|
||||||
if( silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
|
|
||||||
silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015 */
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reached the last iteration */
|
|
||||||
if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
|
|
||||||
for( i = 0; i < LPC_order; i++ ) {
|
|
||||||
pAR_Q12[ i ] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,6 +25,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
#include "silk_define.h"
|
||||||
#include "silk_SigProc_FIX.h"
|
#include "silk_SigProc_FIX.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -33,11 +34,9 @@ Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust.,
|
||||||
Signal Processing, pp. 641-644, 1991.
|
Signal Processing, pp. 641-644, 1991.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define Q_OUT 5
|
|
||||||
|
|
||||||
/* Laroia low complexity NLSF weights */
|
/* Laroia low complexity NLSF weights */
|
||||||
void silk_NLSF_VQ_weights_laroia(
|
void silk_NLSF_VQ_weights_laroia(
|
||||||
SKP_int16 *pNLSFW_Q5, /* O: Pointer to input vector weights [D x 1] */
|
SKP_int16 *pNLSFW_Q_OUT, /* O: Pointer to input vector weights [D x 1] */
|
||||||
const SKP_int16 *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
const SKP_int16 *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
||||||
const SKP_int D /* I: Input vector dimension (even) */
|
const SKP_int D /* I: Input vector dimension (even) */
|
||||||
)
|
)
|
||||||
|
@ -50,28 +49,28 @@ void silk_NLSF_VQ_weights_laroia(
|
||||||
|
|
||||||
/* First value */
|
/* First value */
|
||||||
tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], 1 );
|
tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], 1 );
|
||||||
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||||
tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );
|
tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );
|
||||||
tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
|
tmp2_int = SKP_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp2_int );
|
||||||
pNLSFW_Q5[ 0 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
pNLSFW_Q_OUT[ 0 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
SKP_assert( pNLSFW_Q5[ 0 ] > 0 );
|
SKP_assert( pNLSFW_Q_OUT[ 0 ] > 0 );
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
for( k = 1; k < D - 1; k += 2 ) {
|
for( k = 1; k < D - 1; k += 2 ) {
|
||||||
tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );
|
tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );
|
||||||
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||||
pNLSFW_Q5[ k ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
pNLSFW_Q_OUT[ k ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
SKP_assert( pNLSFW_Q5[ k ] > 0 );
|
SKP_assert( pNLSFW_Q_OUT[ k ] > 0 );
|
||||||
|
|
||||||
tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );
|
tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );
|
||||||
tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
|
tmp2_int = SKP_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp2_int );
|
||||||
pNLSFW_Q5[ k + 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
pNLSFW_Q_OUT[ k + 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
SKP_assert( pNLSFW_Q5[ k + 1 ] > 0 );
|
SKP_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Last value */
|
/* Last value */
|
||||||
tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );
|
tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );
|
||||||
tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
|
tmp1_int = SKP_DIV32_16( 1 << ( 15 + NLSF_W_Q ), tmp1_int );
|
||||||
pNLSFW_Q5[ D - 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
pNLSFW_Q_OUT[ D - 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
|
||||||
SKP_assert( pNLSFW_Q5[ D - 1 ] > 0 );
|
SKP_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,8 @@ void silk_NLSF_decode(
|
||||||
SKP_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
SKP_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 ec_ix[ MAX_LPC_ORDER ];
|
SKP_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 res_Q10[ MAX_LPC_ORDER ];
|
SKP_int16 res_Q10[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 W_tmp_Q5[ MAX_LPC_ORDER ];
|
SKP_int16 W_tmp_QW[ MAX_LPC_ORDER ];
|
||||||
SKP_int32 W_tmp_Q9;
|
SKP_int32 W_tmp_Q9, NLSF_Q15_tmp;
|
||||||
const SKP_uint8 *pCB_element;
|
const SKP_uint8 *pCB_element;
|
||||||
|
|
||||||
/* Decode first stage */
|
/* Decode first stage */
|
||||||
|
@ -83,12 +83,13 @@ void silk_NLSF_decode(
|
||||||
silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
|
silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
|
||||||
|
|
||||||
/* Weights from codebook vector */
|
/* Weights from codebook vector */
|
||||||
silk_NLSF_VQ_weights_laroia( W_tmp_Q5, pNLSF_Q15, psNLSF_CB->order );
|
silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );
|
||||||
|
|
||||||
/* Apply inverse square-rooted weights and add to output */
|
/* Apply inverse square-rooted weights and add to output */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_Q5[ i ], 13 ) );
|
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||||
pNLSF_Q15[ i ] = SKP_ADD16( pNLSF_Q15[ i ], (SKP_int16)SKP_DIV32_16( SKP_LSHIFT( ( SKP_int32 )res_Q10[ i ], 14 ), W_tmp_Q9 ) );
|
NLSF_Q15_tmp = SKP_ADD32( pNLSF_Q15[ i ], SKP_DIV32_16( SKP_LSHIFT( ( SKP_int32 )res_Q10[ i ], 14 ), W_tmp_Q9 ) );
|
||||||
|
pNLSF_Q15[ i ] = (SKP_int16)SKP_LIMIT( NLSF_Q15_tmp, 0, 32767 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NLSF stabilization */
|
/* NLSF stabilization */
|
||||||
|
|
|
@ -36,7 +36,7 @@ SKP_int32 silk_NLSF_encode( /* O Returns RD value
|
||||||
SKP_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
SKP_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
||||||
SKP_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
SKP_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
||||||
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
||||||
const SKP_int16 *pW_Q5, /* I NLSF weight vector [ LPC_ORDER ] */
|
const SKP_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */
|
||||||
const SKP_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
|
const SKP_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
|
||||||
const SKP_int nSurvivors, /* I Max survivors after first stage */
|
const SKP_int nSurvivors, /* I Max survivors after first stage */
|
||||||
const SKP_int signalType /* I Signal type: 0/1/2 */
|
const SKP_int signalType /* I Signal type: 0/1/2 */
|
||||||
|
@ -51,7 +51,7 @@ SKP_int32 silk_NLSF_encode( /* O Returns RD value
|
||||||
SKP_int16 res_Q15[ MAX_LPC_ORDER ];
|
SKP_int16 res_Q15[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 res_Q10[ MAX_LPC_ORDER ];
|
SKP_int16 res_Q10[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
|
SKP_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 W_tmp_Q5[ MAX_LPC_ORDER ];
|
SKP_int16 W_tmp_QW[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 W_adj_Q5[ MAX_LPC_ORDER ];
|
SKP_int16 W_adj_Q5[ MAX_LPC_ORDER ];
|
||||||
SKP_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
SKP_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 ec_ix[ MAX_LPC_ORDER ];
|
SKP_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||||
|
@ -91,17 +91,17 @@ SKP_int32 silk_NLSF_encode( /* O Returns RD value
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Weights from codebook vector */
|
/* Weights from codebook vector */
|
||||||
silk_NLSF_VQ_weights_laroia( W_tmp_Q5, NLSF_tmp_Q15, psNLSF_CB->order );
|
silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );
|
||||||
|
|
||||||
/* Apply square-rooted weights */
|
/* Apply square-rooted weights */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_Q5[ i ], 13 ) );
|
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||||
res_Q10[ i ] = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
res_Q10[ i ] = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modify input weights accordingly */
|
/* Modify input weights accordingly */
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_adj_Q5[ i ] = SKP_DIV32_16( SKP_LSHIFT( ( SKP_int32 )pW_Q5[ i ], 5 ), W_tmp_Q5[ i ] );
|
W_adj_Q5[ i ] = SKP_DIV32_16( SKP_LSHIFT( ( SKP_int32 )pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack entropy table indices and predictor for current CB1 index */
|
/* Unpack entropy table indices and predictor for current CB1 index */
|
||||||
|
@ -142,9 +142,9 @@ SKP_int32 silk_NLSF_encode( /* O Returns RD value
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
NLSF_tmp_Q15[ i ] = SKP_LSHIFT16( ( SKP_int16 )pCB_element[ i ], 7 );
|
NLSF_tmp_Q15[ i ] = SKP_LSHIFT16( ( SKP_int16 )pCB_element[ i ], 7 );
|
||||||
}
|
}
|
||||||
silk_NLSF_VQ_weights_laroia( W_tmp_Q5, NLSF_tmp_Q15, psNLSF_CB->order );
|
silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );
|
||||||
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
for( i = 0; i < psNLSF_CB->order; i++ ) {
|
||||||
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_Q5[ i ], 13 ) );
|
W_tmp_Q9 = silk_SQRT_APPROX( SKP_LSHIFT( ( SKP_int32 )W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
|
||||||
res_Q15[ i ] = pNLSF_Q15_orig[ i ] - NLSF_tmp_Q15[ i ];
|
res_Q15[ i ] = pNLSF_Q15_orig[ i ] - NLSF_tmp_Q15[ i ];
|
||||||
res_Q10[ i ] = (SKP_int16)SKP_RSHIFT( SKP_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
res_Q10[ i ] = (SKP_int16)SKP_RSHIFT( SKP_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
|
||||||
DEBUG_STORE_DATA( NLSF_res_q10.dat, &res_Q10[ i ], sizeof( SKP_int16 ) );
|
DEBUG_STORE_DATA( NLSF_res_q10.dat, &res_Q10[ i ], sizeof( SKP_int16 ) );
|
||||||
|
|
|
@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/* Euclidean distance to input vector */
|
/* Euclidean distance to input vector */
|
||||||
/* - Output are sorted NLSF coefficients */
|
/* - Output are sorted NLSF coefficients */
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
#include "silk_SigProc_FIX.h"
|
#include "silk_SigProc_FIX.h"
|
||||||
|
|
||||||
/* Constant Definitions */
|
/* Constant Definitions */
|
||||||
|
@ -45,10 +46,9 @@ void silk_NLSF_stabilize(
|
||||||
const SKP_int L /* I: Number of NLSF parameters in the input vector */
|
const SKP_int L /* I: Number of NLSF parameters in the input vector */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int16 center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
|
SKP_int i, I=0, k, loops;
|
||||||
SKP_int32 min_diff_Q15;
|
SKP_int16 center_freq_Q15;
|
||||||
SKP_int loops;
|
SKP_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15;
|
||||||
SKP_int i, I=0, k;
|
|
||||||
|
|
||||||
/* This is necessary to ensure an output within range of a SKP_int16 */
|
/* This is necessary to ensure an output within range of a SKP_int16 */
|
||||||
SKP_assert( NDeltaMin_Q15[L] >= 1 );
|
SKP_assert( NDeltaMin_Q15[L] >= 1 );
|
||||||
|
@ -99,11 +99,11 @@ void silk_NLSF_stabilize(
|
||||||
min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
|
min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||||
|
|
||||||
/* Find the upper extreme for the location of the current center frequency */
|
/* Find the upper extreme for the location of the current center frequency */
|
||||||
max_center_Q15 = (1<<15);
|
max_center_Q15 = 1 << 15;
|
||||||
for( k = L; k > I; k-- ) {
|
for( k = L; k > I; k-- ) {
|
||||||
max_center_Q15 -= NDeltaMin_Q15[k];
|
max_center_Q15 -= NDeltaMin_Q15[k];
|
||||||
}
|
}
|
||||||
max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );
|
max_center_Q15 -= SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
|
||||||
|
|
||||||
/* Move apart, sorted by value, keeping the same center frequency */
|
/* Move apart, sorted by value, keeping the same center frequency */
|
||||||
center_freq_Q15 = (SKP_int16)SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
|
center_freq_Q15 = (SKP_int16)SKP_LIMIT_32( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
|
||||||
|
|
|
@ -129,32 +129,7 @@ void silk_biquad_alt(
|
||||||
const SKP_int32 len /* I: signal length (must be even) */
|
const SKP_int32 len /* I: signal length (must be even) */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*!
|
/* Variable order MA prediction error filter. */
|
||||||
* variable order MA filter. Prediction error filter implementation. Coeficients negated and starting with coef to x[n - 1]
|
|
||||||
*/
|
|
||||||
void silk_MA_Prediction(
|
|
||||||
const SKP_int16 *in, /* I: Input signal */
|
|
||||||
const SKP_int16 *B, /* I: MA prediction coefficients, Q12 [order] */
|
|
||||||
SKP_int32 *S, /* I/O: State vector [order] */
|
|
||||||
SKP_int16 *out, /* O: Output signal */
|
|
||||||
const SKP_int32 len, /* I: Signal length */
|
|
||||||
const SKP_int32 order /* I: Filter order */
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* 16th order AR filter for LPC synthesis, coefficients are in Q12
|
|
||||||
*/
|
|
||||||
void silk_LPC_synthesis_order16(
|
|
||||||
const SKP_int16 *in, /* I: excitation signal */
|
|
||||||
const SKP_int16 *A_Q12, /* I: AR coefficients [16], between -8_Q0 and 8_Q0 */
|
|
||||||
const SKP_int32 Gain_Q26, /* I: gain */
|
|
||||||
SKP_int32 *S, /* I/O: state vector [16] */
|
|
||||||
SKP_int16 *out, /* O: output signal */
|
|
||||||
const SKP_int32 len /* I: signal length, must be multiple of 16 */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* variable order MA prediction error filter. */
|
|
||||||
/* Inverse filter of silk_LPC_synthesis_filter */
|
|
||||||
void silk_LPC_analysis_filter(
|
void silk_LPC_analysis_filter(
|
||||||
SKP_int16 *out, /* O: Output signal */
|
SKP_int16 *out, /* O: Output signal */
|
||||||
const SKP_int16 *in, /* I: Input signal */
|
const SKP_int16 *in, /* I: Input signal */
|
||||||
|
@ -163,17 +138,6 @@ void silk_LPC_analysis_filter(
|
||||||
const SKP_int32 Order /* I: Filter order */
|
const SKP_int32 Order /* I: Filter order */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* even order AR filter */
|
|
||||||
void silk_LPC_synthesis_filter(
|
|
||||||
const SKP_int16 *in, /* I: excitation signal */
|
|
||||||
const SKP_int16 *A_Q12, /* I: AR coefficients [Order], between -8_Q0 and 8_Q0 */
|
|
||||||
const SKP_int32 Gain_Q26, /* I: gain */
|
|
||||||
SKP_int32 *S, /* I/O: state vector [Order] */
|
|
||||||
SKP_int16 *out, /* O: output signal */
|
|
||||||
const SKP_int32 len, /* I: signal length */
|
|
||||||
const SKP_int Order /* I: filter order, must be even */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Chirp (bandwidth expand) LP AR filter */
|
/* Chirp (bandwidth expand) LP AR filter */
|
||||||
void silk_bwexpander(
|
void silk_bwexpander(
|
||||||
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
SKP_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */
|
||||||
|
@ -321,13 +285,6 @@ SKP_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 u
|
||||||
const SKP_int nb_subfr /* I number of 5 ms subframes */
|
const SKP_int nb_subfr /* I number of 5 ms subframes */
|
||||||
);
|
);
|
||||||
|
|
||||||
void silk_LPC_fit(
|
|
||||||
SKP_int16 *a_QQ, /* O stabilized LPC vector, Q(24-rshift) [L] */
|
|
||||||
SKP_int32 *a_Q24, /* I LPC vector [L] */
|
|
||||||
const SKP_int QQ, /* I Q domain of output LPC vector */
|
|
||||||
const SKP_int L /* I Number of LPC parameters in the input vector */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
|
/* 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. */
|
/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
|
||||||
void silk_A2NLSF(
|
void silk_A2NLSF(
|
||||||
|
@ -338,9 +295,9 @@ void silk_A2NLSF(
|
||||||
|
|
||||||
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
/* compute whitening filter coefficients from normalized line spectral frequencies */
|
||||||
void silk_NLSF2A(
|
void silk_NLSF2A(
|
||||||
SKP_int16 *a, /* o monic whitening filter coefficients in Q12, [d] */
|
SKP_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
|
||||||
const SKP_int16 *NLSF, /* i normalized line spectral frequencies in Q15, [d] */
|
const SKP_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
|
||||||
const SKP_int d /* i filter order (should be even) */
|
const SKP_int d /* I filter order (should be even) */
|
||||||
);
|
);
|
||||||
|
|
||||||
void silk_insertion_sort_increasing(
|
void silk_insertion_sort_increasing(
|
||||||
|
@ -371,7 +328,7 @@ void silk_NLSF_stabilize(
|
||||||
|
|
||||||
/* Laroia low complexity NLSF weights */
|
/* Laroia low complexity NLSF weights */
|
||||||
void silk_NLSF_VQ_weights_laroia(
|
void silk_NLSF_VQ_weights_laroia(
|
||||||
SKP_int16 *pNLSFW_Q5, /* O: Pointer to input vector weights [D x 1] */
|
SKP_int16 *pNLSFW_Q_OUT, /* O: Pointer to input vector weights [D x 1] */
|
||||||
const SKP_int16 *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
const SKP_int16 *pNLSF_Q15, /* I: Pointer to input vector [D x 1] */
|
||||||
const SKP_int D /* I: Input vector dimension (even) */
|
const SKP_int D /* I: Input vector dimension (even) */
|
||||||
);
|
);
|
||||||
|
|
|
@ -35,9 +35,7 @@ void silk_bwexpander(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int i;
|
SKP_int i;
|
||||||
SKP_int32 chirp_minus_one_Q16;
|
SKP_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
||||||
|
|
||||||
chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
|
||||||
|
|
||||||
/* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL(), 16 ), below. */
|
/* NB: Dont use SKP_SMULWB, instead of SKP_RSHIFT_ROUND( SKP_MUL(), 16 ), below. */
|
||||||
/* Bias in SKP_SMULWB can lead to unstable filters */
|
/* Bias in SKP_SMULWB can lead to unstable filters */
|
||||||
|
|
|
@ -35,12 +35,12 @@ void silk_bwexpander_32(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int i;
|
SKP_int i;
|
||||||
SKP_int32 tmp_chirp_Q16;
|
SKP_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536;
|
||||||
|
|
||||||
tmp_chirp_Q16 = chirp_Q16;
|
|
||||||
for( i = 0; i < d - 1; i++ ) {
|
for( i = 0; i < d - 1; i++ ) {
|
||||||
ar[ i ] = SKP_SMULWW( ar[ i ], tmp_chirp_Q16 );
|
ar[ i ] = SKP_SMULWW( chirp_Q16, ar[ i ] );
|
||||||
tmp_chirp_Q16 = SKP_SMULWW( chirp_Q16, tmp_chirp_Q16 );
|
chirp_Q16 += SKP_RSHIFT_ROUND( SKP_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
|
||||||
}
|
}
|
||||||
ar[ d - 1 ] = SKP_SMULWW( ar[ d - 1 ], tmp_chirp_Q16 );
|
ar[ d - 1 ] = SKP_SMULWW( chirp_Q16, ar[ d - 1 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,13 +125,9 @@
|
||||||
<ClCompile Include="silk_log2lin.c" />
|
<ClCompile Include="silk_log2lin.c" />
|
||||||
<ClCompile Include="silk_LPC_analysis_filter.c" />
|
<ClCompile Include="silk_LPC_analysis_filter.c" />
|
||||||
<ClCompile Include="silk_LPC_inv_pred_gain.c" />
|
<ClCompile Include="silk_LPC_inv_pred_gain.c" />
|
||||||
<ClCompile Include="silk_LPC_stabilize.c" />
|
|
||||||
<ClCompile Include="silk_LPC_synthesis_filter.c" />
|
|
||||||
<ClCompile Include="silk_LPC_synthesis_order16.c" />
|
|
||||||
<ClCompile Include="silk_LP_variable_cutoff.c" />
|
<ClCompile Include="silk_LP_variable_cutoff.c" />
|
||||||
<ClCompile Include="silk_table_LSF_cos.c" />
|
<ClCompile Include="silk_table_LSF_cos.c" />
|
||||||
<ClCompile Include="silk_NLSF2A.c" />
|
<ClCompile Include="silk_NLSF2A.c" />
|
||||||
<ClCompile Include="silk_NLSF2A_stable.c" />
|
|
||||||
<ClCompile Include="silk_NLSF_decode.c" />
|
<ClCompile Include="silk_NLSF_decode.c" />
|
||||||
<ClCompile Include="silk_NLSF_del_dec_quant.c" />
|
<ClCompile Include="silk_NLSF_del_dec_quant.c" />
|
||||||
<ClCompile Include="silk_NLSF_encode.c" />
|
<ClCompile Include="silk_NLSF_encode.c" />
|
||||||
|
|
|
@ -138,24 +138,12 @@
|
||||||
<ClCompile Include="silk_LPC_inv_pred_gain.c">
|
<ClCompile Include="silk_LPC_inv_pred_gain.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="silk_LPC_stabilize.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="silk_LPC_synthesis_filter.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="silk_LPC_synthesis_order16.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="silk_table_LSF_cos.c">
|
<ClCompile Include="silk_table_LSF_cos.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="silk_NLSF2A.c">
|
<ClCompile Include="silk_NLSF2A.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="silk_NLSF2A_stable.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="silk_NLSF_decode.c">
|
<ClCompile Include="silk_NLSF_decode.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -349,7 +349,7 @@ SKP_int silk_setup_complexity(
|
||||||
psEncC->nStatesDelayedDecision = 2;
|
psEncC->nStatesDelayedDecision = 2;
|
||||||
psEncC->useInterpolatedNLSFs = 0;
|
psEncC->useInterpolatedNLSFs = 0;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 6;
|
psEncC->NLSF_MSVQ_Survivors = 8;
|
||||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||||
} else if( Complexity < 8 ) {
|
} else if( Complexity < 8 ) {
|
||||||
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
|
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
|
||||||
|
@ -360,7 +360,7 @@ SKP_int silk_setup_complexity(
|
||||||
psEncC->nStatesDelayedDecision = 3;
|
psEncC->nStatesDelayedDecision = 3;
|
||||||
psEncC->useInterpolatedNLSFs = 0;
|
psEncC->useInterpolatedNLSFs = 0;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 8;
|
psEncC->NLSF_MSVQ_Survivors = 16;
|
||||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||||
} else {
|
} else {
|
||||||
psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
|
psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
|
||||||
|
@ -371,7 +371,7 @@ SKP_int silk_setup_complexity(
|
||||||
psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
|
psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
|
||||||
psEncC->useInterpolatedNLSFs = 1;
|
psEncC->useInterpolatedNLSFs = 1;
|
||||||
psEncC->LTPQuantLowComplexity = 0;
|
psEncC->LTPQuantLowComplexity = 0;
|
||||||
psEncC->NLSF_MSVQ_Survivors = 16;
|
psEncC->NLSF_MSVQ_Survivors = 32;
|
||||||
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void silk_decode_parameters(
|
||||||
silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
|
silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
|
||||||
|
|
||||||
/* Convert NLSF parameters to AR prediction filter coefficients */
|
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||||
silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
|
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
|
||||||
|
|
||||||
/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
|
/* 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 */
|
/* improves the case of packet loss in the first frame after a switch */
|
||||||
|
@ -64,7 +64,7 @@ void silk_decode_parameters(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert NLSF parameters to AR prediction filter coefficients */
|
/* Convert NLSF parameters to AR prediction filter coefficients */
|
||||||
silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
|
||||||
} else {
|
} else {
|
||||||
/* Copy LPC coefficients for first half from second half */
|
/* Copy LPC coefficients for first half from second half */
|
||||||
SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
|
SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ],
|
||||||
|
|
|
@ -205,8 +205,9 @@ extern "C"
|
||||||
/******************/
|
/******************/
|
||||||
/* NLSF quantizer */
|
/* NLSF quantizer */
|
||||||
/******************/
|
/******************/
|
||||||
|
#define NLSF_W_Q 2
|
||||||
#define NLSF_VQ_MAX_VECTORS 32
|
#define NLSF_VQ_MAX_VECTORS 32
|
||||||
#define NLSF_VQ_MAX_SURVIVORS 16
|
#define NLSF_VQ_MAX_SURVIVORS 32
|
||||||
#define NLSF_QUANT_MAX_AMPLITUDE 4
|
#define NLSF_QUANT_MAX_AMPLITUDE 4
|
||||||
#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
|
#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
|
||||||
#define NLSF_QUANT_LEVEL_ADJ 0.1
|
#define NLSF_QUANT_LEVEL_ADJ 0.1
|
||||||
|
|
|
@ -183,13 +183,6 @@ void silk_gains_dequant(
|
||||||
const SKP_int nb_subfr /* I number of subframes */
|
const SKP_int nb_subfr /* I number of subframes */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Convert NLSF parameters to stable AR prediction filter coefficients */
|
|
||||||
void silk_NLSF2A_stable(
|
|
||||||
SKP_int16 pAR_Q12[ MAX_LPC_ORDER ], /* O Stabilized AR coefs [LPC_order] */
|
|
||||||
const SKP_int16 pNLSF[ MAX_LPC_ORDER ], /* I NLSF vector [LPC_order] */
|
|
||||||
const SKP_int LPC_order /* I LPC/LSF order */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Interpolate two vectors */
|
/* Interpolate two vectors */
|
||||||
void silk_interpolate(
|
void silk_interpolate(
|
||||||
SKP_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */
|
SKP_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */
|
||||||
|
@ -306,7 +299,7 @@ SKP_int32 silk_NLSF_encode( /* O Returns RD v
|
||||||
SKP_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
SKP_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
|
||||||
SKP_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
SKP_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
|
||||||
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
|
||||||
const SKP_int16 *pW_Q5, /* I NLSF weight vector [ LPC_ORDER ] */
|
const SKP_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */
|
||||||
const SKP_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
|
const SKP_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
|
||||||
const SKP_int nSurvivors, /* I Max survivors after first stage */
|
const SKP_int nSurvivors, /* I Max survivors after first stage */
|
||||||
const SKP_int signalType /* I Signal type: 0/1/2 */
|
const SKP_int signalType /* I Signal type: 0/1/2 */
|
||||||
|
|
|
@ -36,11 +36,11 @@ void silk_process_NLSFs(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SKP_int i, doInterpolate;
|
SKP_int i, doInterpolate;
|
||||||
SKP_int16 pNLSFW_Q5[ MAX_LPC_ORDER ];
|
|
||||||
SKP_int NLSF_mu_Q20;
|
SKP_int NLSF_mu_Q20;
|
||||||
SKP_int32 i_sqr_Q15;
|
SKP_int32 i_sqr_Q15;
|
||||||
SKP_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
|
SKP_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
|
||||||
SKP_int16 pNLSFW0_temp_Q5[ MAX_LPC_ORDER ];
|
SKP_int16 pNLSFW_QW[ MAX_LPC_ORDER ];
|
||||||
|
SKP_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ];
|
||||||
|
|
||||||
SKP_assert( psEncC->speech_activity_Q8 >= 0 );
|
SKP_assert( psEncC->speech_activity_Q8 >= 0 );
|
||||||
SKP_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
|
SKP_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
|
||||||
|
@ -49,7 +49,7 @@ void silk_process_NLSFs(
|
||||||
/* Calculate mu values */
|
/* Calculate mu values */
|
||||||
/***********************/
|
/***********************/
|
||||||
/* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */
|
/* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */
|
||||||
NLSF_mu_Q20 = SKP_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.0015, 28 ), psEncC->speech_activity_Q8 );
|
NLSF_mu_Q20 = SKP_SMLAWB( SILK_FIX_CONST( 0.0025, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 );
|
||||||
if( psEncC->nb_subfr == 2 ) {
|
if( psEncC->nb_subfr == 2 ) {
|
||||||
/* Multiply by 1.5 for 10 ms packets */
|
/* Multiply by 1.5 for 10 ms packets */
|
||||||
NLSF_mu_Q20 = SKP_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
|
NLSF_mu_Q20 = SKP_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
|
||||||
|
@ -59,7 +59,7 @@ void silk_process_NLSFs(
|
||||||
SKP_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.0045, 20 ) );
|
SKP_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.0045, 20 ) );
|
||||||
|
|
||||||
/* Calculate NLSF weights */
|
/* Calculate NLSF weights */
|
||||||
silk_NLSF_VQ_weights_laroia( pNLSFW_Q5, pNLSF_Q15, psEncC->predictLPCOrder );
|
silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Update NLSF weights for interpolated NLSFs */
|
/* Update NLSF weights for interpolated NLSFs */
|
||||||
doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );
|
doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );
|
||||||
|
@ -69,24 +69,24 @@ void silk_process_NLSFs(
|
||||||
psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
|
psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Calculate first half NLSF weights for the interpolated NLSFs */
|
/* Calculate first half NLSF weights for the interpolated NLSFs */
|
||||||
silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_Q5, pNLSF0_temp_Q15, psEncC->predictLPCOrder );
|
silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Update NLSF weights with contribution from first half */
|
/* Update NLSF weights with contribution from first half */
|
||||||
i_sqr_Q15 = SKP_LSHIFT( SKP_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
|
i_sqr_Q15 = SKP_LSHIFT( SKP_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
|
||||||
for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
|
for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
|
||||||
pNLSFW_Q5[ i ] = SKP_SMLAWB( SKP_RSHIFT( pNLSFW_Q5[ i ], 1 ), pNLSFW0_temp_Q5[ i ], i_sqr_Q15 );
|
pNLSFW_QW[ i ] = SKP_SMLAWB( SKP_RSHIFT( pNLSFW_QW[ i ], 1 ), pNLSFW0_temp_QW[ i ], i_sqr_Q15 );
|
||||||
SKP_assert( pNLSFW_Q5[ i ] <= SKP_int16_MAX );
|
SKP_assert( pNLSFW_QW[ i ] <= SKP_int16_MAX );
|
||||||
SKP_assert( pNLSFW_Q5[ i ] >= 1 );
|
SKP_assert( pNLSFW_QW[ i ] >= 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIC(NLSF_encode)
|
TIC(NLSF_encode)
|
||||||
silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_Q5,
|
silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,
|
||||||
NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
|
NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
|
||||||
TOC(NLSF_encode)
|
TOC(NLSF_encode)
|
||||||
|
|
||||||
/* Convert quantized NLSFs back to LPC coefficients */
|
/* Convert quantized NLSFs back to LPC coefficients */
|
||||||
silk_NLSF2A_stable( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder );
|
silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
if( doInterpolate ) {
|
if( doInterpolate ) {
|
||||||
/* Calculate the interpolated, quantized LSF vector for the first half */
|
/* Calculate the interpolated, quantized LSF vector for the first half */
|
||||||
|
@ -94,7 +94,7 @@ void silk_process_NLSFs(
|
||||||
psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
|
psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
/* Convert back to LPC coefficients */
|
/* Convert back to LPC coefficients */
|
||||||
silk_NLSF2A_stable( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder );
|
silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Copy LPC coefficients for first half from second half */
|
/* Copy LPC coefficients for first half from second half */
|
||||||
|
|
|
@ -135,7 +135,7 @@ const SKP_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const SKP_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
|
const SKP_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
|
||||||
322, 3, 6, 3, 3, 3, 4, 3,
|
250, 3, 6, 3, 3, 3, 4, 3,
|
||||||
3, 3, 461
|
3, 3, 461
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ const SKP_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const SKP_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
|
const SKP_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
|
||||||
121, 3, 42, 3, 3, 3, 5, 14,
|
100, 3, 40, 3, 3, 3, 5, 14,
|
||||||
14, 10, 11, 3, 8, 9, 7, 3,
|
14, 10, 11, 3, 8, 9, 7, 3,
|
||||||
347
|
347
|
||||||
};
|
};
|
||||||
|
@ -181,8 +181,8 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB =
|
||||||
{
|
{
|
||||||
32,
|
32,
|
||||||
16,
|
16,
|
||||||
SILK_FIX_CONST( 0.16, 16 ),
|
SILK_FIX_CONST( 0.15, 16 ),
|
||||||
SILK_FIX_CONST( 1.0 / 0.16, 6 ),
|
SILK_FIX_CONST( 1.0 / 0.15, 6 ),
|
||||||
silk_NLSF_CB1_WB_Q8,
|
silk_NLSF_CB1_WB_Q8,
|
||||||
silk_NLSF_CB1_iCDF_WB,
|
silk_NLSF_CB1_iCDF_WB,
|
||||||
silk_NLSF_PRED_WB_Q8,
|
silk_NLSF_PRED_WB_Q8,
|
||||||
|
@ -191,3 +191,4 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB =
|
||||||
silk_NLSF_CB2_BITS_WB_Q5,
|
silk_NLSF_CB2_BITS_WB_Q5,
|
||||||
silk_NLSF_DELTA_MIN_WB_Q15,
|
silk_NLSF_DELTA_MIN_WB_Q15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ silk/silk_encode_pulses.c \
|
||||||
silk/silk_gain_quant.c \
|
silk/silk_gain_quant.c \
|
||||||
silk/silk_interpolate.c \
|
silk/silk_interpolate.c \
|
||||||
silk/silk_LP_variable_cutoff.c \
|
silk/silk_LP_variable_cutoff.c \
|
||||||
silk/silk_NLSF2A_stable.c \
|
|
||||||
silk/silk_NLSF_decode.c \
|
silk/silk_NLSF_decode.c \
|
||||||
silk/silk_NSQ.c \
|
silk/silk_NSQ.c \
|
||||||
silk/silk_NSQ_del_dec.c \
|
silk/silk_NSQ_del_dec.c \
|
||||||
|
@ -62,9 +61,6 @@ silk/silk_lin2log.c \
|
||||||
silk/silk_log2lin.c \
|
silk/silk_log2lin.c \
|
||||||
silk/silk_LPC_analysis_filter.c \
|
silk/silk_LPC_analysis_filter.c \
|
||||||
silk/silk_LPC_inv_pred_gain.c \
|
silk/silk_LPC_inv_pred_gain.c \
|
||||||
silk/silk_LPC_stabilize.c \
|
|
||||||
silk/silk_LPC_synthesis_filter.c \
|
|
||||||
silk/silk_LPC_synthesis_order16.c \
|
|
||||||
silk/silk_table_LSF_cos.c \
|
silk/silk_table_LSF_cos.c \
|
||||||
silk/silk_NLSF2A.c \
|
silk/silk_NLSF2A.c \
|
||||||
silk/silk_NLSF_stabilize.c \
|
silk/silk_NLSF_stabilize.c \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue