123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "SigProc_FIX.h"
- #define MAX_LOOPS 20
- void silk_NLSF_stabilize(
- opus_int16 *NLSF_Q15,
- const opus_int16 *NDeltaMin_Q15,
- const opus_int L
- )
- {
- opus_int i, I=0, k, loops;
- opus_int16 center_freq_Q15;
- opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15;
-
- silk_assert( NDeltaMin_Q15[L] >= 1 );
- for( loops = 0; loops < MAX_LOOPS; loops++ ) {
-
-
-
-
- min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
- I = 0;
-
- for( i = 1; i <= L-1; i++ ) {
- diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
- if( diff_Q15 < min_diff_Q15 ) {
- min_diff_Q15 = diff_Q15;
- I = i;
- }
- }
-
- diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
- if( diff_Q15 < min_diff_Q15 ) {
- min_diff_Q15 = diff_Q15;
- I = L;
- }
-
-
-
- if( min_diff_Q15 >= 0 ) {
- return;
- }
- if( I == 0 ) {
-
- NLSF_Q15[0] = NDeltaMin_Q15[0];
- } else if( I == L) {
-
- NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L];
- } else {
-
- min_center_Q15 = 0;
- for( k = 0; k < I; k++ ) {
- min_center_Q15 += NDeltaMin_Q15[k];
- }
- min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 );
-
- max_center_Q15 = 1 << 15;
- for( k = L; k > I; k-- ) {
- max_center_Q15 -= NDeltaMin_Q15[k];
- }
- max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 );
-
- center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ),
- min_center_Q15, max_center_Q15 );
- NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 );
- NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
- }
- }
-
- if( loops == MAX_LOOPS )
- {
-
-
-
- silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L );
-
- NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
-
- for( i = 1; i < L; i++ )
- NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
-
- NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
-
- for( i = L-2; i >= 0; i-- )
- NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
- }
- }
|