LCOV - code coverage report
Current view: top level - media/libopus/silk - NLSF_stabilize.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 40 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 further 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           0 : 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 parameters in the input vector              */
      51             : )
      52             : {
      53           0 :     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           0 :     silk_assert( NDeltaMin_Q15[L] >= 1 );
      59             : 
      60           0 :     for( loops = 0; loops < MAX_LOOPS; loops++ ) {
      61             :         /**************************/
      62             :         /* Find smallest distance */
      63             :         /**************************/
      64             :         /* First element */
      65           0 :         min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
      66           0 :         I = 0;
      67             :         /* Middle elements */
      68           0 :         for( i = 1; i <= L-1; i++ ) {
      69           0 :             diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
      70           0 :             if( diff_Q15 < min_diff_Q15 ) {
      71           0 :                 min_diff_Q15 = diff_Q15;
      72           0 :                 I = i;
      73             :             }
      74             :         }
      75             :         /* Last element */
      76           0 :         diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
      77           0 :         if( diff_Q15 < min_diff_Q15 ) {
      78           0 :             min_diff_Q15 = diff_Q15;
      79           0 :             I = L;
      80             :         }
      81             : 
      82             :         /***************************************************/
      83             :         /* Now check if the smallest distance non-negative */
      84             :         /***************************************************/
      85           0 :         if( min_diff_Q15 >= 0 ) {
      86           0 :             return;
      87             :         }
      88             : 
      89           0 :         if( I == 0 ) {
      90             :             /* Move away from lower limit */
      91           0 :             NLSF_Q15[0] = NDeltaMin_Q15[0];
      92             : 
      93           0 :         } else if( I == L) {
      94             :             /* Move away from higher limit */
      95           0 :             NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L];
      96             : 
      97             :         } else {
      98             :             /* Find the lower extreme for the location of the current center frequency */
      99           0 :             min_center_Q15 = 0;
     100           0 :             for( k = 0; k < I; k++ ) {
     101           0 :                 min_center_Q15 += NDeltaMin_Q15[k];
     102             :             }
     103           0 :             min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 );
     104             : 
     105             :             /* Find the upper extreme for the location of the current center frequency */
     106           0 :             max_center_Q15 = 1 << 15;
     107           0 :             for( k = L; k > I; k-- ) {
     108           0 :                 max_center_Q15 -= NDeltaMin_Q15[k];
     109             :             }
     110           0 :             max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 );
     111             : 
     112             :             /* Move apart, sorted by value, keeping the same center frequency */
     113           0 :             center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ),
     114             :                 min_center_Q15, max_center_Q15 );
     115           0 :             NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 );
     116           0 :             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           0 :     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           0 :         silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L );
     127             : 
     128             :         /* First NLSF should be no less than NDeltaMin[0] */
     129           0 :         NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
     130             : 
     131             :         /* Keep delta_min distance between the NLSFs */
     132           0 :         for( i = 1; i < L; i++ )
     133           0 :             NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
     134             : 
     135             :         /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
     136           0 :         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           0 :         for( i = L-2; i >= 0; i-- )
     140           0 :             NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
     141             :     }
     142             : }

Generated by: LCOV version 1.13