123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "SigProc_FIX.h"
- #include "define.h"
- #define QA 24
- #define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
- #define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
- static opus_int32 LPC_inverse_pred_gain_QA(
- opus_int32 A_QA[ SILK_MAX_ORDER_LPC ],
- const opus_int order
- )
- {
- opus_int k, n, mult2Q;
- opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
- invGain_Q30 = SILK_FIX_CONST( 1, 30 );
- for( k = order - 1; k > 0; k-- ) {
-
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
- return 0;
- }
-
- rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
-
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
- silk_assert( rc_mult1_Q30 > ( 1 << 15 ) );
- silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
-
-
- invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
- silk_assert( invGain_Q30 >= 0 );
- silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
-
- mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
- rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
-
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- opus_int64 tmp64;
- tmp1 = A_QA[ n ];
- tmp2 = A_QA[ k - n - 1 ];
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
- MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ n ] = ( opus_int32 )tmp64;
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
- MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
- }
- }
-
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
- return 0;
- }
-
- rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
-
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
-
-
- invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
- silk_assert( invGain_Q30 >= 0 );
- silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
- return invGain_Q30;
- }
- opus_int32 silk_LPC_inverse_pred_gain(
- const opus_int16 *A_Q12,
- const opus_int order
- )
- {
- opus_int k;
- opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
- opus_int32 DC_resp = 0;
-
- for( k = 0; k < order; k++ ) {
- DC_resp += (opus_int32)A_Q12[ k ];
- Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
- }
-
- if( DC_resp >= 4096 ) {
- return 0;
- }
- return LPC_inverse_pred_gain_QA( Atmp_QA, order );
- }
- #ifdef FIXED_POINT
- opus_int32 silk_LPC_inverse_pred_gain_Q24(
- const opus_int32 *A_Q24,
- const opus_int order
- )
- {
- opus_int k;
- opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
-
- for( k = 0; k < order; k++ ) {
- Atmp_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
- }
- return LPC_inverse_pred_gain_QA( Atmp_QA, order );
- }
- #endif
|