Update opus from 1.1.4 to 1.2.1
This commit is contained in:
1 parent
c38c823a2a
commit
cb24c59567
155 files changed
+6263
-3968
No files matched your search
@@ -45,7 +45,7 @@ void silk_LTP_analysis_filter_FIX(
|
||||
const opus_int16 *x_ptr, *x_lag_ptr;
|
||||
opus_int16 Btmp_Q14[ LTP_ORDER ];
|
||||
opus_int16 *LTP_res_ptr;
|
||||
opus_int k, i, j;
|
||||
opus_int k, i;
|
||||
opus_int32 LTP_est;
|
||||
|
||||
x_ptr = x;
|
||||
@@ -53,9 +53,12 @@ void silk_LTP_analysis_filter_FIX(
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
|
||||
x_lag_ptr = x_ptr - pitchL[ k ];
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ];
|
||||
}
|
||||
|
||||
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++ ) {
|
||||
@@ -63,9 +66,11 @@ void silk_LTP_analysis_filter_FIX(
|
||||
|
||||
/* Long-term prediction */
|
||||
LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
|
||||
for( j = 1; j < LTP_ORDER; j++ ) {
|
||||
LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] );
|
||||
}
|
||||
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 */
|
||||
|
||||
@@ -37,12 +37,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#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 N_BITS_HEAD_ROOM 3
|
||||
#define MIN_RSHIFTS -16
|
||||
#define MAX_RSHIFTS (32 - QA)
|
||||
|
||||
/* Compute reflection coefficients from input signal */
|
||||
void silk_burg_modified(
|
||||
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) */
|
||||
@@ -54,7 +54,7 @@ void silk_burg_modified(
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
|
||||
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 ];
|
||||
@@ -63,27 +63,23 @@ void silk_burg_modified(
|
||||
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 */
|
||||
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;
|
||||
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 {
|
||||
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;
|
||||
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 ) {
|
||||
@@ -91,7 +87,7 @@ void silk_burg_modified(
|
||||
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 ), rshifts );
|
||||
silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -154,8 +150,11 @@ void silk_burg_modified(
|
||||
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 */
|
||||
/* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
|
||||
but they cancel each other and the real result seems to always fit in a 32-bit
|
||||
signed integer. This was determined experimentally, not theoretically (unfortunately). */
|
||||
tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
|
||||
tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
|
||||
}
|
||||
tmp1 = -tmp1; /* Q17 */
|
||||
tmp2 = -tmp2; /* Q17 */
|
||||
@@ -204,12 +203,14 @@ void silk_burg_modified(
|
||||
/* 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;
|
||||
if( rc_Q31 > 0 ) {
|
||||
/* 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;
|
||||
@@ -252,12 +253,12 @@ void silk_burg_modified(
|
||||
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 ), rshifts );
|
||||
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 ), -rshifts );
|
||||
C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);
|
||||
}
|
||||
}
|
||||
/* Approximate residual energy */
|
||||
|
||||
@@ -42,7 +42,8 @@ void silk_corrVector_FIX(
|
||||
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 */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int lag, i;
|
||||
@@ -57,7 +58,7 @@ void silk_corrVector_FIX(
|
||||
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 );
|
||||
inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
|
||||
}
|
||||
Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
@@ -65,7 +66,7 @@ void silk_corrVector_FIX(
|
||||
} else {
|
||||
silk_assert( rshifts == 0 );
|
||||
for( lag = 0; lag < order; lag++ ) {
|
||||
Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
|
||||
Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */
|
||||
ptr1--; /* Go to next column of X */
|
||||
}
|
||||
}
|
||||
@@ -76,60 +77,54 @@ 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 */
|
||||
opus_int32 *nrg, /* O Energy of x vector */
|
||||
opus_int *rshifts, /* O Right shifts of correlations and energy */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, j, lag, rshifts_local, head_room_rshifts;
|
||||
opus_int i, j, lag;
|
||||
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;
|
||||
silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
|
||||
energy = *nrg;
|
||||
|
||||
/* 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;
|
||||
energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *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;
|
||||
silk_assert( energy >= 0 );
|
||||
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 ) );
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
|
||||
matrix_ptr( XX, j, j, order ) = energy;
|
||||
silk_assert( energy >= 0 );
|
||||
}
|
||||
|
||||
ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
|
||||
/* Calculate the remaining elements of the correlation matrix */
|
||||
if( rshifts_local > 0 ) {
|
||||
if( *rshifts > 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 );
|
||||
energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
|
||||
}
|
||||
/* 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 ) );
|
||||
energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
|
||||
energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
|
||||
matrix_ptr( XX, lag + j, j, order ) = energy;
|
||||
matrix_ptr( XX, j, lag + j, order ) = energy;
|
||||
}
|
||||
@@ -138,7 +133,7 @@ void silk_corrMatrix_FIX(
|
||||
} 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 );
|
||||
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] */
|
||||
@@ -151,6 +146,5 @@ void silk_corrMatrix_FIX(
|
||||
ptr2--;/* Update pointer to first sample of next column (lag) in X */
|
||||
}
|
||||
}
|
||||
*rshifts = rshifts_local;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "main_FIX.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "tuning_parameters.h"
|
||||
@@ -37,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
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 */
|
||||
const opus_int16 x16[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
);
|
||||
|
||||
@@ -48,7 +49,7 @@ void silk_encode_do_VAD_FIX(
|
||||
/****************************/
|
||||
/* Voice Activity Detection */
|
||||
/****************************/
|
||||
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 );
|
||||
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
|
||||
|
||||
/**************************************************/
|
||||
/* Convert speech activity into VAD and DTX flags */
|
||||
@@ -94,6 +95,9 @@ opus_int silk_encode_frame_FIX(
|
||||
opus_int16 ec_prevLagIndex_copy;
|
||||
opus_int ec_prevSignalType_copy;
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
|
||||
opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
|
||||
opus_int best_sum[ MAX_NB_SUBFR ];
|
||||
SAVE_STACK;
|
||||
|
||||
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
|
||||
@@ -118,7 +122,6 @@ opus_int silk_encode_frame_FIX(
|
||||
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;
|
||||
@@ -132,7 +135,7 @@ opus_int silk_encode_frame_FIX(
|
||||
/*****************************************/
|
||||
/* Find pitch lags, initial LPC analysis */
|
||||
/*****************************************/
|
||||
silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
|
||||
silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
|
||||
|
||||
/************************/
|
||||
/* Noise shape analysis */
|
||||
@@ -142,23 +145,17 @@ opus_int silk_encode_frame_FIX(
|
||||
/***************************************************/
|
||||
/* Find linear prediction coefficients (LPC + LTP) */
|
||||
/***************************************************/
|
||||
silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
|
||||
silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, 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 );
|
||||
silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
|
||||
|
||||
/* Loop over quantizer and entropy coding to control bitrate */
|
||||
maxIter = 6;
|
||||
@@ -194,13 +191,19 @@ opus_int silk_encode_frame_FIX(
|
||||
/* 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 );
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_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 );
|
||||
silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
|
||||
sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_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);
|
||||
}
|
||||
|
||||
if ( iter == maxIter && !found_lower ) {
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
@@ -216,6 +219,33 @@ opus_int silk_encode_frame_FIX(
|
||||
|
||||
nBits = ec_tell( psRangeEnc );
|
||||
|
||||
/* If we still bust after the last iteration, do some damage control. */
|
||||
if ( iter == maxIter && !found_lower && nBits > maxBits ) {
|
||||
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
|
||||
|
||||
/* Keep gains the same as the last frame. */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
psEnc->sCmn.indices.GainsIndices[ i ] = 4;
|
||||
}
|
||||
if (condCoding != CODE_CONDITIONALLY) {
|
||||
psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
|
||||
}
|
||||
psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
|
||||
psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
|
||||
/* Clear all pulses. */
|
||||
for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
|
||||
psEnc->sCmn.pulses[ i ] = 0;
|
||||
}
|
||||
|
||||
silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -263,15 +293,35 @@ opus_int silk_encode_frame_FIX(
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found_lower && nBits > maxBits ) {
|
||||
int j;
|
||||
for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
int sum=0;
|
||||
for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
|
||||
sum += abs( psEnc->sCmn.pulses[j] );
|
||||
}
|
||||
if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
|
||||
best_sum[i] = sum;
|
||||
best_gain_mult[i] = gainMult_Q8;
|
||||
} else {
|
||||
gain_lock[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 ) );
|
||||
if (gainMult_Q8 < 16384) {
|
||||
gainMult_Q8 *= 2;
|
||||
} else {
|
||||
gainMult_Q8 = 32767;
|
||||
}
|
||||
} else {
|
||||
opus_int32 gain_factor_Q16;
|
||||
gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
|
||||
gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
|
||||
}
|
||||
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 );
|
||||
@@ -285,9 +335,15 @@ opus_int silk_encode_frame_FIX(
|
||||
}
|
||||
|
||||
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 );
|
||||
opus_int16 tmp;
|
||||
if ( gain_lock[i] ) {
|
||||
tmp = best_gain_mult[i];
|
||||
} else {
|
||||
tmp = gainMult_Q8;
|
||||
}
|
||||
sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
|
||||
}
|
||||
|
||||
|
||||
/* Quantize gains */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
|
||||
@@ -329,7 +385,7 @@ opus_int silk_encode_frame_FIX(
|
||||
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 */
|
||||
const opus_int16 x16[], /* I Input signal */
|
||||
opus_int condCoding /* I The type of conditional coding used so far for this frame */
|
||||
)
|
||||
{
|
||||
@@ -368,15 +424,15 @@ static OPUS_INLINE void silk_LBRR_encode_FIX(
|
||||
/* 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,
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
|
||||
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 );
|
||||
psEncCtrl->AR_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,
|
||||
silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
|
||||
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 );
|
||||
psEncCtrl->AR_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 */
|
||||
|
||||
@@ -92,10 +92,10 @@ void silk_find_LPC_FIX(
|
||||
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 );
|
||||
silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
/* Calculate residual energy with NLSF interpolation */
|
||||
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder );
|
||||
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 );
|
||||
|
||||
@@ -32,213 +32,68 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#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 */
|
||||
opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
|
||||
opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
|
||||
const opus_int16 r_ptr[], /* I Residual signal after LPC */
|
||||
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 */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i, k, lshift;
|
||||
const opus_int16 *r_ptr, *lag_ptr;
|
||||
opus_int16 *b_Q14_ptr;
|
||||
opus_int i, k, extra_shifts;
|
||||
opus_int xx_shifts, xX_shifts, XX_shifts;
|
||||
const opus_int16 *lag_ptr;
|
||||
opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
|
||||
opus_int32 xx, nrg, temp;
|
||||
|
||||
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 ];
|
||||
xXLTP_Q17_ptr = xXLTP_Q17;
|
||||
XXLTP_Q17_ptr = XXLTP_Q17;
|
||||
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 ] ); /* 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 ] ); /* 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 ] );
|
||||
silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */
|
||||
silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch ); /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */
|
||||
extra_shifts = xx_shifts - XX_shifts;
|
||||
if( extra_shifts > 0 ) {
|
||||
/* Shift XX */
|
||||
xX_shifts = xx_shifts;
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */
|
||||
}
|
||||
nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */
|
||||
} else if( extra_shifts < 0 ) {
|
||||
/* Shift xx */
|
||||
xX_shifts = XX_shifts;
|
||||
xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */
|
||||
} else {
|
||||
temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
|
||||
xX_shifts = xx_shifts;
|
||||
}
|
||||
silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
|
||||
|
||||
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 */
|
||||
/* At this point all correlations are in Q(-xX_shifts) */
|
||||
temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
|
||||
temp = silk_max( temp, xx );
|
||||
TIC(div)
|
||||
#if 0
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
|
||||
}
|
||||
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 );
|
||||
xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
|
||||
}
|
||||
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 ) );
|
||||
#else
|
||||
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
|
||||
}
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
|
||||
}
|
||||
#endif
|
||||
TOC(div)
|
||||
r_ptr += subfr_length;
|
||||
XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
|
||||
xXLTP_Q17_ptr += LTP_ORDER;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ void silk_find_pitch_lags_FIX(
|
||||
{
|
||||
opus_int buf_len, i, scale;
|
||||
opus_int32 thrhld_Q13, res_nrg;
|
||||
const opus_int16 *x_buf, *x_buf_ptr;
|
||||
const opus_int16 *x_ptr;
|
||||
VARDECL( opus_int16, Wsig );
|
||||
opus_int16 *Wsig_ptr;
|
||||
opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
|
||||
@@ -61,8 +61,6 @@ void silk_find_pitch_lags_FIX(
|
||||
/* Safety check */
|
||||
silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
|
||||
|
||||
x_buf = x - psEnc->sCmn.ltp_mem_length;
|
||||
|
||||
/*************************************/
|
||||
/* Estimate LPC AR coefficients */
|
||||
/*************************************/
|
||||
@@ -72,19 +70,19 @@ void silk_find_pitch_lags_FIX(
|
||||
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;
|
||||
x_ptr = x + 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 );
|
||||
silk_apply_sine_window( Wsig_ptr, x_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 ) );
|
||||
x_ptr += psEnc->sCmn.la_pitch;
|
||||
silk_memcpy( Wsig_ptr, x_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 );
|
||||
x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
|
||||
silk_apply_sine_window( Wsig_ptr, x_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 );
|
||||
@@ -112,7 +110,7 @@ void silk_find_pitch_lags_FIX(
|
||||
/*****************************************/
|
||||
/* LPC analysis filtering */
|
||||
/*****************************************/
|
||||
silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
|
||||
silk_LPC_analysis_filter( res, x, 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 */
|
||||
|
||||
@@ -41,13 +41,12 @@ void silk_find_pred_coefs_FIX(
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
|
||||
opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ 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 ];
|
||||
opus_int32 min_gain_Q16, minInvGain_Q30;
|
||||
SAVE_STACK;
|
||||
|
||||
/* weighting for weighted least squares */
|
||||
@@ -61,13 +60,11 @@ void silk_find_pred_coefs_FIX(
|
||||
/* 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 );
|
||||
/* Limit inverse */
|
||||
invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
|
||||
|
||||
/* 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 ] );
|
||||
@@ -77,23 +74,24 @@ void silk_find_pred_coefs_FIX(
|
||||
psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
|
||||
+ psEnc->sCmn.frame_length, opus_int16 );
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
VARDECL( opus_int32, WLTP );
|
||||
VARDECL( opus_int32, xXLTP_Q17 );
|
||||
VARDECL( opus_int32, XXLTP_Q17 );
|
||||
|
||||
/**********/
|
||||
/* 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 );
|
||||
ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
|
||||
ALLOC( XXLTP_Q17, 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 );
|
||||
silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
|
||||
psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, 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.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
|
||||
|
||||
/* Control LTP scaling */
|
||||
silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
|
||||
@@ -118,16 +116,16 @@ void silk_find_pred_coefs_FIX(
|
||||
|
||||
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;
|
||||
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 {
|
||||
} 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 ),
|
||||
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 );
|
||||
}
|
||||
|
||||
@@ -139,7 +137,7 @@ void silk_find_pred_coefs_FIX(
|
||||
|
||||
/* 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.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 ) );
|
||||
|
||||
@@ -39,14 +39,15 @@ void silk_k2a(
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 rc, tmp1, tmp2;
|
||||
|
||||
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 ] );
|
||||
rc = rc_Q15[ k ];
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = A_Q24[ n ];
|
||||
tmp2 = A_Q24[ k - n - 1 ];
|
||||
A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
|
||||
A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
|
||||
}
|
||||
A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
|
||||
}
|
||||
|
||||
@@ -39,15 +39,16 @@ void silk_k2a_Q16(
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
opus_int32 rc, tmp1, tmp2;
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Atmp[ n ] = A_Q24[ n ];
|
||||
rc = rc_Q16[ k ];
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = A_Q24[ n ];
|
||||
tmp2 = A_Q24[ k - n - 1 ];
|
||||
A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc );
|
||||
A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
|
||||
}
|
||||
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 );
|
||||
A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "debug.h"
|
||||
#include "entenc.h"
|
||||
|
||||
#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
|
||||
|| defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
|
||||
#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -47,6 +52,9 @@ extern "C"
|
||||
#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
|
||||
#define silk_encode_frame_Fxx silk_encode_frame_FIX
|
||||
|
||||
#define QC 10
|
||||
#define QS 13
|
||||
|
||||
/*********************/
|
||||
/* Encoder Functions */
|
||||
/*********************/
|
||||
@@ -81,22 +89,11 @@ opus_int silk_init_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 */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Noise shaping analysis */
|
||||
/**************************/
|
||||
@@ -110,7 +107,7 @@ void silk_noise_shape_analysis_FIX(
|
||||
);
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
void silk_warped_autocorrelation_FIX(
|
||||
void silk_warped_autocorrelation_FIX_c(
|
||||
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 */
|
||||
@@ -119,6 +116,11 @@ void silk_warped_autocorrelation_FIX(
|
||||
const opus_int order /* I Correlation order (even) */
|
||||
);
|
||||
|
||||
#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
|
||||
#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
|
||||
((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
|
||||
#endif
|
||||
|
||||
/* Calculation of LTP state scaling */
|
||||
void silk_LTP_scale_ctrl_FIX(
|
||||
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
|
||||
@@ -157,16 +159,13 @@ void silk_find_LPC_FIX(
|
||||
|
||||
/* 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 */
|
||||
opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
|
||||
opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
|
||||
const opus_int16 r_lpc[], /* I Residual signal after LPC */
|
||||
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 */
|
||||
const opus_int subfr_length, /* I Subframe length */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
void silk_LTP_analysis_filter_FIX(
|
||||
@@ -190,7 +189,8 @@ void silk_residual_energy_FIX(
|
||||
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 */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
|
||||
@@ -218,9 +218,10 @@ 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 */
|
||||
opus_int32 *nrg, /* O Energy of x vector */
|
||||
opus_int *rshifts, /* O Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Calculates correlation vector X'*t */
|
||||
@@ -230,23 +231,8 @@ void silk_corrVector_FIX(
|
||||
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 */
|
||||
);
|
||||
|
||||
/* 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 */
|
||||
const opus_int rshifts, /* I Right shifts of correlations */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
#ifndef FORCE_CPP_BUILD
|
||||
|
||||
@@ -57,90 +57,86 @@ static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
|
||||
/* 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_int32 *coefs_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 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
|
||||
opus_int32 nom_Q16, den_Q24;
|
||||
opus_int32 limit_Q20, maxabs_Q20;
|
||||
|
||||
/* 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 );
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_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 );
|
||||
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_Q24[ 0 ], lambda_Q16 );
|
||||
gain_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 ] );
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
|
||||
}
|
||||
|
||||
limit_Q20 = silk_RSHIFT(limit_Q24, 4);
|
||||
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 ] ) );
|
||||
tmp = silk_abs_int32( coefs_Q24[ i ] );
|
||||
if( tmp > maxabs_Q24 ) {
|
||||
maxabs_Q24 = tmp;
|
||||
ind = i;
|
||||
}
|
||||
}
|
||||
if( maxabs_Q24 <= limit_Q24 ) {
|
||||
/* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
|
||||
maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
|
||||
if( maxabs_Q20 <= limit_Q20 ) {
|
||||
/* 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 );
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
|
||||
}
|
||||
gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );
|
||||
gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );
|
||||
gain_Q16 = silk_INVERSE32_varQ( gain_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 ] );
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_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 );
|
||||
silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
|
||||
silk_MUL( maxabs_Q20, ind + 1 ), 22 );
|
||||
silk_bwexpander_32( coefs_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 );
|
||||
coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_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 );
|
||||
den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
|
||||
gain_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 ] );
|
||||
coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
|
||||
}
|
||||
}
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
/* Disable MIPS version until it's updated. */
|
||||
#if 0 && 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 */
|
||||
@@ -150,14 +146,13 @@ void silk_noise_shape_analysis_FIX(
|
||||
)
|
||||
{
|
||||
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_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
|
||||
opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
|
||||
opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
|
||||
opus_int32 BWExp_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 ];
|
||||
opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ];
|
||||
VARDECL( opus_int16, x_windowed );
|
||||
const opus_int16 *x_ptr, *pitch_res_ptr;
|
||||
SAVE_STACK;
|
||||
@@ -204,14 +199,14 @@ void silk_noise_shape_analysis_FIX(
|
||||
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++ ) {
|
||||
nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
|
||||
for( k = 0; k < nSegs; k++ ) {
|
||||
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
|
||||
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
|
||||
|
||||
@@ -223,18 +218,12 @@ void silk_noise_shape_analysis_FIX(
|
||||
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 ) ) {
|
||||
if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
|
||||
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 ) );
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
@@ -242,14 +231,8 @@ void silk_noise_shape_analysis_FIX(
|
||||
/*******************************/
|
||||
/* 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 ),
|
||||
BWExp_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 */
|
||||
@@ -279,7 +262,7 @@ void silk_noise_shape_analysis_FIX(
|
||||
|
||||
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 );
|
||||
silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
|
||||
} else {
|
||||
/* Calculate regular auto correlation */
|
||||
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
|
||||
@@ -294,7 +277,7 @@ void silk_noise_shape_analysis_FIX(
|
||||
silk_assert( nrg >= 0 );
|
||||
|
||||
/* Convert reflection coefficients to prediction coefficients */
|
||||
silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
Qnrg = -scale; /* range: -12...30*/
|
||||
silk_assert( Qnrg >= -12 );
|
||||
@@ -313,40 +296,34 @@ void silk_noise_shape_analysis_FIX(
|
||||
|
||||
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;
|
||||
gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
|
||||
if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
|
||||
if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
|
||||
} else {
|
||||
psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
|
||||
}
|
||||
}
|
||||
silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
|
||||
}
|
||||
|
||||
/* Bandwidth expansion for synthesis filter shaping */
|
||||
silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
|
||||
/* Bandwidth expansion */
|
||||
silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
|
||||
|
||||
/* Compute noise shaping filter coefficients */
|
||||
silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* 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 ) );
|
||||
/* Convert from Q24 to Q13 and store in int16 */
|
||||
for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
|
||||
psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
|
||||
}
|
||||
} else {
|
||||
silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,11 +340,6 @@ void silk_noise_shape_analysis_FIX(
|
||||
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 */
|
||||
@@ -405,14 +377,6 @@ void silk_noise_shape_analysis_FIX(
|
||||
/****************************/
|
||||
/* 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 ),
|
||||
@@ -430,16 +394,14 @@ void silk_noise_shape_analysis_FIX(
|
||||
/* 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 */
|
||||
@@ -72,14 +72,15 @@ static void silk_P_Ana_calc_energy_st3(
|
||||
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 */
|
||||
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 */
|
||||
const opus_int16 *frame_unscaled, /* 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 */
|
||||
@@ -93,16 +94,17 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
VARDECL( opus_int16, frame_8kHz );
|
||||
VARDECL( opus_int16, frame_8kHz_buf );
|
||||
VARDECL( opus_int16, frame_4kHz );
|
||||
VARDECL( opus_int16, frame_scaled );
|
||||
opus_int32 filt_state[ 6 ];
|
||||
const opus_int16 *input_frame_ptr;
|
||||
const opus_int16 *frame, *frame_8kHz;
|
||||
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;
|
||||
opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
|
||||
opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
|
||||
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;
|
||||
@@ -118,6 +120,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
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 );
|
||||
|
||||
@@ -136,17 +139,33 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
min_lag = PE_MIN_LAG_MS * Fs_kHz;
|
||||
max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
|
||||
|
||||
/* Downscale input if necessary */
|
||||
silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
|
||||
shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */
|
||||
ALLOC( frame_scaled, frame_length, opus_int16 );
|
||||
if( shift > 0 ) {
|
||||
shift = silk_RSHIFT( shift + 1, 1 );
|
||||
for( i = 0; i < frame_length; i++ ) {
|
||||
frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
|
||||
}
|
||||
frame = frame_scaled;
|
||||
} else {
|
||||
frame = frame_unscaled;
|
||||
}
|
||||
|
||||
ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
|
||||
/* 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 );
|
||||
silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length );
|
||||
frame_8kHz = frame_8kHz_buf;
|
||||
} 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 );
|
||||
silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
|
||||
frame_8kHz = frame_8kHz_buf;
|
||||
} else {
|
||||
silk_assert( Fs_kHz == 8 );
|
||||
silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
|
||||
frame_8kHz = frame;
|
||||
}
|
||||
|
||||
/* Decimate again to 4 kHz */
|
||||
@@ -159,19 +178,6 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
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
|
||||
@@ -195,8 +201,8 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
|
||||
/* 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 );
|
||||
normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ ) );
|
||||
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 ) =
|
||||
@@ -310,18 +316,6 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
** 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
|
||||
*********************************************************************************/
|
||||
@@ -334,7 +328,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
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 ), 1 );
|
||||
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;
|
||||
@@ -343,9 +337,9 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
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 );
|
||||
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 );
|
||||
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,
|
||||
@@ -461,24 +455,6 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
|
||||
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;
|
||||
@@ -518,15 +494,15 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 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 );
|
||||
silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
|
||||
silk_P_Ana_calc_energy_st3( energies_st3, frame, 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 ), 1 );
|
||||
target_ptr = &frame[ 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;
|
||||
@@ -671,7 +647,8 @@ static void silk_P_Ana_calc_energy_st3(
|
||||
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 */
|
||||
opus_int complexity, /* I Complexity setting */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
const opus_int16 *target_ptr, *basis_ptr;
|
||||
@@ -705,7 +682,7 @@ static void silk_P_Ana_calc_energy_st3(
|
||||
|
||||
/* 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 );
|
||||
energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch );
|
||||
silk_assert( energy >= 0 );
|
||||
scratch_mem[ lag_counter ] = energy;
|
||||
lag_counter++;
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
/***********************************************************************
|
||||
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"
|
||||
|
||||
/* 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(
|
||||
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 );
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -42,7 +42,8 @@ void silk_residual_energy_FIX(
|
||||
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 */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int offset, i, j, rshift, lz1, lz2;
|
||||
@@ -60,7 +61,7 @@ void silk_residual_energy_FIX(
|
||||
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 );
|
||||
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;
|
||||
|
||||
@@ -43,7 +43,7 @@ opus_int32 silk_schur64( /* O returns residual ene
|
||||
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 );
|
||||
silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
|
||||
|
||||
/* Check for invalid input */
|
||||
if( c[ 0 ] <= 0 ) {
|
||||
@@ -51,9 +51,10 @@ opus_int32 silk_schur64( /* O returns residual ene
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
k = 0;
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
}
|
||||
} while( ++k <= order );
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Check that we won't be getting an unstable rc, otherwise stop here. */
|
||||
|
||||
@@ -43,28 +43,29 @@ opus_int32 silk_schur( /* O Returns residual ene
|
||||
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 );
|
||||
silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
|
||||
|
||||
/* Get number of leading zeros */
|
||||
lz = silk_CLZ32( c[ 0 ] );
|
||||
|
||||
/* Copy correlations and adjust level to Q30 */
|
||||
k = 0;
|
||||
if( lz < 2 ) {
|
||||
/* lz must be 1, so shift one to the right */
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
|
||||
}
|
||||
} while( ++k <= order );
|
||||
} else if( lz > 2 ) {
|
||||
/* Shift to the left */
|
||||
lz -= 2;
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
|
||||
}
|
||||
} while( ++k <= order );
|
||||
} else {
|
||||
/* No need to shift */
|
||||
for( k = 0; k < order + 1; k++ ) {
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
|
||||
}
|
||||
} while( ++k <= order );
|
||||
}
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
/***********************************************************************
|
||||
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 );
|
||||
}
|
||||
}
|
||||
@@ -47,31 +47,17 @@ typedef struct {
|
||||
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 */
|
||||
opus_int32 resNrgSmth;
|
||||
} silk_encoder_state_FIX;
|
||||
|
||||
/************************/
|
||||
@@ -87,11 +73,8 @@ typedef struct {
|
||||
|
||||
/* 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 ];
|
||||
silk_DWORD_ALIGN opus_int16 AR_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;
|
||||
@@ -99,7 +82,6 @@ typedef struct {
|
||||
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 */
|
||||
@@ -116,6 +98,7 @@ typedef 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;
|
||||
|
||||
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#endif
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "pitch.h"
|
||||
|
||||
/* Copy and multiply a vector by a constant */
|
||||
void silk_scale_copy_vector16(
|
||||
@@ -70,18 +71,23 @@ void silk_scale_vector32_Q26_lshift_18(
|
||||
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 */
|
||||
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(
|
||||
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 */
|
||||
|
||||
@@ -31,11 +31,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "main_FIX.h"
|
||||
|
||||
#define QC 10
|
||||
#define QS 14
|
||||
#if defined(MIPSr1_ASM)
|
||||
#include "mips/warped_autocorrelation_FIX_mipsr1.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Autocorrelations for a warped frequency axis */
|
||||
void silk_warped_autocorrelation_FIX(
|
||||
void silk_warped_autocorrelation_FIX_c(
|
||||
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 */
|
||||
|
||||
Reference in new issue
Block a user