LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_cng_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 180 183 98.4 %
Date: 2025-05-23 08:37:30 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include <math.h>
      36             : #include "cnst.h"
      37             : #include "rom_enc.h"
      38             : #include "rom_com.h"
      39             : #include "prot.h"
      40             : #include "ivas_prot.h"
      41             : #include "ivas_cnst.h"
      42             : #include "ivas_rom_com.h"
      43             : #ifdef DEBUGGING
      44             : #include "debug.h"
      45             : #endif
      46             : #include "wmc_auto.h"
      47             : 
      48             : 
      49             : /*-------------------------------------------------------------------
      50             :  * Local constants
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53             : #define COH_FADE_MAX     4
      54             : #define COH_FADE_UPDATES 2
      55             : 
      56             : 
      57             : /*---------------------------------------------------------------
      58             :  * stereo_dft_enc_sid_calc_coh()
      59             :  *
      60             :  * Encodes the coherence in SID frames
      61             :  * ---------------------------------------------------------------*/
      62             : 
      63        1445 : void stereo_dft_enc_sid_calc_coh(
      64             :     STEREO_DFT_ENC_DATA_HANDLE hStereoDft,               /* i/o: DFT stereo handle           */
      65             :     float prev_cohBand[2 * ( STEREO_DFT_BAND_MAX / 2 )], /* i/o: Previous coherence   */
      66             :     int16_t *td_active,                                  /* i/o: TD stereo mode indicator    */
      67             :     int16_t *first_SID,                                  /* i/o: First SID indicator         */
      68             :     float *cohBand                                       /* i/o: Coherence per band          */
      69             : )
      70             : {
      71             :     int16_t b, k;
      72             :     float coh_weight;
      73             :     float coh_weight_sum;
      74             :     float xspec_scale;
      75             :     /* Cluster the coherence into bands using a weighted average. The coherence is weighted with the energy spectrum of the
      76             :        mixdown signal.  */
      77        9799 :     for ( b = 0; b < hStereoDft->nbands; b++ )
      78             :     {
      79        8354 :         cohBand[b] = 0;
      80        8354 :         coh_weight_sum = 0;
      81             : 
      82        8354 :         if ( hStereoDft->coh_fade_counter == 0 && !*first_SID )
      83             :         {
      84      213903 :             for ( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
      85             :             {
      86      211800 :                 xspec_scale = sqrtf( ( prev_cohBand[b] * ( hStereoDft->Spd_L_smooth[k] * hStereoDft->Spd_R_smooth[k] ) ) / ( hStereoDft->xspec_smooth[2 * k] * hStereoDft->xspec_smooth[2 * k] + hStereoDft->xspec_smooth[2 * k + 1] * hStereoDft->xspec_smooth[2 * k + 1] + EPSILON ) );
      87      211800 :                 hStereoDft->xspec_smooth[2 * k] *= xspec_scale;
      88      211800 :                 hStereoDft->xspec_smooth[2 * k + 1] *= xspec_scale;
      89             :             }
      90             : 
      91        2103 :             cohBand[b] = prev_cohBand[b];
      92             :         }
      93             :         else
      94             :         {
      95      616686 :             for ( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
      96             :             {
      97      610435 :                 coh_weight = hStereoDft->DFT[0][2 * k] * hStereoDft->DFT[0][2 * k] + hStereoDft->DFT[0][2 * k + 1] * hStereoDft->DFT[0][2 * k + 1];
      98      610435 :                 cohBand[b] += coh_weight * ( ( hStereoDft->xspec_smooth[2 * k] * hStereoDft->xspec_smooth[2 * k] + hStereoDft->xspec_smooth[2 * k + 1] * hStereoDft->xspec_smooth[2 * k + 1] ) / ( hStereoDft->Spd_L_smooth[k] * hStereoDft->Spd_R_smooth[k] + EPSILON ) );
      99      610435 :                 coh_weight_sum += coh_weight;
     100             :             }
     101        6251 :             if ( coh_weight_sum > 0 )
     102             :             {
     103        6224 :                 cohBand[b] = cohBand[b] / coh_weight_sum;
     104             :             }
     105             :         }
     106             :     }
     107             : 
     108        1445 :     if ( *first_SID )
     109             :     {
     110          27 :         mvr2r( cohBand, prev_cohBand, hStereoDft->nbands );
     111          27 :         mvr2r( prev_cohBand, &( prev_cohBand[STEREO_DFT_BAND_MAX / 2] ), hStereoDft->nbands );
     112          27 :         *first_SID = 0;
     113             :     }
     114             : 
     115        1445 :     if ( hStereoDft->coh_fade_counter < COH_FADE_MAX && ( *td_active || hStereoDft->currentNumUpdates < COH_FADE_UPDATES ) )
     116             :     {
     117         224 :         for ( b = 0; b < hStereoDft->nbands; b++ )
     118             :         {
     119         191 :             cohBand[b] = ( cohBand[b] * hStereoDft->coh_fade_counter + prev_cohBand[b] * ( COH_FADE_MAX - hStereoDft->coh_fade_counter ) ) / COH_FADE_MAX;
     120             :         }
     121          33 :         hStereoDft->coh_fade_counter++;
     122          33 :         if ( hStereoDft->coh_fade_counter > 0 )
     123             :         {
     124          33 :             mvr2r( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
     125             :         }
     126          33 :         mvr2r( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
     127             :     }
     128             :     else
     129             :     {
     130        1412 :         if ( hStereoDft->coh_fade_counter > 0 )
     131             :         {
     132        1058 :             mvr2r( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
     133             :         }
     134        1412 :         mvr2r( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
     135        1412 :         hStereoDft->coh_fade_counter = COH_FADE_MAX;
     136        1412 :         *td_active = 0;
     137             :     }
     138             : 
     139        1445 :     return;
     140             : }
     141             : 
     142             : 
     143             : /*---------------------------------------------------------------
     144             :  * stereo_dft_enc_sid_coh()
     145             :  *
     146             :  * Encodes the coherence in SID frames
     147             :  * ---------------------------------------------------------------*/
     148             : 
     149        1445 : void stereo_dft_enc_sid_coh(
     150             :     BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle             */
     151             :     float *mem_cohBand,    /* i/o: Coherence memory             */
     152             :     const int16_t nbands,  /* i  : number of DFT stereo bands   */
     153             :     int16_t *nb_bits,      /* i/o: number of bits written       */
     154             :     float *cohBand         /* i/o: Coherence per band           */
     155             : )
     156             : {
     157             :     int16_t b, k;
     158             :     int16_t zeropad;
     159             :     int16_t nr_of_sid_stereo_bits;
     160             :     int16_t coh_pred_index;
     161             :     float min_pred_err;
     162             :     float pred_err;
     163             :     int16_t res_index;
     164             :     int16_t i;
     165             :     float tmp;
     166             :     const float *pptr;
     167             :     float pred;
     168             :     float cohBandq[STEREO_DFT_BAND_MAX / 2]; /* Reconstructed coherence values for intra-frame prediction */
     169             :     const float *alphaptr;
     170             :     int16_t nbbits_test;
     171             :     int16_t prev_nbbits_test;
     172             :     int16_t alpha_step;
     173             :     int16_t alpha_level;
     174             :     int16_t n;
     175             : 
     176        1445 :     nr_of_sid_stereo_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
     177        1445 :     zeropad = 0;
     178             : 
     179             :     /* Encode coherence vector. Find best fixed predictor by minimizing prediction error on input vector.
     180             :        The prediction is formed by a linear combination of the previous values
     181             :        in the vector. Hence, prediction is only done for coefficient 1 and up.
     182             :        If not enough bits for at least one bit for encoding prediction
     183             :        residual then skip the coding and write zeroes to the bitstream if needed.
     184             :        In this case the decoder will set alpha to 0, i.e. reuse previous coherence */
     185             : 
     186        1445 :     if ( ( nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS - STEREO_DFT_PRED_NBITS ) > 0 )
     187             :     {
     188        1445 :         min_pred_err = 1e6f;
     189        1445 :         coh_pred_index = -1;
     190        1445 :         pptr = dft_cng_coh_pred[0];
     191        7225 :         for ( k = 0; k < STEREO_DFT_N_COH_PRED; k++ )
     192             :         {
     193        5780 :             pred_err = 0;
     194       33416 :             for ( b = 1; b < nbands; b++ ) /* Set b=1 to skip first coefficient (same error would otherwise be added for all predictors: (cohBand[0] - 0).^2) */
     195             :             {
     196       27636 :                 pred = 0;
     197      108016 :                 for ( i = 0; i < b; i++ )
     198             :                 {
     199       80380 :                     pred += ( *pptr++ ) * cohBand[i];
     200             :                 }
     201       27636 :                 tmp = cohBand[b] - pred;
     202       27636 :                 pred_err += tmp * tmp;
     203             :             }
     204        5780 :             if ( pred_err < min_pred_err ) /* Store best candidate */
     205             :             {
     206        2846 :                 min_pred_err = pred_err;
     207        2846 :                 coh_pred_index = k;
     208             :             }
     209             :         }
     210             : 
     211        1445 :         push_next_indice( hBstr, coh_pred_index, STEREO_DFT_PRED_NBITS ); /* Write selected predictor to bitstream */
     212        1445 :         ( *nb_bits ) += STEREO_DFT_PRED_NBITS;
     213             : 
     214             :         /* Pick two different alphas (one low and one high) as a function
     215             :            of the number of available bits. */
     216        1445 :         alpha_step = 0;
     217        7225 :         for ( i = 0; i < STEREO_DFT_N_COH_ALPHA_STEPS - 1; i++ )
     218             :         {
     219        5780 :             if ( nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS > dft_cng_coh_alpha_start[i] )
     220             :             {
     221        5780 :                 alpha_step = i + 1;
     222             :             }
     223             :         }
     224             : 
     225             :         /* Calculate the number of encoded bits.   */
     226        1445 :         alphaptr = dft_cng_alpha_bits[alpha_step];
     227        1445 :         alpha_level = 0;
     228        1445 :         prev_nbbits_test = 100;
     229        4335 :         for ( i = 0; i < STEREO_DFT_N_COH_ALPHA_LEVELS; i++ )
     230             :         {
     231        2890 :             nbbits_test = 0;
     232        2890 :             pptr = dft_cng_coh_pred[coh_pred_index];
     233        2890 :             pred = 0.4f;
     234       19598 :             for ( b = 0; b < nbands; b++ )
     235             :             {
     236       56898 :                 for ( n = 0; n < b; n++ )
     237             :                 {
     238       40190 :                     pred += ( *pptr++ ) * cohBandq[n];
     239             :                 }
     240             : 
     241       16708 :                 pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
     242       16708 :                 pred_err = cohBand[b] - pred;
     243       16708 :                 res_index = usquant( pred_err, &pred_err, -0.4f, 0.1f, 9 );
     244       16708 :                 res_index = dft_cng_coh_i2u[res_index];
     245       16708 :                 nbbits_test += res_index + 1;
     246       16708 :                 res_index = dft_cng_coh_u2i[res_index];
     247       16708 :                 pred_err = usdequant( res_index, -0.4f, 0.1f );
     248       16708 :                 cohBandq[b] = pred + pred_err;
     249       16708 :                 if ( cohBandq[b] > 1 )
     250             :                 {
     251           0 :                     cohBandq[b] = 1;
     252             :                 }
     253       16708 :                 else if ( cohBandq[b] < 0 )
     254             :                 {
     255         251 :                     cohBandq[b] = 0;
     256             :                 }
     257       16708 :                 pred = 0;
     258             :             }
     259             : 
     260        2890 :             if ( nbbits_test < nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS )
     261             :             {
     262        2871 :                 alpha_level = i;
     263             :             }
     264             : 
     265        2890 :             if ( nbbits_test < prev_nbbits_test )
     266             :             {
     267        1535 :                 alpha_level = i;
     268             :             }
     269             : 
     270        2890 :             prev_nbbits_test = nbbits_test;
     271        2890 :             alphaptr++;
     272             :         }
     273             : 
     274             :         /* Do the actual encoding using the selected predictor and alpha */
     275        1445 :         push_next_indice( hBstr, alpha_level, STEREO_DFT_N_COH_ALPHA_BITS ); /* Write selected alpha index to bitstream */
     276        1445 :         ( *nb_bits ) += STEREO_DFT_N_COH_ALPHA_BITS;
     277        1445 :         alphaptr = &dft_cng_alpha_bits[alpha_step][alpha_level];
     278        1445 :         pptr = dft_cng_coh_pred[coh_pred_index]; /* Set pointer to selected predictor */
     279        1445 :         pred = 0.4f;
     280             : 
     281        9799 :         for ( b = 0; b < nbands; b++ )
     282             :         {
     283             :             /* Intra-frame prediction using quantized values */
     284       28449 :             for ( i = 0; i < b; i++ )
     285             :             {
     286       20095 :                 pred += ( *pptr++ ) * cohBandq[i];
     287             :             }
     288             :             /* Weighted intra/inter-frame prediction */
     289        8354 :             pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
     290        8354 :             pred_err = cohBand[b] - pred;
     291        8354 :             res_index = usquant( pred_err, &pred_err, -0.4f, 0.1f, 9 ); /* Quantize prediction residual */
     292        8354 :             res_index = dft_cng_coh_i2u[res_index];                     /* Convert to unary codeword - res_index+1 now equal to codeword
     293             :                                                                          length in bits with the following order:
     294             :                                                                          [0.0, 0.1, -0.1, 0.2, -0.2, 0.3, -0.3, 0.4, -0.4] */
     295             :             /* Bit rate truncation */
     296        8354 :             while ( res_index + 1 + *nb_bits > nr_of_sid_stereo_bits && res_index > 0 )
     297             :             {
     298           0 :                 res_index = max( 0, res_index - 2 ); /* Reduce step by one, keeping sign. */
     299             :             }
     300             :             /* Write residual index to bitstream */
     301        8354 :             if ( res_index + 1 + *nb_bits <= nr_of_sid_stereo_bits ) /* If the bit limit is reached, res_index = 0 is assumed for remaining indices */
     302             :             {
     303        8354 :                 *nb_bits += write_GR0( hBstr, IND_STEREO_DFT_SID_COH, &res_index, 1 );
     304             :             }
     305             : 
     306             :             /* Reconstruct */
     307        8354 :             res_index = dft_cng_coh_u2i[res_index];
     308        8354 :             pred_err = usdequant( res_index, -0.4f, 0.1f );
     309        8354 :             cohBandq[b] = pred + pred_err; /* Store for intra-frame prediction */
     310        8354 :             if ( cohBandq[b] > 1 )
     311             :             {
     312           0 :                 cohBandq[b] = 1;
     313             :             }
     314        8354 :             else if ( cohBandq[b] < 0 )
     315             :             {
     316         146 :                 cohBandq[b] = 0;
     317             :             }
     318             : 
     319        8354 :             mem_cohBand[b] = cohBandq[b]; /* Update memory for next frame */
     320        8354 :             pred = 0;
     321             :         }
     322             :     }
     323             : 
     324             :     /* Zero pad up to max number of bits to get constant bitrate */
     325       25680 :     for ( k = *nb_bits; k < nr_of_sid_stereo_bits; k++ )
     326             :     {
     327       24235 :         push_next_indice( hBstr, zeropad, 1 );
     328       24235 :         ( *nb_bits )++;
     329             :     }
     330             : 
     331             : 
     332        1445 :     return;
     333             : }
     334             : 
     335             : 
     336             : /*-------------------------------------------------------------------------
     337             :  * stereo_dft_cng_side_gain()
     338             :  *
     339             :  * Calculate CNG side gain
     340             :  *-------------------------------------------------------------------------*/
     341             : 
     342       10351 : void stereo_dft_cng_side_gain(
     343             :     STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo handle            */
     344             :     STEREO_CNG_ENC_HANDLE hStereoCng,      /* i/o: Stereo CNG data structure    */
     345             :     const int32_t core_brate,              /* i  : core bitrate                 */
     346             :     const int32_t last_core_brate,         /* i  : last core bitrate            */
     347             :     const int16_t bwidth                   /* i  : audio band-width             */
     348             : )
     349             : {
     350             :     int16_t b;
     351             :     int16_t sgSum;
     352             :     int16_t band_limits_full[STEREO_DFT_BAND_MAX + 1];
     353             :     float prev_weight;
     354             :     int16_t NFFT_inner;
     355             :     int16_t nbands_full;
     356             :     float tmp;
     357             : 
     358       10351 :     NFFT_inner = ( STEREO_DFT_N_MAX_ENC * inner_frame_tbl[bwidth] ) / L_FRAME48k;
     359       10351 :     nbands_full = hStereoDft->nbands;
     360             : 
     361             :     /* Calculate side gain average. First average in an inactive period */
     362             :     /* uses a weighted sum of the current average and the one from the  */
     363             :     /* previous inactive segment */
     364             : 
     365             :     /* Inactive frame => Update both sets of averages */
     366      105887 :     for ( b = 0; b < nbands_full; b++ )
     367             :     {
     368       95536 :         hStereoCng->sg_average[b] += hStereoDft->sidSideGain[b];
     369             :     }
     370       10351 :     hStereoCng->sg_average_counter++;
     371             : 
     372       10351 :     hStereoCng->cng_counter++;
     373       10351 :     hStereoCng->cng_counter = min( hStereoCng->cng_counter, STEREO_DFT_SG_ACT_CNT_MAX );
     374             : 
     375       10351 :     if ( core_brate == SID_2k40 )
     376             :     {
     377             :         /* SID frame */
     378        1519 :         if ( last_core_brate == FRAME_NO_DATA || hStereoCng->first_SID )
     379             :         {
     380             :             /* If first ever SID frame or not the first SID in an inactive segment  */
     381             :             /* Calculate average only based on current sg_average                   */
     382             :             /* Copy current sum to previous                                         */
     383       11837 :             for ( b = 0; b < hStereoDft->nbands; b++ )
     384             :             {
     385       10678 :                 hStereoCng->prev_sg_average[b] = hStereoCng->sg_average[b];
     386       10678 :                 hStereoCng->sg_average[b] = hStereoCng->sg_average[b] / (float) hStereoCng->sg_average_counter;
     387             :             }
     388             : 
     389        1159 :             hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
     390             :         }
     391             :         else
     392             :         {
     393             :             /* If first SID in a new inactive segment                                       */
     394             :             /* Calculate weighting factor based on the time since the last inactive segment */
     395         360 :             prev_weight = 0.8f * (float) ( STEREO_DFT_SG_ACT_CNT_MAX - hStereoCng->sg_active_cnt ) / (float) STEREO_DFT_SG_ACT_CNT_MAX + 0.2f;
     396             : 
     397             :             /* Calculate weighted average between prev and current sg */
     398             :             /* Set prev_sg sum to current. */
     399        3785 :             for ( b = 0; b < hStereoDft->nbands; b++ )
     400             :             {
     401        3425 :                 tmp = hStereoCng->sg_average[b];
     402        3425 :                 hStereoCng->sg_average[b] = ( hStereoCng->sg_average[b] + prev_weight * hStereoCng->prev_sg_average[b] ) / ( (float) hStereoCng->sg_average_counter + prev_weight * (float) hStereoCng->prev_sg_average_counter );
     403        3425 :                 hStereoCng->prev_sg_average[b] = tmp;
     404             :             }
     405         360 :             hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
     406             :         }
     407             : 
     408             :         /* Use coarse band partitioning in inactive frames                              */
     409             :         /* Rescale bands to the coarser partitioning taking the band size into account  */
     410        1519 :         mvs2s( hStereoDft->band_limits, band_limits_full, STEREO_DFT_BAND_MAX + 1 );
     411        1519 :         hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->hConfig->band_res, min( STEREO_DFT_N_32k_ENC, NFFT_inner ), ENC );
     412        1519 :         if ( nbands_full > hStereoDft->nbands + 1 )
     413             :         {
     414        5981 :             for ( b = 0; b < hStereoDft->nbands; b++ )
     415             :             {
     416        5104 :                 hStereoDft->sidSideGain[b] = hStereoCng->sg_average[2 * b] * ( band_limits_full[2 * b + 1] - band_limits_full[2 * b] );
     417        5104 :                 sgSum = band_limits_full[2 * b + 1] - band_limits_full[2 * b];
     418        5104 :                 if ( ( 2 * b + 1 ) < nbands_full )
     419             :                 {
     420        5091 :                     hStereoDft->sidSideGain[b] += hStereoCng->sg_average[2 * b + 1] * ( band_limits_full[2 * b + 2] - band_limits_full[2 * b + 1] );
     421        5091 :                     sgSum += band_limits_full[2 * b + 2] - band_limits_full[2 * b + 1];
     422             :                 }
     423        5104 :                 hStereoDft->sidSideGain[b] = hStereoDft->sidSideGain[b] / sgSum;
     424        5104 :                 stereo_dft_quantize_res_gains( &hStereoDft->sidSideGain[b], NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
     425             :             }
     426             :         }
     427             :         else
     428             :         {
     429        4336 :             for ( b = 0; b < hStereoDft->nbands; b++ )
     430             :             {
     431        3694 :                 stereo_dft_quantize_res_gains( &hStereoCng->sg_average[b], NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
     432             :             }
     433             :         }
     434             :         /* Restart SID avg after sending SID */
     435        1519 :         hStereoCng->sg_average_counter = 0;
     436        1519 :         set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
     437             :     }
     438             :     else
     439             :     {
     440       90265 :         for ( b = 0; b < nbands_full; b++ )
     441             :         {
     442       81433 :             hStereoCng->prev_sg_average[b] += hStereoDft->sidSideGain[b];
     443             :         }
     444             : 
     445        8832 :         hStereoCng->prev_sg_average_counter++;
     446             :     }
     447             : 
     448       10351 :     hStereoCng->sg_active_cnt = 0;
     449       10351 :     hStereoCng->first_SID_after_TD = 0;
     450             : 
     451       10351 :     return;
     452             : }
     453             : 
     454             : 
     455             : /*---------------------------------------------------------------
     456             :  * stereo_enc_cng_init()
     457             :  *
     458             :  * Initializes counters and averages
     459             :  * ---------------------------------------------------------------*/
     460             : 
     461          57 : void stereo_enc_cng_init(
     462             :     STEREO_CNG_ENC_HANDLE hStereoCng /* i/o: stereo CNG encoder structure   */
     463             : )
     464             : {
     465          57 :     hStereoCng->sg_average_counter = 0;
     466          57 :     set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
     467          57 :     hStereoCng->prev_sg_average_counter = 0;
     468          57 :     set_zero( hStereoCng->prev_sg_average, STEREO_DFT_BAND_MAX );
     469          57 :     hStereoCng->sg_active_cnt = 0;
     470          57 :     hStereoCng->first_SID = 1;
     471          57 :     set_f( hStereoCng->mem_cohBand, 0.5f, STEREO_DFT_BAND_MAX / 2 );
     472          57 :     set_zero( hStereoCng->prev_cohBand, 2 * ( STEREO_DFT_BAND_MAX / 2 ) );
     473          57 :     hStereoCng->td_active = 0;
     474          57 :     hStereoCng->first_SID_after_TD = 1;
     475          57 :     hStereoCng->cng_counter = 0;
     476             : 
     477          57 :     return;
     478             : }
     479             : 
     480             : 
     481             : /*-------------------------------------------------------------------------
     482             :  * stereo_cng_upd_counters()
     483             :  *
     484             :  * Update Stereo CNG counters
     485             :  *-------------------------------------------------------------------------*/
     486             : 
     487       21617 : void stereo_cng_upd_counters(
     488             :     STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure     */
     489             :     const int32_t element_mode,       /* i  : element mode                  */
     490             :     const int16_t nbands,             /* i  : Number of bands in active     */
     491             :     const float sidSideGain[],        /* i  : SID side gains                */
     492             :     const int16_t burst_ho_count,     /* i  : Hang-over count               */
     493             :     int16_t *coh_fade_counter         /* i  : Coherence fade counter        */
     494             : )
     495             : {
     496             :     int16_t b;
     497             : 
     498             :     /* Update sg avg in hangover frames, reset in active frames */
     499       21617 :     if ( burst_ho_count > 0 && element_mode == IVAS_CPE_DFT )
     500             :     {
     501       13916 :         for ( b = 0; b < nbands; b++ )
     502             :         {
     503       12537 :             hStereoCng->sg_average[b] += sidSideGain[b];
     504             :         }
     505        1379 :         hStereoCng->sg_average_counter++;
     506             :     }
     507             :     else
     508             :     {
     509       20238 :         hStereoCng->sg_average_counter = 0;
     510       20238 :         set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
     511             :     }
     512             : 
     513             :     /* Increment active counter, stop at max value */
     514       21617 :     hStereoCng->sg_active_cnt++;
     515       21617 :     hStereoCng->sg_active_cnt = min( hStereoCng->sg_active_cnt, STEREO_DFT_SG_ACT_CNT_MAX );
     516             : 
     517       21617 :     if ( hStereoCng->sg_active_cnt > STEREO_DFT_CNG_ITD_CNT )
     518             :     {
     519       19702 :         hStereoCng->cng_counter = 0;
     520             :     }
     521             : 
     522       21617 :     if ( element_mode == IVAS_CPE_DFT )
     523             :     {
     524       19952 :         *coh_fade_counter = 0;
     525             :     }
     526       21617 :     return;
     527             : }

Generated by: LCOV version 1.14