| OLD | NEW |
| (Empty) | |
| 1 /*********************************************************************** |
| 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved. |
| 3 Redistribution and use in source and binary forms, with or without |
| 4 modification, are permitted provided that the following conditions |
| 5 are met: |
| 6 - Redistributions of source code must retain the above copyright notice, |
| 7 this list of conditions and the following disclaimer. |
| 8 - Redistributions in binary form must reproduce the above copyright |
| 9 notice, this list of conditions and the following disclaimer in the |
| 10 documentation and/or other materials provided with the distribution. |
| 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the |
| 12 names of specific contributors, may be used to endorse or promote |
| 13 products derived from this software without specific prior written |
| 14 permission. |
| 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” |
| 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 25 POSSIBILITY OF SUCH DAMAGE. |
| 26 ***********************************************************************/ |
| 27 |
| 28 #ifdef HAVE_CONFIG_H |
| 29 #include "config.h" |
| 30 #endif |
| 31 |
| 32 /* NLSF stabilizer: */ |
| 33 /* */ |
| 34 /* - Moves NLSFs futher apart if they are too close */ |
| 35 /* - Moves NLSFs away from borders if they are too close */ |
| 36 /* - High effort to achieve a modification with minimum */ |
| 37 /* Euclidean distance to input vector */ |
| 38 /* - Output are sorted NLSF coefficients */ |
| 39 /* */ |
| 40 |
| 41 #include "SigProc_FIX.h" |
| 42 |
| 43 /* Constant Definitions */ |
| 44 #define MAX_LOOPS 20 |
| 45 |
| 46 /* NLSF stabilizer, for a single input data vector */ |
| 47 void silk_NLSF_stabilize( |
| 48 opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized
normalized LSF vector in Q15 [L] */ |
| 49 const opus_int16 *NDeltaMin_Q15, /* I Min distance vector
, NDeltaMin_Q15[L] must be >= 1 [L+1] */ |
| 50 const opus_int L /* I Number of NLSF para
meters in the input vector */ |
| 51 ) |
| 52 { |
| 53 opus_int i, I=0, k, loops; |
| 54 opus_int16 center_freq_Q15; |
| 55 opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15; |
| 56 |
| 57 /* This is necessary to ensure an output within range of a opus_int16 */ |
| 58 silk_assert( NDeltaMin_Q15[L] >= 1 ); |
| 59 |
| 60 for( loops = 0; loops < MAX_LOOPS; loops++ ) { |
| 61 /**************************/ |
| 62 /* Find smallest distance */ |
| 63 /**************************/ |
| 64 /* First element */ |
| 65 min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; |
| 66 I = 0; |
| 67 /* Middle elements */ |
| 68 for( i = 1; i <= L-1; i++ ) { |
| 69 diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); |
| 70 if( diff_Q15 < min_diff_Q15 ) { |
| 71 min_diff_Q15 = diff_Q15; |
| 72 I = i; |
| 73 } |
| 74 } |
| 75 /* Last element */ |
| 76 diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); |
| 77 if( diff_Q15 < min_diff_Q15 ) { |
| 78 min_diff_Q15 = diff_Q15; |
| 79 I = L; |
| 80 } |
| 81 |
| 82 /***************************************************/ |
| 83 /* Now check if the smallest distance non-negative */ |
| 84 /***************************************************/ |
| 85 if( min_diff_Q15 >= 0 ) { |
| 86 return; |
| 87 } |
| 88 |
| 89 if( I == 0 ) { |
| 90 /* Move away from lower limit */ |
| 91 NLSF_Q15[0] = NDeltaMin_Q15[0]; |
| 92 |
| 93 } else if( I == L) { |
| 94 /* Move away from higher limit */ |
| 95 NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L]; |
| 96 |
| 97 } else { |
| 98 /* Find the lower extreme for the location of the current center fre
quency */ |
| 99 min_center_Q15 = 0; |
| 100 for( k = 0; k < I; k++ ) { |
| 101 min_center_Q15 += NDeltaMin_Q15[k]; |
| 102 } |
| 103 min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 ); |
| 104 |
| 105 /* Find the upper extreme for the location of the current center fre
quency */ |
| 106 max_center_Q15 = 1 << 15; |
| 107 for( k = L; k > I; k-- ) { |
| 108 max_center_Q15 -= NDeltaMin_Q15[k]; |
| 109 } |
| 110 max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 ); |
| 111 |
| 112 /* Move apart, sorted by value, keeping the same center frequency */ |
| 113 center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opu
s_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ), |
| 114 min_center_Q15, max_center_Q15 ); |
| 115 NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 )
; |
| 116 NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; |
| 117 } |
| 118 } |
| 119 |
| 120 /* Safe and simple fall back method, which is less ideal than the above */ |
| 121 if( loops == MAX_LOOPS ) |
| 122 { |
| 123 /* Insertion sort (fast for already almost sorted arrays): */ |
| 124 /* Best case: O(n) for an already sorted array */ |
| 125 /* Worst case: O(n^2) for an inversely sorted array */ |
| 126 silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L ); |
| 127 |
| 128 /* First NLSF should be no less than NDeltaMin[0] */ |
| 129 NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); |
| 130 |
| 131 /* Keep delta_min distance between the NLSFs */ |
| 132 for( i = 1; i < L; i++ ) |
| 133 NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q
15[i] ); |
| 134 |
| 135 /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ |
| 136 NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L]
); |
| 137 |
| 138 /* Keep NDeltaMin distance between the NLSFs */ |
| 139 for( i = L-2; i >= 0; i-- ) |
| 140 NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q
15[i+1] ); |
| 141 } |
| 142 } |
| OLD | NEW |