LCOV - code coverage report
Current view: top level - media/libopus/silk/float - pitch_analysis_core_FLP.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 289 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 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             : /*****************************************************************************
      33             : * Pitch analyser function
      34             : ******************************************************************************/
      35             : #include "SigProc_FLP.h"
      36             : #include "SigProc_FIX.h"
      37             : #include "pitch_est_defines.h"
      38             : #include "pitch.h"
      39             : 
      40             : #define SCRATCH_SIZE        22
      41             : 
      42             : /************************************************************/
      43             : /* Internally used functions                                */
      44             : /************************************************************/
      45             : static void silk_P_Ana_calc_corr_st3(
      46             :     silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
      47             :     const silk_float    frame[],            /* I vector to correlate                                            */
      48             :     opus_int            start_lag,          /* I start lag                                                      */
      49             :     opus_int            sf_length,          /* I sub frame length                                               */
      50             :     opus_int            nb_subfr,           /* I number of subframes                                            */
      51             :     opus_int            complexity,         /* I Complexity setting                                             */
      52             :     int                 arch                /* I Run-time architecture                                          */
      53             : );
      54             : 
      55             : static void silk_P_Ana_calc_energy_st3(
      56             :     silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
      57             :     const silk_float    frame[],            /* I vector to correlate                                            */
      58             :     opus_int            start_lag,          /* I start lag                                                      */
      59             :     opus_int            sf_length,          /* I sub frame length                                               */
      60             :     opus_int            nb_subfr,           /* I number of subframes                                            */
      61             :     opus_int            complexity          /* I Complexity setting                                             */
      62             : );
      63             : 
      64             : /************************************************************/
      65             : /* CORE PITCH ANALYSIS FUNCTION                             */
      66             : /************************************************************/
      67           0 : opus_int silk_pitch_analysis_core_FLP(      /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */
      68             :     const silk_float    *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */
      69             :     opus_int            *pitch_out,         /* O    Pitch lag values [nb_subfr]                                 */
      70             :     opus_int16          *lagIndex,          /* O    Lag Index                                                   */
      71             :     opus_int8           *contourIndex,      /* O    Pitch contour Index                                         */
      72             :     silk_float          *LTPCorr,           /* I/O  Normalized correlation; input: value from previous frame    */
      73             :     opus_int            prevLag,            /* I    Last lag of previous frame; set to zero is unvoiced         */
      74             :     const silk_float    search_thres1,      /* I    First stage threshold for lag candidates 0 - 1              */
      75             :     const silk_float    search_thres2,      /* I    Final threshold for lag candidates 0 - 1                    */
      76             :     const opus_int      Fs_kHz,             /* I    sample frequency (kHz)                                      */
      77             :     const opus_int      complexity,         /* I    Complexity setting, 0-2, where 2 is highest                 */
      78             :     const opus_int      nb_subfr,           /* I    Number of 5 ms subframes                                    */
      79             :     int                 arch                /* I    Run-time architecture                                       */
      80             : )
      81             : {
      82             :     opus_int   i, k, d, j;
      83             :     silk_float frame_8kHz[  PE_MAX_FRAME_LENGTH_MS * 8 ];
      84             :     silk_float frame_4kHz[  PE_MAX_FRAME_LENGTH_MS * 4 ];
      85             :     opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ];
      86             :     opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ];
      87             :     opus_int32 filt_state[ 6 ];
      88             :     silk_float threshold, contour_bias;
      89             :     silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ];
      90             :     opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ];
      91             :     silk_float CC[ PE_NB_CBKS_STAGE2_EXT ];
      92             :     const silk_float *target_ptr, *basis_ptr;
      93             :     double    cross_corr, normalizer, energy, energy_tmp;
      94             :     opus_int   d_srch[ PE_D_SRCH_LENGTH ];
      95             :     opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ];
      96             :     opus_int   length_d_srch, length_d_comp;
      97             :     silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;
      98             :     opus_int   CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;
      99             :     opus_int   cbk_size;
     100             :     silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr;
     101             :     silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
     102             :     silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
     103             :     opus_int   lag_counter;
     104             :     opus_int   frame_length, frame_length_8kHz, frame_length_4kHz;
     105             :     opus_int   sf_length, sf_length_8kHz, sf_length_4kHz;
     106             :     opus_int   min_lag, min_lag_8kHz, min_lag_4kHz;
     107             :     opus_int   max_lag, max_lag_8kHz, max_lag_4kHz;
     108             :     opus_int   nb_cbk_search;
     109             :     const opus_int8 *Lag_CB_ptr;
     110             : 
     111             :     /* Check for valid sampling frequency */
     112           0 :     silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
     113             : 
     114             :     /* Check for valid complexity setting */
     115           0 :     silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
     116           0 :     silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
     117             : 
     118           0 :     silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
     119           0 :     silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
     120             : 
     121             :     /* Set up frame lengths max / min lag for the sampling frequency */
     122           0 :     frame_length      = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
     123           0 :     frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
     124           0 :     frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
     125           0 :     sf_length         = PE_SUBFR_LENGTH_MS * Fs_kHz;
     126           0 :     sf_length_4kHz    = PE_SUBFR_LENGTH_MS * 4;
     127           0 :     sf_length_8kHz    = PE_SUBFR_LENGTH_MS * 8;
     128           0 :     min_lag           = PE_MIN_LAG_MS * Fs_kHz;
     129           0 :     min_lag_4kHz      = PE_MIN_LAG_MS * 4;
     130           0 :     min_lag_8kHz      = PE_MIN_LAG_MS * 8;
     131           0 :     max_lag           = PE_MAX_LAG_MS * Fs_kHz - 1;
     132           0 :     max_lag_4kHz      = PE_MAX_LAG_MS * 4;
     133           0 :     max_lag_8kHz      = PE_MAX_LAG_MS * 8 - 1;
     134             : 
     135             :     /* Resample from input sampled at Fs_kHz to 8 kHz */
     136           0 :     if( Fs_kHz == 16 ) {
     137             :         /* Resample to 16 -> 8 khz */
     138             :         opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ];
     139           0 :         silk_float2short_array( frame_16_FIX, frame, frame_length );
     140           0 :         silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
     141           0 :         silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length );
     142           0 :         silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
     143           0 :     } else if( Fs_kHz == 12 ) {
     144             :         /* Resample to 12 -> 8 khz */
     145             :         opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ];
     146           0 :         silk_float2short_array( frame_12_FIX, frame, frame_length );
     147           0 :         silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
     148           0 :         silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
     149           0 :         silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
     150             :     } else {
     151           0 :         silk_assert( Fs_kHz == 8 );
     152           0 :         silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
     153             :     }
     154             : 
     155             :     /* Decimate again to 4 kHz */
     156           0 :     silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
     157           0 :     silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz );
     158           0 :     silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz );
     159             : 
     160             :     /* Low-pass filter */
     161           0 :     for( i = frame_length_4kHz - 1; i > 0; i-- ) {
     162           0 :         frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
     163             :     }
     164             : 
     165             :     /******************************************************************************
     166             :     * FIRST STAGE, operating in 4 khz
     167             :     ******************************************************************************/
     168           0 :     silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5));
     169           0 :     target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
     170           0 :     for( k = 0; k < nb_subfr >> 1; k++ ) {
     171             :         /* Check that we are within range of the array */
     172           0 :         silk_assert( target_ptr >= frame_4kHz );
     173           0 :         silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
     174             : 
     175           0 :         basis_ptr = target_ptr - min_lag_4kHz;
     176             : 
     177             :         /* Check that we are within range of the array */
     178           0 :         silk_assert( basis_ptr >= frame_4kHz );
     179           0 :         silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
     180             : 
     181           0 :         celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
     182             : 
     183             :         /* Calculate first vector products before loop */
     184           0 :         cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];
     185           0 :         normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
     186           0 :                      silk_energy_FLP( basis_ptr,  sf_length_8kHz ) +
     187           0 :                      sf_length_8kHz * 4000.0f;
     188             : 
     189           0 :         C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );
     190             : 
     191             :         /* From now on normalizer is computed recursively */
     192           0 :         for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
     193           0 :             basis_ptr--;
     194             : 
     195             :             /* Check that we are within range of the array */
     196           0 :             silk_assert( basis_ptr >= frame_4kHz );
     197           0 :             silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
     198             : 
     199           0 :             cross_corr = xcorr[ max_lag_4kHz - d ];
     200             : 
     201             :             /* Add contribution of new sample and remove contribution from oldest sample */
     202           0 :             normalizer +=
     203           0 :                 basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] -
     204           0 :                 basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ];
     205           0 :             C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer );
     206             :         }
     207             :         /* Update target pointer */
     208           0 :         target_ptr += sf_length_8kHz;
     209             :     }
     210             : 
     211             :     /* Apply short-lag bias */
     212           0 :     for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
     213           0 :         C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;
     214             :     }
     215             : 
     216             :     /* Sort */
     217           0 :     length_d_srch = 4 + 2 * complexity;
     218           0 :     silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
     219           0 :     silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
     220             : 
     221             :     /* Escape if correlation is very low already here */
     222           0 :     Cmax = C[ 0 ][ min_lag_4kHz ];
     223           0 :     if( Cmax < 0.2f ) {
     224           0 :         silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
     225           0 :         *LTPCorr      = 0.0f;
     226           0 :         *lagIndex     = 0;
     227           0 :         *contourIndex = 0;
     228           0 :         return 1;
     229             :     }
     230             : 
     231           0 :     threshold = search_thres1 * Cmax;
     232           0 :     for( i = 0; i < length_d_srch; i++ ) {
     233             :         /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
     234           0 :         if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
     235           0 :             d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
     236             :         } else {
     237           0 :             length_d_srch = i;
     238           0 :             break;
     239             :         }
     240             :     }
     241           0 :     silk_assert( length_d_srch > 0 );
     242             : 
     243           0 :     for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
     244           0 :         d_comp[ i ] = 0;
     245             :     }
     246           0 :     for( i = 0; i < length_d_srch; i++ ) {
     247           0 :         d_comp[ d_srch[ i ] ] = 1;
     248             :     }
     249             : 
     250             :     /* Convolution */
     251           0 :     for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
     252           0 :         d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
     253             :     }
     254             : 
     255           0 :     length_d_srch = 0;
     256           0 :     for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
     257           0 :         if( d_comp[ i + 1 ] > 0 ) {
     258           0 :             d_srch[ length_d_srch ] = i;
     259           0 :             length_d_srch++;
     260             :         }
     261             :     }
     262             : 
     263             :     /* Convolution */
     264           0 :     for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
     265           0 :         d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
     266             :     }
     267             : 
     268           0 :     length_d_comp = 0;
     269           0 :     for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
     270           0 :         if( d_comp[ i ] > 0 ) {
     271           0 :             d_comp[ length_d_comp ] = (opus_int16)( i - 2 );
     272           0 :             length_d_comp++;
     273             :         }
     274             :     }
     275             : 
     276             :     /**********************************************************************************
     277             :     ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
     278             :     *************************************************************************************/
     279             :     /*********************************************************************************
     280             :     * Find energy of each subframe projected onto its history, for a range of delays
     281             :     *********************************************************************************/
     282           0 :     silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float));
     283             : 
     284           0 :     if( Fs_kHz == 8 ) {
     285           0 :         target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ];
     286             :     } else {
     287           0 :         target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
     288             :     }
     289           0 :     for( k = 0; k < nb_subfr; k++ ) {
     290           0 :         energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0;
     291           0 :         for( j = 0; j < length_d_comp; j++ ) {
     292           0 :             d = d_comp[ j ];
     293           0 :             basis_ptr = target_ptr - d;
     294           0 :             cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );
     295           0 :             if( cross_corr > 0.0f ) {
     296           0 :                 energy = silk_energy_FLP( basis_ptr, sf_length_8kHz );
     297           0 :                 C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) );
     298             :             } else {
     299           0 :                 C[ k ][ d ] = 0.0f;
     300             :             }
     301             :         }
     302           0 :         target_ptr += sf_length_8kHz;
     303             :     }
     304             : 
     305             :     /* search over lag range and lags codebook */
     306             :     /* scale factor for lag codebook, as a function of center lag */
     307             : 
     308           0 :     CCmax   = 0.0f; /* This value doesn't matter */
     309           0 :     CCmax_b = -1000.0f;
     310             : 
     311           0 :     CBimax = 0; /* To avoid returning undefined lag values */
     312           0 :     lag = -1;   /* To check if lag with strong enough correlation has been found */
     313             : 
     314           0 :     if( prevLag > 0 ) {
     315           0 :         if( Fs_kHz == 12 ) {
     316           0 :             prevLag = silk_LSHIFT( prevLag, 1 ) / 3;
     317           0 :         } else if( Fs_kHz == 16 ) {
     318           0 :             prevLag = silk_RSHIFT( prevLag, 1 );
     319             :         }
     320           0 :         prevLag_log2 = silk_log2( (silk_float)prevLag );
     321             :     } else {
     322           0 :         prevLag_log2 = 0;
     323             :     }
     324             : 
     325             :     /* Set up stage 2 codebook based on number of subframes */
     326           0 :     if( nb_subfr == PE_MAX_NB_SUBFR ) {
     327           0 :         cbk_size   = PE_NB_CBKS_STAGE2_EXT;
     328           0 :         Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
     329           0 :         if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
     330             :             /* If input is 8 khz use a larger codebook here because it is last stage */
     331           0 :             nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
     332             :         } else {
     333           0 :             nb_cbk_search = PE_NB_CBKS_STAGE2;
     334             :         }
     335             :     } else {
     336           0 :         cbk_size       = PE_NB_CBKS_STAGE2_10MS;
     337           0 :         Lag_CB_ptr     = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
     338           0 :         nb_cbk_search  = PE_NB_CBKS_STAGE2_10MS;
     339             :     }
     340             : 
     341           0 :     for( k = 0; k < length_d_srch; k++ ) {
     342           0 :         d = d_srch[ k ];
     343           0 :         for( j = 0; j < nb_cbk_search; j++ ) {
     344           0 :             CC[j] = 0.0f;
     345           0 :             for( i = 0; i < nb_subfr; i++ ) {
     346             :                 /* Try all codebooks */
     347           0 :                 CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
     348             :             }
     349             :         }
     350             :         /* Find best codebook */
     351           0 :         CCmax_new  = -1000.0f;
     352           0 :         CBimax_new = 0;
     353           0 :         for( i = 0; i < nb_cbk_search; i++ ) {
     354           0 :             if( CC[ i ] > CCmax_new ) {
     355           0 :                 CCmax_new = CC[ i ];
     356           0 :                 CBimax_new = i;
     357             :             }
     358             :         }
     359             : 
     360             :         /* Bias towards shorter lags */
     361           0 :         lag_log2 = silk_log2( (silk_float)d );
     362           0 :         CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2;
     363             : 
     364             :         /* Bias towards previous lag */
     365           0 :         if( prevLag > 0 ) {
     366           0 :             delta_lag_log2_sqr = lag_log2 - prevLag_log2;
     367           0 :             delta_lag_log2_sqr *= delta_lag_log2_sqr;
     368           0 :             CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f );
     369             :         }
     370             : 
     371           0 :         if( CCmax_new_b > CCmax_b &&                /* Find maximum biased correlation                  */
     372           0 :             CCmax_new > nb_subfr * search_thres2    /* Correlation needs to be high enough to be voiced */
     373             :         ) {
     374           0 :             CCmax_b = CCmax_new_b;
     375           0 :             CCmax   = CCmax_new;
     376           0 :             lag     = d;
     377           0 :             CBimax  = CBimax_new;
     378             :         }
     379             :     }
     380             : 
     381           0 :     if( lag == -1 ) {
     382             :         /* No suitable candidate found */
     383           0 :         silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) );
     384           0 :         *LTPCorr      = 0.0f;
     385           0 :         *lagIndex     = 0;
     386           0 :         *contourIndex = 0;
     387           0 :         return 1;
     388             :     }
     389             : 
     390             :     /* Output normalized correlation */
     391           0 :     *LTPCorr = (silk_float)( CCmax / nb_subfr );
     392           0 :     silk_assert( *LTPCorr >= 0.0f );
     393             : 
     394           0 :     if( Fs_kHz > 8 ) {
     395             :         /* Search in original signal */
     396             : 
     397             :         /* Compensate for decimation */
     398           0 :         silk_assert( lag == silk_SAT16( lag ) );
     399           0 :         if( Fs_kHz == 12 ) {
     400           0 :             lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 );
     401             :         } else { /* Fs_kHz == 16 */
     402           0 :             lag = silk_LSHIFT( lag, 1 );
     403             :         }
     404             : 
     405           0 :         lag = silk_LIMIT_int( lag, min_lag, max_lag );
     406           0 :         start_lag = silk_max_int( lag - 2, min_lag );
     407           0 :         end_lag   = silk_min_int( lag + 2, max_lag );
     408           0 :         lag_new   = lag;                                    /* to avoid undefined lag */
     409           0 :         CBimax    = 0;                                      /* to avoid undefined lag */
     410             : 
     411           0 :         CCmax = -1000.0f;
     412             : 
     413             :         /* Calculate the correlations and energies needed in stage 3 */
     414           0 :         silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
     415           0 :         silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity );
     416             : 
     417           0 :         lag_counter = 0;
     418           0 :         silk_assert( lag == silk_SAT16( lag ) );
     419           0 :         contour_bias = PE_FLATCONTOUR_BIAS / lag;
     420             : 
     421             :         /* Set up cbk parameters according to complexity setting and frame length */
     422           0 :         if( nb_subfr == PE_MAX_NB_SUBFR ) {
     423           0 :             nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
     424           0 :             cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     425           0 :             Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];
     426             :         } else {
     427           0 :             nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
     428           0 :             cbk_size      = PE_NB_CBKS_STAGE3_10MS;
     429           0 :             Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
     430             :         }
     431             : 
     432           0 :         target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
     433           0 :         energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0;
     434           0 :         for( d = start_lag; d <= end_lag; d++ ) {
     435           0 :             for( j = 0; j < nb_cbk_search; j++ ) {
     436           0 :                 cross_corr = 0.0;
     437           0 :                 energy = energy_tmp;
     438           0 :                 for( k = 0; k < nb_subfr; k++ ) {
     439           0 :                     cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];
     440           0 :                     energy     +=   energies_st3[ k ][ j ][ lag_counter ];
     441             :                 }
     442           0 :                 if( cross_corr > 0.0 ) {
     443           0 :                     CCmax_new = (silk_float)( 2 * cross_corr / energy );
     444             :                     /* Reduce depending on flatness of contour */
     445           0 :                     CCmax_new *= 1.0f - contour_bias * j;
     446             :                 } else {
     447           0 :                     CCmax_new = 0.0f;
     448             :                 }
     449             : 
     450           0 :                 if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
     451           0 :                     CCmax   = CCmax_new;
     452           0 :                     lag_new = d;
     453           0 :                     CBimax  = j;
     454             :                 }
     455             :             }
     456           0 :             lag_counter++;
     457             :         }
     458             : 
     459           0 :         for( k = 0; k < nb_subfr; k++ ) {
     460           0 :             pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
     461           0 :             pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
     462             :         }
     463           0 :         *lagIndex = (opus_int16)( lag_new - min_lag );
     464           0 :         *contourIndex = (opus_int8)CBimax;
     465             :     } else {        /* Fs_kHz == 8 */
     466             :         /* Save Lags */
     467           0 :         for( k = 0; k < nb_subfr; k++ ) {
     468           0 :             pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
     469           0 :             pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );
     470             :         }
     471           0 :         *lagIndex = (opus_int16)( lag - min_lag_8kHz );
     472           0 :         *contourIndex = (opus_int8)CBimax;
     473             :     }
     474           0 :     silk_assert( *lagIndex >= 0 );
     475             :     /* return as voiced */
     476           0 :     return 0;
     477             : }
     478             : 
     479             : /***********************************************************************
     480             :  * Calculates the correlations used in stage 3 search. In order to cover
     481             :  * the whole lag codebook for all the searched offset lags (lag +- 2),
     482             :  * the following correlations are needed in each sub frame:
     483             :  *
     484             :  * sf1: lag range [-8,...,7] total 16 correlations
     485             :  * sf2: lag range [-4,...,4] total 9 correlations
     486             :  * sf3: lag range [-3,....4] total 8 correltions
     487             :  * sf4: lag range [-6,....8] total 15 correlations
     488             :  *
     489             :  * In total 48 correlations. The direct implementation computed in worst
     490             :  * case 4*12*5 = 240 correlations, but more likely around 120.
     491             :  ***********************************************************************/
     492           0 : static void silk_P_Ana_calc_corr_st3(
     493             :     silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
     494             :     const silk_float    frame[],            /* I vector to correlate                                            */
     495             :     opus_int            start_lag,          /* I start lag                                                      */
     496             :     opus_int            sf_length,          /* I sub frame length                                               */
     497             :     opus_int            nb_subfr,           /* I number of subframes                                            */
     498             :     opus_int            complexity,         /* I Complexity setting                                             */
     499             :     int                 arch                /* I Run-time architecture                                          */
     500             : )
     501             : {
     502             :     const silk_float *target_ptr;
     503             :     opus_int   i, j, k, lag_counter, lag_low, lag_high;
     504             :     opus_int   nb_cbk_search, delta, idx, cbk_size;
     505             :     silk_float scratch_mem[ SCRATCH_SIZE ];
     506             :     opus_val32 xcorr[ SCRATCH_SIZE ];
     507             :     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
     508             : 
     509           0 :     silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
     510           0 :     silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
     511             : 
     512           0 :     if( nb_subfr == PE_MAX_NB_SUBFR ) {
     513           0 :         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
     514           0 :         Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];
     515           0 :         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
     516           0 :         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     517             :     } else {
     518           0 :         silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
     519           0 :         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
     520           0 :         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
     521           0 :         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
     522           0 :         cbk_size      = PE_NB_CBKS_STAGE3_10MS;
     523             :     }
     524             : 
     525           0 :     target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
     526           0 :     for( k = 0; k < nb_subfr; k++ ) {
     527           0 :         lag_counter = 0;
     528             : 
     529             :         /* Calculate the correlations for each subframe */
     530           0 :         lag_low  = matrix_ptr( Lag_range_ptr, k, 0, 2 );
     531           0 :         lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
     532           0 :         silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
     533           0 :         celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch );
     534           0 :         for( j = lag_low; j <= lag_high; j++ ) {
     535           0 :             silk_assert( lag_counter < SCRATCH_SIZE );
     536           0 :             scratch_mem[ lag_counter ] = xcorr[ lag_high - j ];
     537           0 :             lag_counter++;
     538             :         }
     539             : 
     540           0 :         delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
     541           0 :         for( i = 0; i < nb_cbk_search; i++ ) {
     542             :             /* Fill out the 3 dim array that stores the correlations for */
     543             :             /* each code_book vector for each start lag */
     544           0 :             idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
     545           0 :             for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
     546           0 :                 silk_assert( idx + j < SCRATCH_SIZE );
     547           0 :                 silk_assert( idx + j < lag_counter );
     548           0 :                 cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
     549             :             }
     550             :         }
     551           0 :         target_ptr += sf_length;
     552             :     }
     553           0 : }
     554             : 
     555             : /********************************************************************/
     556             : /* Calculate the energies for first two subframes. The energies are */
     557             : /* calculated recursively.                                          */
     558             : /********************************************************************/
     559           0 : static void silk_P_Ana_calc_energy_st3(
     560             :     silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
     561             :     const silk_float    frame[],            /* I vector to correlate                                            */
     562             :     opus_int            start_lag,          /* I start lag                                                      */
     563             :     opus_int            sf_length,          /* I sub frame length                                               */
     564             :     opus_int            nb_subfr,           /* I number of subframes                                            */
     565             :     opus_int            complexity          /* I Complexity setting                                             */
     566             : )
     567             : {
     568             :     const silk_float *target_ptr, *basis_ptr;
     569             :     double    energy;
     570             :     opus_int   k, i, j, lag_counter;
     571             :     opus_int   nb_cbk_search, delta, idx, cbk_size, lag_diff;
     572             :     silk_float scratch_mem[ SCRATCH_SIZE ];
     573             :     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
     574             : 
     575           0 :     silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
     576           0 :     silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
     577             : 
     578           0 :     if( nb_subfr == PE_MAX_NB_SUBFR ) {
     579           0 :         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
     580           0 :         Lag_CB_ptr    = &silk_CB_lags_stage3[ 0 ][ 0 ];
     581           0 :         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
     582           0 :         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     583             :     } else {
     584           0 :         silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
     585           0 :         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
     586           0 :         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
     587           0 :         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
     588           0 :         cbk_size      = PE_NB_CBKS_STAGE3_10MS;
     589             :     }
     590             : 
     591           0 :     target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
     592           0 :     for( k = 0; k < nb_subfr; k++ ) {
     593           0 :         lag_counter = 0;
     594             : 
     595             :         /* Calculate the energy for first lag */
     596           0 :         basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
     597           0 :         energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;
     598           0 :         silk_assert( energy >= 0.0 );
     599           0 :         scratch_mem[lag_counter] = (silk_float)energy;
     600           0 :         lag_counter++;
     601             : 
     602           0 :         lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) -  matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
     603           0 :         for( i = 1; i < lag_diff; i++ ) {
     604             :             /* remove part outside new window */
     605           0 :             energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i];
     606           0 :             silk_assert( energy >= 0.0 );
     607             : 
     608             :             /* add part that comes into window */
     609           0 :             energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ];
     610           0 :             silk_assert( energy >= 0.0 );
     611           0 :             silk_assert( lag_counter < SCRATCH_SIZE );
     612           0 :             scratch_mem[lag_counter] = (silk_float)energy;
     613           0 :             lag_counter++;
     614             :         }
     615             : 
     616           0 :         delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
     617           0 :         for( i = 0; i < nb_cbk_search; i++ ) {
     618             :             /* Fill out the 3 dim array that stores the correlations for    */
     619             :             /* each code_book vector for each start lag                     */
     620           0 :             idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
     621           0 :             for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
     622           0 :                 silk_assert( idx + j < SCRATCH_SIZE );
     623           0 :                 silk_assert( idx + j < lag_counter );
     624           0 :                 energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
     625           0 :                 silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
     626             :             }
     627             :         }
     628           0 :         target_ptr += sf_length;
     629             :     }
     630           0 : }

Generated by: LCOV version 1.13