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
@@ -31,8 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "SigProc_FIX.h"
|
||||
#include "SigProc_FLP.h"
|
||||
|
||||
#define RC_THRESHOLD 0.9999f
|
||||
#include "define.h"
|
||||
|
||||
/* compute inverse of LPC prediction gain, and */
|
||||
/* test if LPC coefficients are stable (all poles within unit circle) */
|
||||
@@ -43,34 +42,32 @@ silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction ga
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
double invGain, rc, rc_mult1, rc_mult2;
|
||||
silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
|
||||
silk_float *Aold, *Anew;
|
||||
double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2;
|
||||
silk_float Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
|
||||
Anew = Atmp[ order & 1 ];
|
||||
silk_memcpy( Anew, A, order * sizeof(silk_float) );
|
||||
silk_memcpy( Atmp, A, order * sizeof(silk_float) );
|
||||
|
||||
invGain = 1.0;
|
||||
for( k = order - 1; k > 0; k-- ) {
|
||||
rc = -Anew[ k ];
|
||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||
rc = -Atmp[ k ];
|
||||
rc_mult1 = 1.0f - rc * rc;
|
||||
invGain *= rc_mult1;
|
||||
if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
|
||||
return 0.0f;
|
||||
}
|
||||
rc_mult1 = 1.0f - rc * rc;
|
||||
rc_mult2 = 1.0f / rc_mult1;
|
||||
invGain *= rc_mult1;
|
||||
/* swap pointers */
|
||||
Aold = Anew;
|
||||
Anew = Atmp[ k & 1 ];
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = Atmp[ n ];
|
||||
tmp2 = Atmp[ k - n - 1 ];
|
||||
Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 );
|
||||
Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 );
|
||||
}
|
||||
}
|
||||
rc = -Anew[ 0 ];
|
||||
if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
|
||||
return 0.0f;
|
||||
}
|
||||
rc = -Atmp[ 0 ];
|
||||
rc_mult1 = 1.0f - rc * rc;
|
||||
invGain *= rc_mult1;
|
||||
if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
|
||||
return 0.0f;
|
||||
}
|
||||
return (silk_float)invGain;
|
||||
}
|
||||
@@ -68,13 +68,6 @@ void silk_k2a_FLP(
|
||||
opus_int32 order /* I prediction order */
|
||||
);
|
||||
|
||||
/* Solve the normal equations using the Levinson-Durbin recursion */
|
||||
silk_float silk_levinsondurbin_FLP( /* O prediction error energy */
|
||||
silk_float A[], /* O prediction coefficients [order] */
|
||||
const silk_float corr[], /* I input auto-correlations [order + 1] */
|
||||
const opus_int order /* I prediction order */
|
||||
);
|
||||
|
||||
/* compute autocorrelation */
|
||||
void silk_autocorrelation_FLP(
|
||||
silk_float *results, /* O result (length correlationCount) */
|
||||
|
||||
@@ -29,6 +29,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "main_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
@@ -85,7 +86,6 @@ opus_int silk_encode_frame_FLP(
|
||||
silk_encoder_control_FLP sEncCtrl;
|
||||
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
|
||||
silk_float *x_frame, *res_pitch_frame;
|
||||
silk_float xfw[ MAX_FRAME_LENGTH ];
|
||||
silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
|
||||
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
|
||||
silk_nsq_state sNSQ_copy, sNSQ_copy2;
|
||||
@@ -97,6 +97,9 @@ opus_int silk_encode_frame_FLP(
|
||||
opus_int8 LastGainIndex_copy2;
|
||||
opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
|
||||
opus_uint8 ec_buf_copy[ 1275 ];
|
||||
opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
|
||||
opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
|
||||
opus_int best_sum[ MAX_NB_SUBFR ];
|
||||
|
||||
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
|
||||
LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
|
||||
@@ -139,22 +142,17 @@ opus_int silk_encode_frame_FLP(
|
||||
/***************************************************/
|
||||
/* Find linear prediction coefficients (LPC + LTP) */
|
||||
/***************************************************/
|
||||
silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
|
||||
silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
|
||||
|
||||
/****************************************/
|
||||
/* Process gains */
|
||||
/****************************************/
|
||||
silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
|
||||
|
||||
/*****************************************/
|
||||
/* Prefiltering for noise shaper */
|
||||
/*****************************************/
|
||||
silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );
|
||||
|
||||
/****************************************/
|
||||
/* Low Bitrate Redundant Encoding */
|
||||
/****************************************/
|
||||
silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
|
||||
silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
|
||||
|
||||
/* Loop over quantizer and entroy coding to control bitrate */
|
||||
maxIter = 6;
|
||||
@@ -188,7 +186,11 @@ opus_int silk_encode_frame_FLP(
|
||||
/*****************************************/
|
||||
/* Noise shaping quantization */
|
||||
/*****************************************/
|
||||
silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );
|
||||
silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
|
||||
|
||||
if ( iter == maxIter && !found_lower ) {
|
||||
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Encode Parameters */
|
||||
@@ -203,6 +205,33 @@ opus_int silk_encode_frame_FLP(
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -223,7 +252,9 @@ opus_int silk_encode_frame_FLP(
|
||||
if( nBits > maxBits ) {
|
||||
if( found_lower == 0 && iter >= 2 ) {
|
||||
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
|
||||
sEncCtrl.Lambda *= 1.5f;
|
||||
sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
|
||||
/* Reducing dithering can help us hit the target. */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
found_upper = 0;
|
||||
gainsID_upper = -1;
|
||||
} else {
|
||||
@@ -250,15 +281,34 @@ opus_int silk_encode_frame_FLP(
|
||||
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 + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
|
||||
@@ -272,7 +322,13 @@ opus_int silk_encode_frame_FLP(
|
||||
}
|
||||
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
pGains_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;
|
||||
}
|
||||
pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
|
||||
}
|
||||
|
||||
/* Quantize gains */
|
||||
|
||||
@@ -37,13 +37,12 @@ double silk_energy_FLP(
|
||||
opus_int dataSize
|
||||
)
|
||||
{
|
||||
opus_int i, dataSize4;
|
||||
opus_int i;
|
||||
double result;
|
||||
|
||||
/* 4x unrolled loop */
|
||||
result = 0.0;
|
||||
dataSize4 = dataSize & 0xFFFC;
|
||||
for( i = 0; i < dataSize4; i += 4 ) {
|
||||
for( i = 0; i < dataSize - 3; i += 4 ) {
|
||||
result += data[ i + 0 ] * (double)data[ i + 0 ] +
|
||||
data[ i + 1 ] * (double)data[ i + 1 ] +
|
||||
data[ i + 2 ] * (double)data[ i + 2 ] +
|
||||
|
||||
@@ -73,7 +73,7 @@ void silk_find_LPC_FLP(
|
||||
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
|
||||
|
||||
/* Convert to LPC for residual energy evaluation */
|
||||
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );
|
||||
silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
|
||||
|
||||
/* Calculate residual energy with LSF interpolation */
|
||||
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
|
||||
|
||||
@@ -33,100 +33,32 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
void silk_find_LTP_FLP(
|
||||
silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
|
||||
silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
silk_float *LTPredCodGain, /* O LTP coding gain */
|
||||
const silk_float r_lpc[], /* I LPC residual */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */
|
||||
silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
const silk_float r_ptr[], /* I LPC residual */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
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 */
|
||||
const opus_int nb_subfr /* I number of subframes */
|
||||
)
|
||||
{
|
||||
opus_int i, k;
|
||||
silk_float *b_ptr, temp, *WLTP_ptr;
|
||||
silk_float LPC_res_nrg, LPC_LTP_res_nrg;
|
||||
silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ];
|
||||
silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu;
|
||||
silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
|
||||
const silk_float *r_ptr, *lag_ptr;
|
||||
opus_int k;
|
||||
silk_float *xX_ptr, *XX_ptr;
|
||||
const silk_float *lag_ptr;
|
||||
silk_float xx, temp;
|
||||
|
||||
b_ptr = b;
|
||||
WLTP_ptr = WLTP;
|
||||
r_ptr = &r_lpc[ mem_offset ];
|
||||
xX_ptr = xX;
|
||||
XX_ptr = XX;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
|
||||
silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr );
|
||||
silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr );
|
||||
xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER );
|
||||
temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f );
|
||||
silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER );
|
||||
silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER );
|
||||
|
||||
silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr );
|
||||
silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr );
|
||||
|
||||
rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length );
|
||||
regu = 1.0f + rr[ k ] +
|
||||
matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) +
|
||||
matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER );
|
||||
regu *= LTP_DAMPING / 3;
|
||||
silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER );
|
||||
silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr );
|
||||
|
||||
/* Calculate residual energy */
|
||||
nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER );
|
||||
|
||||
temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length );
|
||||
silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER );
|
||||
w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER );
|
||||
|
||||
r_ptr += subfr_length;
|
||||
b_ptr += LTP_ORDER;
|
||||
WLTP_ptr += LTP_ORDER * LTP_ORDER;
|
||||
}
|
||||
|
||||
/* Compute LTP coding gain */
|
||||
if( LTPredCodGain != NULL ) {
|
||||
LPC_LTP_res_nrg = 1e-6f;
|
||||
LPC_res_nrg = 0.0f;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
LPC_res_nrg += rr[ k ] * Wght[ k ];
|
||||
LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ];
|
||||
}
|
||||
|
||||
silk_assert( LPC_LTP_res_nrg > 0 );
|
||||
*LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg );
|
||||
}
|
||||
|
||||
/* Smoothing */
|
||||
/* d = sum( B, 1 ); */
|
||||
b_ptr = b;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
d[ k ] = 0;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
d[ k ] += b_ptr[ i ];
|
||||
}
|
||||
b_ptr += LTP_ORDER;
|
||||
}
|
||||
/* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
|
||||
temp = 1e-3f;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
temp += w[ k ];
|
||||
}
|
||||
m = 0;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
m += d[ k ] * w[ k ];
|
||||
}
|
||||
m = m / temp;
|
||||
|
||||
b_ptr = b;
|
||||
for( k = 0; k < nb_subfr; k++ ) {
|
||||
g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] );
|
||||
temp = 0;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f );
|
||||
temp += delta_b[ i ];
|
||||
}
|
||||
temp = g / temp;
|
||||
for( i = 0; i < LTP_ORDER; i++ ) {
|
||||
b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp;
|
||||
}
|
||||
b_ptr += LTP_ORDER;
|
||||
r_ptr += subfr_length;
|
||||
XX_ptr += LTP_ORDER * LTP_ORDER;
|
||||
xX_ptr += LTP_ORDER;
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,9 @@ void silk_find_pred_coefs_FLP(
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
|
||||
silk_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ];
|
||||
silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
|
||||
silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ];
|
||||
silk_float invGains[ MAX_NB_SUBFR ];
|
||||
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
|
||||
const silk_float *x_ptr;
|
||||
silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
|
||||
@@ -52,7 +53,6 @@ void silk_find_pred_coefs_FLP(
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
silk_assert( psEncCtrl->Gains[ i ] > 0.0f );
|
||||
invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
|
||||
Wght[ i ] = invGains[ i ] * invGains[ i ];
|
||||
}
|
||||
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
@@ -62,13 +62,11 @@ void silk_find_pred_coefs_FLP(
|
||||
silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
|
||||
|
||||
/* LTP analysis */
|
||||
silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch,
|
||||
psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length );
|
||||
silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
|
||||
|
||||
/* Quantize LTP gain parameters */
|
||||
silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
|
||||
&psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
|
||||
psEnc->sCmn.arch );
|
||||
&psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
|
||||
|
||||
/* Control LTP scaling */
|
||||
silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );
|
||||
|
||||
@@ -38,13 +38,12 @@ double silk_inner_product_FLP(
|
||||
opus_int dataSize
|
||||
)
|
||||
{
|
||||
opus_int i, dataSize4;
|
||||
opus_int i;
|
||||
double result;
|
||||
|
||||
/* 4x unrolled loop */
|
||||
result = 0.0;
|
||||
dataSize4 = dataSize & 0xFFFC;
|
||||
for( i = 0; i < dataSize4; i += 4 ) {
|
||||
for( i = 0; i < dataSize - 3; i += 4 ) {
|
||||
result += data1[ i + 0 ] * (double)data2[ i + 0 ] +
|
||||
data1[ i + 1 ] * (double)data2[ i + 1 ] +
|
||||
data1[ i + 2 ] * (double)data2[ i + 2 ] +
|
||||
|
||||
@@ -39,15 +39,16 @@ void silk_k2a_FLP(
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
silk_float Atmp[ SILK_MAX_ORDER_LPC ];
|
||||
silk_float rck, tmp1, tmp2;
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
for( n = 0; n < k; n++ ) {
|
||||
Atmp[ n ] = A[ n ];
|
||||
rck = rc[ k ];
|
||||
for( n = 0; n < (k + 1) >> 1; n++ ) {
|
||||
tmp1 = A[ n ];
|
||||
tmp2 = A[ k - n - 1 ];
|
||||
A[ n ] = tmp1 + tmp2 * rck;
|
||||
A[ k - n - 1 ] = tmp2 + tmp1 * rck;
|
||||
}
|
||||
for( n = 0; n < k; n++ ) {
|
||||
A[ n ] += Atmp[ k - n - 1 ] * rc[ k ];
|
||||
}
|
||||
A[ k ] = -rc[ k ];
|
||||
A[ k ] = -rck;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +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 "SigProc_FLP.h"
|
||||
|
||||
/* Solve the normal equations using the Levinson-Durbin recursion */
|
||||
silk_float silk_levinsondurbin_FLP( /* O prediction error energy */
|
||||
silk_float A[], /* O prediction coefficients [order] */
|
||||
const silk_float corr[], /* I input auto-correlations [order + 1] */
|
||||
const opus_int order /* I prediction order */
|
||||
)
|
||||
{
|
||||
opus_int i, mHalf, m;
|
||||
silk_float min_nrg, nrg, t, km, Atmp1, Atmp2;
|
||||
|
||||
min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;
|
||||
nrg = corr[ 0 ];
|
||||
nrg = silk_max_float(min_nrg, nrg);
|
||||
A[ 0 ] = corr[ 1 ] / nrg;
|
||||
nrg -= A[ 0 ] * corr[ 1 ];
|
||||
nrg = silk_max_float(min_nrg, nrg);
|
||||
|
||||
for( m = 1; m < order; m++ )
|
||||
{
|
||||
t = corr[ m + 1 ];
|
||||
for( i = 0; i < m; i++ ) {
|
||||
t -= A[ i ] * corr[ m - i ];
|
||||
}
|
||||
|
||||
/* reflection coefficient */
|
||||
km = t / nrg;
|
||||
|
||||
/* residual energy */
|
||||
nrg -= km * t;
|
||||
nrg = silk_max_float(min_nrg, nrg);
|
||||
|
||||
mHalf = m >> 1;
|
||||
for( i = 0; i < mHalf; i++ ) {
|
||||
Atmp1 = A[ i ];
|
||||
Atmp2 = A[ m - i - 1 ];
|
||||
A[ m - i - 1 ] -= km * Atmp1;
|
||||
A[ i ] -= km * Atmp2;
|
||||
}
|
||||
if( m & 1 ) {
|
||||
A[ mHalf ] -= km * A[ mHalf ];
|
||||
}
|
||||
A[ m ] = km;
|
||||
}
|
||||
|
||||
/* return the residual energy */
|
||||
return nrg;
|
||||
}
|
||||
|
||||
@@ -79,22 +79,11 @@ opus_int silk_init_encoder(
|
||||
opus_int silk_control_encoder(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
|
||||
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_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
|
||||
silk_float xw[], /* O Weighted signal */
|
||||
const silk_float x[] /* I Speech signal */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Noise shaping analysis */
|
||||
/**************************/
|
||||
@@ -153,15 +142,12 @@ void silk_find_LPC_FLP(
|
||||
|
||||
/* LTP analysis */
|
||||
void silk_find_LTP_FLP(
|
||||
silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
|
||||
silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
silk_float *LTPredCodGain, /* O LTP coding gain */
|
||||
const silk_float r_lpc[], /* I LPC residual */
|
||||
silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
|
||||
const silk_float r_ptr[], /* I LPC residual */
|
||||
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
|
||||
const silk_float Wght[ 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 */
|
||||
const opus_int nb_subfr /* I number of subframes */
|
||||
);
|
||||
|
||||
void silk_LTP_analysis_filter_FLP(
|
||||
@@ -198,14 +184,15 @@ void silk_LPC_analysis_filter_FLP(
|
||||
|
||||
/* LTP tap quantizer */
|
||||
void silk_quant_LTP_gains_FLP(
|
||||
silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */
|
||||
silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
|
||||
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
|
||||
opus_int8 *periodicity_index, /* O Periodicity index */
|
||||
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
|
||||
const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */
|
||||
const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */
|
||||
const opus_int lowComplexity, /* I Flag for low complexity */
|
||||
const opus_int nb_subfr, /* I number of subframes */
|
||||
silk_float *pred_gain_dB, /* O LTP prediction gain */
|
||||
const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
|
||||
const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
|
||||
const opus_int subfr_len, /* I Number of samples per subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
@@ -245,22 +232,6 @@ void silk_corrVector_FLP(
|
||||
silk_float *Xt /* O X'*t correlation vector [order] */
|
||||
);
|
||||
|
||||
/* Add noise to matrix diagonal */
|
||||
void silk_regularize_correlations_FLP(
|
||||
silk_float *XX, /* I/O Correlation matrices */
|
||||
silk_float *xx, /* I/O Correlation values */
|
||||
const silk_float noise, /* I Noise energy to add */
|
||||
const opus_int D /* I Dimension of XX */
|
||||
);
|
||||
|
||||
/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */
|
||||
void silk_solve_LDL_FLP(
|
||||
silk_float *A, /* I/O Symmetric square matrix, out: reg. */
|
||||
const opus_int M, /* I Size of matrix */
|
||||
const silk_float *b, /* I Pointer to b vector */
|
||||
silk_float *x /* O Pointer to x solution vector */
|
||||
);
|
||||
|
||||
/* Apply sine window to signal vector. */
|
||||
/* Window types: */
|
||||
/* 1 -> sine window from 0 to pi/2 */
|
||||
@@ -285,7 +256,8 @@ void silk_A2NLSF_FLP(
|
||||
void silk_NLSF2A_FLP(
|
||||
silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
||||
const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
||||
const opus_int LPC_order /* I LPC order */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
);
|
||||
|
||||
/* Limit, stabilize, and quantize NLSFs */
|
||||
|
||||
@@ -55,25 +55,21 @@ static OPUS_INLINE silk_float warped_gain(
|
||||
/* 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 warped_true2monic_coefs(
|
||||
silk_float *coefs_syn,
|
||||
silk_float *coefs_ana,
|
||||
silk_float *coefs,
|
||||
silk_float lambda,
|
||||
silk_float limit,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i, iter, ind = 0;
|
||||
silk_float tmp, maxabs, chirp, gain_syn, gain_ana;
|
||||
silk_float tmp, maxabs, chirp, gain;
|
||||
|
||||
/* Convert to monic coefficients */
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
|
||||
coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
|
||||
coefs[ i - 1 ] -= lambda * coefs[ i ];
|
||||
}
|
||||
gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
|
||||
gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
|
||||
gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn[ i ] *= gain_syn;
|
||||
coefs_ana[ i ] *= gain_ana;
|
||||
coefs[ i ] *= gain;
|
||||
}
|
||||
|
||||
/* Limit */
|
||||
@@ -81,7 +77,7 @@ static OPUS_INLINE void warped_true2monic_coefs(
|
||||
/* Find maximum absolute value */
|
||||
maxabs = -1.0f;
|
||||
for( i = 0; i < order; i++ ) {
|
||||
tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) );
|
||||
tmp = silk_abs_float( coefs[ i ] );
|
||||
if( tmp > maxabs ) {
|
||||
maxabs = tmp;
|
||||
ind = i;
|
||||
@@ -94,36 +90,59 @@ static OPUS_INLINE void warped_true2monic_coefs(
|
||||
|
||||
/* Convert back to true warped coefficients */
|
||||
for( i = 1; i < order; i++ ) {
|
||||
coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];
|
||||
coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];
|
||||
coefs[ i - 1 ] += lambda * coefs[ i ];
|
||||
}
|
||||
gain_syn = 1.0f / gain_syn;
|
||||
gain_ana = 1.0f / gain_ana;
|
||||
gain = 1.0f / gain;
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn[ i ] *= gain_syn;
|
||||
coefs_ana[ i ] *= gain_ana;
|
||||
coefs[ i ] *= gain;
|
||||
}
|
||||
|
||||
/* Apply bandwidth expansion */
|
||||
chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
|
||||
silk_bwexpander_FLP( coefs_syn, order, chirp );
|
||||
silk_bwexpander_FLP( coefs_ana, order, chirp );
|
||||
silk_bwexpander_FLP( coefs, order, chirp );
|
||||
|
||||
/* Convert to monic warped coefficients */
|
||||
for( i = order - 1; i > 0; i-- ) {
|
||||
coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
|
||||
coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
|
||||
coefs[ i - 1 ] -= lambda * coefs[ i ];
|
||||
}
|
||||
gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
|
||||
gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
|
||||
gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
|
||||
for( i = 0; i < order; i++ ) {
|
||||
coefs_syn[ i ] *= gain_syn;
|
||||
coefs_ana[ i ] *= gain_ana;
|
||||
coefs[ i ] *= gain;
|
||||
}
|
||||
}
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
static OPUS_INLINE void limit_coefs(
|
||||
silk_float *coefs,
|
||||
silk_float limit,
|
||||
opus_int order
|
||||
) {
|
||||
opus_int i, iter, ind = 0;
|
||||
silk_float tmp, maxabs, chirp;
|
||||
|
||||
for( iter = 0; iter < 10; iter++ ) {
|
||||
/* Find maximum absolute value */
|
||||
maxabs = -1.0f;
|
||||
for( i = 0; i < order; i++ ) {
|
||||
tmp = silk_abs_float( coefs[ i ] );
|
||||
if( tmp > maxabs ) {
|
||||
maxabs = tmp;
|
||||
ind = i;
|
||||
}
|
||||
}
|
||||
if( maxabs <= limit ) {
|
||||
/* Coefficients are within range - done */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Apply bandwidth expansion */
|
||||
chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
|
||||
silk_bwexpander_FLP( coefs, order, chirp );
|
||||
}
|
||||
silk_assert( 0 );
|
||||
}
|
||||
|
||||
/* Compute noise shaping coefficients and initial gain values */
|
||||
void silk_noise_shape_analysis_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
@@ -133,12 +152,13 @@ void silk_noise_shape_analysis_FLP(
|
||||
)
|
||||
{
|
||||
silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
|
||||
opus_int k, nSamples;
|
||||
silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;
|
||||
silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;
|
||||
silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;
|
||||
opus_int k, nSamples, nSegs;
|
||||
silk_float SNR_adj_dB, HarmShapeGain, Tilt;
|
||||
silk_float nrg, log_energy, log_energy_prev, energy_variation;
|
||||
silk_float BWExp, gain_mult, gain_add, strength, b, warping;
|
||||
silk_float x_windowed[ SHAPE_LPC_WIN_MAX ];
|
||||
silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
const silk_float *x_ptr, *pitch_res_ptr;
|
||||
|
||||
/* Point to start of first LPC analysis block */
|
||||
@@ -176,14 +196,14 @@ void silk_noise_shape_analysis_FLP(
|
||||
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Initially set to 0; may be overruled in process_gains(..) */
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
psEncCtrl->sparseness = 0.0f;
|
||||
} else {
|
||||
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
|
||||
nSamples = 2 * psEnc->sCmn.fs_kHz;
|
||||
energy_variation = 0.0f;
|
||||
log_energy_prev = 0.0f;
|
||||
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++ ) {
|
||||
nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
|
||||
log_energy = silk_log2( nrg );
|
||||
if( k > 0 ) {
|
||||
@@ -192,17 +212,13 @@ void silk_noise_shape_analysis_FLP(
|
||||
log_energy_prev = log_energy;
|
||||
pitch_res_ptr += nSamples;
|
||||
}
|
||||
psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) );
|
||||
|
||||
/* Set quantization offset depending on sparseness measure */
|
||||
if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {
|
||||
if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) {
|
||||
psEnc->sCmn.indices.quantOffsetType = 0;
|
||||
} else {
|
||||
psEnc->sCmn.indices.quantOffsetType = 1;
|
||||
}
|
||||
|
||||
/* Increase coding SNR for sparse signals */
|
||||
SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
@@ -210,19 +226,10 @@ void silk_noise_shape_analysis_FLP(
|
||||
/*******************************/
|
||||
/* More BWE for signals with high prediction gain */
|
||||
strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
|
||||
BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
|
||||
delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );
|
||||
BWExp1 -= delta;
|
||||
BWExp2 += delta;
|
||||
/* BWExp1 will be applied after BWExp2, so make it relative */
|
||||
BWExp1 /= BWExp2;
|
||||
BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
|
||||
} else {
|
||||
warping = 0.0f;
|
||||
}
|
||||
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
|
||||
warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
|
||||
|
||||
/********************************************/
|
||||
/* Compute noise shaping AR coefs and gains */
|
||||
@@ -252,37 +259,28 @@ void silk_noise_shape_analysis_FLP(
|
||||
}
|
||||
|
||||
/* Add white noise, as a fraction of energy */
|
||||
auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;
|
||||
auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f;
|
||||
|
||||
/* Convert correlations to prediction coefficients, and compute residual energy */
|
||||
nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder );
|
||||
silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder );
|
||||
psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
|
||||
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Adjust gain for warping */
|
||||
psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
|
||||
psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
|
||||
}
|
||||
|
||||
/* Bandwidth expansion for synthesis filter shaping */
|
||||
silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );
|
||||
silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp );
|
||||
|
||||
/* Compute noise shaping filter coefficients */
|
||||
silk_memcpy(
|
||||
&psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
|
||||
&psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],
|
||||
psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) );
|
||||
|
||||
/* Bandwidth expansion for analysis filter shaping */
|
||||
silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
|
||||
|
||||
/* Ratio of prediction gains, in energy domain */
|
||||
pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
||||
nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
|
||||
psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
|
||||
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
|
||||
warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
|
||||
if( psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
/* Convert to monic warped prediction coefficients and limit absolute values */
|
||||
warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
|
||||
} else {
|
||||
/* Limit absolute values */
|
||||
limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder );
|
||||
}
|
||||
}
|
||||
|
||||
/*****************/
|
||||
@@ -296,11 +294,6 @@ void silk_noise_shape_analysis_FLP(
|
||||
psEncCtrl->Gains[ k ] += gain_add;
|
||||
}
|
||||
|
||||
gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psEncCtrl->GainsPre[ k ] *= gain_mult;
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Control low-frequency shaping and noise tilt */
|
||||
/************************************************/
|
||||
@@ -331,12 +324,6 @@ void silk_noise_shape_analysis_FLP(
|
||||
/****************************/
|
||||
/* HARMONIC SHAPING CONTROL */
|
||||
/****************************/
|
||||
/* Control boosting of harmonic frequencies */
|
||||
HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;
|
||||
|
||||
/* More harmonic boost for noisy input signals */
|
||||
HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );
|
||||
|
||||
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
|
||||
/* Harmonic noise shaping */
|
||||
HarmShapeGain = HARMONIC_SHAPING;
|
||||
@@ -355,8 +342,6 @@ void silk_noise_shape_analysis_FLP(
|
||||
/* Smooth over subframes */
|
||||
/*************************/
|
||||
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
|
||||
psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );
|
||||
psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth;
|
||||
psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
|
||||
psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
|
||||
psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
|
||||
|
||||
@@ -159,7 +159,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
|
||||
|
||||
/* Low-pass filter */
|
||||
for( i = frame_length_4kHz - 1; i > 0; i-- ) {
|
||||
frame_4kHz[ i ] += frame_4kHz[ i - 1 ];
|
||||
frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -1,206 +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_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/*
|
||||
* Prefilter for finding Quantizer input signal
|
||||
*/
|
||||
static OPUS_INLINE void silk_prefilt_FLP(
|
||||
silk_prefilter_state_FLP *P, /* I/O state */
|
||||
silk_float st_res[], /* I */
|
||||
silk_float xw[], /* O */
|
||||
silk_float *HarmShapeFIR, /* I */
|
||||
silk_float Tilt, /* I */
|
||||
silk_float LF_MA_shp, /* I */
|
||||
silk_float LF_AR_shp, /* I */
|
||||
opus_int lag, /* I */
|
||||
opus_int length /* I */
|
||||
);
|
||||
|
||||
static void silk_warped_LPC_analysis_filter_FLP(
|
||||
silk_float state[], /* I/O State [order + 1] */
|
||||
silk_float res[], /* O Residual signal [length] */
|
||||
const silk_float coef[], /* I Coefficients [order] */
|
||||
const silk_float input[], /* I Input signal [length] */
|
||||
const silk_float lambda, /* I Warping factor */
|
||||
const opus_int length, /* I Length of input signal */
|
||||
const opus_int order /* I Filter order (even) */
|
||||
)
|
||||
{
|
||||
opus_int n, i;
|
||||
silk_float acc, tmp1, tmp2;
|
||||
|
||||
/* Order must be even */
|
||||
silk_assert( ( order & 1 ) == 0 );
|
||||
|
||||
for( n = 0; n < length; n++ ) {
|
||||
/* Output of lowpass section */
|
||||
tmp2 = state[ 0 ] + lambda * state[ 1 ];
|
||||
state[ 0 ] = input[ n ];
|
||||
/* Output of allpass section */
|
||||
tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
|
||||
state[ 1 ] = tmp2;
|
||||
acc = coef[ 0 ] * tmp2;
|
||||
/* Loop over allpass sections */
|
||||
for( i = 2; i < order; i += 2 ) {
|
||||
/* Output of allpass section */
|
||||
tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
|
||||
state[ i ] = tmp1;
|
||||
acc += coef[ i - 1 ] * tmp1;
|
||||
/* Output of allpass section */
|
||||
tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
|
||||
state[ i + 1 ] = tmp2;
|
||||
acc += coef[ i ] * tmp2;
|
||||
}
|
||||
state[ order ] = tmp1;
|
||||
acc += coef[ order - 1 ] * tmp1;
|
||||
res[ n ] = input[ n ] - acc;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* silk_prefilter. Main prefilter function
|
||||
*/
|
||||
void silk_prefilter_FLP(
|
||||
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
|
||||
const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
|
||||
silk_float xw[], /* O Weighted signal */
|
||||
const silk_float x[] /* I Speech signal */
|
||||
)
|
||||
{
|
||||
silk_prefilter_state_FLP *P = &psEnc->sPrefilt;
|
||||
opus_int j, k, lag;
|
||||
silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;
|
||||
silk_float B[ 2 ];
|
||||
const silk_float *AR1_shp;
|
||||
const silk_float *px;
|
||||
silk_float *pxw;
|
||||
silk_float HarmShapeFIR[ 3 ];
|
||||
silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
|
||||
|
||||
/* Set up pointers */
|
||||
px = x;
|
||||
pxw = xw;
|
||||
lag = P->lagPrev;
|
||||
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 = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );
|
||||
HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain;
|
||||
HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain;
|
||||
HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain;
|
||||
Tilt = psEncCtrl->Tilt[ k ];
|
||||
LF_MA_shp = psEncCtrl->LF_MA_shp[ k ];
|
||||
LF_AR_shp = psEncCtrl->LF_AR_shp[ k ];
|
||||
AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];
|
||||
|
||||
/* Short term FIR filtering */
|
||||
silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,
|
||||
(silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
|
||||
|
||||
/* Reduce (mainly) low frequencies during harmonic emphasis */
|
||||
B[ 0 ] = psEncCtrl->GainsPre[ k ];
|
||||
B[ 1 ] = -psEncCtrl->GainsPre[ k ] *
|
||||
( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );
|
||||
pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;
|
||||
for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
|
||||
pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];
|
||||
}
|
||||
P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
|
||||
|
||||
silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );
|
||||
|
||||
px += psEnc->sCmn.subfr_length;
|
||||
pxw += psEnc->sCmn.subfr_length;
|
||||
}
|
||||
P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
|
||||
}
|
||||
|
||||
/*
|
||||
* Prefilter for finding Quantizer input signal
|
||||
*/
|
||||
static OPUS_INLINE void silk_prefilt_FLP(
|
||||
silk_prefilter_state_FLP *P, /* I/O state */
|
||||
silk_float st_res[], /* I */
|
||||
silk_float xw[], /* O */
|
||||
silk_float *HarmShapeFIR, /* I */
|
||||
silk_float Tilt, /* I */
|
||||
silk_float LF_MA_shp, /* I */
|
||||
silk_float LF_AR_shp, /* I */
|
||||
opus_int lag, /* I */
|
||||
opus_int length /* I */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int idx, LTP_shp_buf_idx;
|
||||
silk_float n_Tilt, n_LF, n_LTP;
|
||||
silk_float sLF_AR_shp, sLF_MA_shp;
|
||||
silk_float *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 = P->sLF_AR_shp;
|
||||
sLF_MA_shp = P->sLF_MA_shp;
|
||||
|
||||
for( i = 0; i < length; i++ ) {
|
||||
if( lag > 0 ) {
|
||||
silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
|
||||
idx = lag + LTP_shp_buf_idx;
|
||||
n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
|
||||
n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
|
||||
n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
|
||||
} else {
|
||||
n_LTP = 0;
|
||||
}
|
||||
|
||||
n_Tilt = sLF_AR_shp * Tilt;
|
||||
n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;
|
||||
|
||||
sLF_AR_shp = st_res[ i ] - n_Tilt;
|
||||
sLF_MA_shp = sLF_AR_shp - n_LF;
|
||||
|
||||
LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
|
||||
LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;
|
||||
|
||||
xw[ i ] = sLF_MA_shp - n_LTP;
|
||||
}
|
||||
/* Copy temp variable back to state */
|
||||
P->sLF_AR_shp = sLF_AR_shp;
|
||||
P->sLF_MA_shp = sLF_MA_shp;
|
||||
P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
|
||||
}
|
||||
@@ -38,22 +38,23 @@ silk_float silk_schur_FLP( /* O returns residual energy
|
||||
)
|
||||
{
|
||||
opus_int k, n;
|
||||
silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
|
||||
silk_float Ctmp1, Ctmp2, rc_tmp;
|
||||
double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
|
||||
double Ctmp1, Ctmp2, rc_tmp;
|
||||
|
||||
silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
|
||||
silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
|
||||
|
||||
/* Copy correlations */
|
||||
for( k = 0; k < order+1; k++ ) {
|
||||
k = 0;
|
||||
do {
|
||||
C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];
|
||||
}
|
||||
} while( ++k <= order );
|
||||
|
||||
for( k = 0; k < order; k++ ) {
|
||||
/* Get reflection coefficient */
|
||||
rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );
|
||||
|
||||
/* Save the output */
|
||||
refl_coef[ k ] = rc_tmp;
|
||||
refl_coef[ k ] = (silk_float)rc_tmp;
|
||||
|
||||
/* Update correlations */
|
||||
for( n = 0; n < order - k; n++ ) {
|
||||
@@ -65,6 +66,5 @@ silk_float silk_schur_FLP( /* O returns residual energy
|
||||
}
|
||||
|
||||
/* Return residual energy */
|
||||
return C[ 0 ][ 1 ];
|
||||
return (silk_float)C[ 0 ][ 1 ];
|
||||
}
|
||||
|
||||
@@ -1,207 +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_FLP.h"
|
||||
#include "tuning_parameters.h"
|
||||
|
||||
/**********************************************************************
|
||||
* LDL Factorisation. Finds the upper triangular matrix L and the diagonal
|
||||
* Matrix D (only the diagonal elements returned in a vector)such that
|
||||
* the symmetric matric A is given by A = L*D*L'.
|
||||
**********************************************************************/
|
||||
static OPUS_INLINE void silk_LDL_FLP(
|
||||
silk_float *A, /* I/O Pointer to Symetric Square Matrix */
|
||||
opus_int M, /* I Size of Matrix */
|
||||
silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */
|
||||
silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */
|
||||
);
|
||||
|
||||
/**********************************************************************
|
||||
* Function to solve linear equation Ax = b, when A is a MxM lower
|
||||
* triangular matrix, with ones on the diagonal.
|
||||
**********************************************************************/
|
||||
static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
|
||||
const silk_float *L, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const silk_float *b, /* I b Vector */
|
||||
silk_float *x /* O x Vector */
|
||||
);
|
||||
|
||||
/**********************************************************************
|
||||
* Function to solve linear equation (A^T)x = b, when A is a MxM lower
|
||||
* triangular, with ones on the diagonal. (ie then A^T is upper triangular)
|
||||
**********************************************************************/
|
||||
static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
|
||||
const silk_float *L, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const silk_float *b, /* I b Vector */
|
||||
silk_float *x /* O x Vector */
|
||||
);
|
||||
|
||||
/**********************************************************************
|
||||
* Function to solve linear equation Ax = b, when A is a MxM
|
||||
* symmetric square matrix - using LDL factorisation
|
||||
**********************************************************************/
|
||||
void silk_solve_LDL_FLP(
|
||||
silk_float *A, /* I/O Symmetric square matrix, out: reg. */
|
||||
const opus_int M, /* I Size of matrix */
|
||||
const silk_float *b, /* I Pointer to b vector */
|
||||
silk_float *x /* O Pointer to x solution vector */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
silk_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ];
|
||||
silk_float T[ MAX_MATRIX_SIZE ];
|
||||
silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/
|
||||
|
||||
silk_assert( M <= MAX_MATRIX_SIZE );
|
||||
|
||||
/***************************************************
|
||||
Factorize A by LDL such that A = L*D*(L^T),
|
||||
where L is lower triangular with ones on diagonal
|
||||
****************************************************/
|
||||
silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv );
|
||||
|
||||
/****************************************************
|
||||
* substitute D*(L^T) = T. ie:
|
||||
L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b
|
||||
******************************************************/
|
||||
silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T );
|
||||
|
||||
/****************************************************
|
||||
D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is
|
||||
diagonal just multiply with 1/d_i
|
||||
****************************************************/
|
||||
for( i = 0; i < M; i++ ) {
|
||||
T[ i ] = T[ i ] * Dinv[ i ];
|
||||
}
|
||||
/****************************************************
|
||||
x = inv(L') * inv(D) * T
|
||||
*****************************************************/
|
||||
silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x );
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
|
||||
const silk_float *L, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const silk_float *b, /* I b Vector */
|
||||
silk_float *x /* O x Vector */
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
silk_float temp;
|
||||
const silk_float *ptr1;
|
||||
|
||||
for( i = M - 1; i >= 0; i-- ) {
|
||||
ptr1 = matrix_adr( L, 0, i, M );
|
||||
temp = 0;
|
||||
for( j = M - 1; j > i ; j-- ) {
|
||||
temp += ptr1[ j * M ] * x[ j ];
|
||||
}
|
||||
temp = b[ i ] - temp;
|
||||
x[ i ] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
|
||||
const silk_float *L, /* I Pointer to Lower Triangular Matrix */
|
||||
opus_int M, /* I Dim of Matrix equation */
|
||||
const silk_float *b, /* I b Vector */
|
||||
silk_float *x /* O x Vector */
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
silk_float temp;
|
||||
const silk_float *ptr1;
|
||||
|
||||
for( i = 0; i < M; i++ ) {
|
||||
ptr1 = matrix_adr( L, i, 0, M );
|
||||
temp = 0;
|
||||
for( j = 0; j < i; j++ ) {
|
||||
temp += ptr1[ j ] * x[ j ];
|
||||
}
|
||||
temp = b[ i ] - temp;
|
||||
x[ i ] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
static OPUS_INLINE void silk_LDL_FLP(
|
||||
silk_float *A, /* I/O Pointer to Symetric Square Matrix */
|
||||
opus_int M, /* I Size of Matrix */
|
||||
silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */
|
||||
silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */
|
||||
)
|
||||
{
|
||||
opus_int i, j, k, loop_count, err = 1;
|
||||
silk_float *ptr1, *ptr2;
|
||||
double temp, diag_min_value;
|
||||
silk_float v[ MAX_MATRIX_SIZE ] = { 0 }, D[ MAX_MATRIX_SIZE ]; /* temp arrays*/
|
||||
|
||||
silk_assert( M <= MAX_MATRIX_SIZE );
|
||||
|
||||
diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] );
|
||||
for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) {
|
||||
err = 0;
|
||||
for( j = 0; j < M; j++ ) {
|
||||
ptr1 = matrix_adr( L, j, 0, M );
|
||||
temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/
|
||||
for( i = 0; i < j; i++ ) {
|
||||
v[ i ] = ptr1[ i ] * D[ i ];
|
||||
temp -= ptr1[ i ] * v[ i ];
|
||||
}
|
||||
if( temp < diag_min_value ) {
|
||||
/* Badly conditioned matrix: add white noise and run again */
|
||||
temp = ( loop_count + 1 ) * diag_min_value - temp;
|
||||
for( i = 0; i < M; i++ ) {
|
||||
matrix_ptr( A, i, i, M ) += ( silk_float )temp;
|
||||
}
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
D[ j ] = ( silk_float )temp;
|
||||
Dinv[ j ] = ( silk_float )( 1.0f / temp );
|
||||
matrix_ptr( L, j, j, M ) = 1.0f;
|
||||
|
||||
ptr1 = matrix_adr( A, j, 0, M );
|
||||
ptr2 = matrix_adr( L, j + 1, 0, M);
|
||||
for( i = j + 1; i < M; i++ ) {
|
||||
temp = 0.0;
|
||||
for( k = 0; k < j; k++ ) {
|
||||
temp += ptr2[ k ] * v[ k ];
|
||||
}
|
||||
matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] );
|
||||
ptr2 += M; /* go to next column*/
|
||||
}
|
||||
}
|
||||
}
|
||||
silk_assert( err == 0 );
|
||||
}
|
||||
|
||||
@@ -42,32 +42,16 @@ extern "C"
|
||||
/********************************/
|
||||
typedef struct {
|
||||
opus_int8 LastGainIndex;
|
||||
silk_float HarmBoost_smth;
|
||||
silk_float HarmShapeGain_smth;
|
||||
silk_float Tilt_smth;
|
||||
} silk_shape_state_FLP;
|
||||
|
||||
/********************************/
|
||||
/* Prefilter state */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
silk_float sLTP_shp[ LTP_BUF_LENGTH ];
|
||||
silk_float sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
|
||||
opus_int sLTP_shp_buf_idx;
|
||||
silk_float sLF_AR_shp;
|
||||
silk_float sLF_MA_shp;
|
||||
silk_float sHarmHP;
|
||||
opus_int32 rand_seed;
|
||||
opus_int lagPrev;
|
||||
} silk_prefilter_state_FLP;
|
||||
|
||||
/********************************/
|
||||
/* Encoder state FLP */
|
||||
/********************************/
|
||||
typedef struct {
|
||||
silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */
|
||||
silk_shape_state_FLP sShape; /* Noise shaping state */
|
||||
silk_prefilter_state_FLP sPrefilt; /* Prefilter State */
|
||||
|
||||
/* Buffer for find pitch and noise shape analysis */
|
||||
silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
|
||||
@@ -86,12 +70,9 @@ typedef struct {
|
||||
opus_int pitchL[ MAX_NB_SUBFR ];
|
||||
|
||||
/* Noise shaping parameters */
|
||||
silk_float AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
silk_float AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
silk_float LF_MA_shp[ MAX_NB_SUBFR ];
|
||||
silk_float LF_AR_shp[ MAX_NB_SUBFR ];
|
||||
silk_float GainsPre[ MAX_NB_SUBFR ];
|
||||
silk_float HarmBoost[ MAX_NB_SUBFR ];
|
||||
silk_float Tilt[ MAX_NB_SUBFR ];
|
||||
silk_float HarmShapeGain[ MAX_NB_SUBFR ];
|
||||
silk_float Lambda;
|
||||
@@ -99,7 +80,6 @@ typedef struct {
|
||||
silk_float coding_quality;
|
||||
|
||||
/* Measures */
|
||||
silk_float sparseness;
|
||||
silk_float predGain;
|
||||
silk_float LTPredCodGain;
|
||||
silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
|
||||
|
||||
@@ -54,13 +54,14 @@ void silk_A2NLSF_FLP(
|
||||
void silk_NLSF2A_FLP(
|
||||
silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
|
||||
const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
|
||||
const opus_int LPC_order /* I LPC order */
|
||||
const opus_int LPC_order, /* I LPC order */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];
|
||||
|
||||
silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );
|
||||
silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch );
|
||||
|
||||
for( i = 0; i < LPC_order; i++ ) {
|
||||
pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
|
||||
@@ -102,14 +103,14 @@ void silk_NSQ_wrapper_FLP(
|
||||
)
|
||||
{
|
||||
opus_int i, j;
|
||||
opus_int32 x_Q3[ MAX_FRAME_LENGTH ];
|
||||
opus_int16 x16[ MAX_FRAME_LENGTH ];
|
||||
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
|
||||
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
|
||||
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
|
||||
opus_int LTP_scale_Q14;
|
||||
|
||||
/* Noise shaping parameters */
|
||||
opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
|
||||
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 Lambda_Q10;
|
||||
opus_int Tilt_Q14[ MAX_NB_SUBFR ];
|
||||
@@ -119,7 +120,7 @@ void silk_NSQ_wrapper_FLP(
|
||||
/* Noise shape parameters */
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {
|
||||
AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
|
||||
AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,16 +156,16 @@ void silk_NSQ_wrapper_FLP(
|
||||
|
||||
/* Convert input to fix */
|
||||
for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
|
||||
x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );
|
||||
x16[ i ] = silk_float2int( x[ i ] );
|
||||
}
|
||||
|
||||
/* Call NSQ */
|
||||
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||
AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
} else {
|
||||
silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||
AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
|
||||
AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,31 +173,35 @@ void silk_NSQ_wrapper_FLP(
|
||||
/* Floating-point Silk LTP quantiation wrapper */
|
||||
/***********************************************/
|
||||
void silk_quant_LTP_gains_FLP(
|
||||
silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */
|
||||
silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
|
||||
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
|
||||
opus_int8 *periodicity_index, /* O Periodicity index */
|
||||
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
|
||||
const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */
|
||||
const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */
|
||||
const opus_int lowComplexity, /* I Flag for low complexity */
|
||||
const opus_int nb_subfr, /* I number of subframes */
|
||||
silk_float *pred_gain_dB, /* O LTP prediction gain */
|
||||
const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
|
||||
const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
|
||||
const opus_int subfr_len, /* I Number of samples per subframe */
|
||||
const opus_int nb_subfr, /* I Number of subframes */
|
||||
int arch /* I Run-time architecture */
|
||||
)
|
||||
{
|
||||
opus_int i;
|
||||
opus_int i, pred_gain_dB_Q7;
|
||||
opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];
|
||||
opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ];
|
||||
opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
|
||||
opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ];
|
||||
|
||||
for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
|
||||
B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f );
|
||||
}
|
||||
for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
|
||||
W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f );
|
||||
XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f );
|
||||
}
|
||||
for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
|
||||
xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f );
|
||||
}
|
||||
|
||||
silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr, arch );
|
||||
silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch );
|
||||
|
||||
for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
|
||||
B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );
|
||||
}
|
||||
|
||||
*pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f );
|
||||
}
|
||||
Reference in new issue
Block a user