annotate src/opus-1.3/silk/NLSF_stabilize.c @ 79:91c729825bca pa_catalina

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