LCOV - code coverage report
Current view: top level - lib_enc - swb_bwe_enc_lr.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 107 206 51.9 %
Date: 2025-05-23 08:37:30 Functions: 4 7 57.1 %

          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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include <math.h>
      43             : #include "cnst.h"
      44             : #include "prot.h"
      45             : #include "rom_com.h"
      46             : #include "stat_com.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : /*--------------------------------------------------------------------------*
      50             :  * GetSubbandCorrIndex2_har()
      51             :  *
      52             :  * Finds the index of best correlation between highband (*inBuf) and lowband (*predBuf) for current subband of length (fLen)
      53             :  *--------------------------------------------------------------------------*/
      54             : 
      55             : /*! r: best correlation index */
      56           0 : static int16_t GetSubbandCorrIndex2_har(
      57             :     const float *inBuf,         /* i  : target buffer (i.e., highband signal)    */
      58             :     const float *predBuf,       /* i  : prediction buffer (i.e., lowband)        */
      59             :     const int16_t fLen,         /* i  : window length                            */
      60             :     const int16_t maxLag,       /* i  : search length                            */
      61             :     const GainItem *G_item,     /* i  : nZero nonzero components (value+index)   */
      62             :     const int16_t nZero,        /* i  : number of nonzero components used in     */
      63             :     int16_t *prev_frame_bstindx /* i  : previous frame best Indices              */
      64             : )
      65             : {
      66             :     int16_t bestIdx, i, j;
      67             :     float corr, energy, corr_sq;
      68             :     float lagCorr_sq, lagEnergy, eOld;
      69             :     int16_t N1, N2;
      70             : 
      71             : 
      72           0 :     bestIdx = 0;
      73           0 :     lagCorr_sq = 0.0f;
      74           0 :     lagEnergy = 1e30f;
      75             : 
      76           0 :     for ( i = 0, energy = 0.0f; i < fLen - 1; i++, predBuf++ )
      77             :     {
      78           0 :         energy += *predBuf * *predBuf;
      79             :     }
      80             : 
      81           0 :     predBuf -= fLen - 1;
      82           0 :     eOld = 0.0f;
      83           0 :     N1 = max( 0, *prev_frame_bstindx - maxLag / 2 );
      84           0 :     if ( *prev_frame_bstindx < 0 )
      85             :     {
      86           0 :         N2 = maxLag - 1;
      87             :     }
      88             :     else
      89             :     {
      90           0 :         N2 = min( maxLag - 1, *prev_frame_bstindx + maxLag / 2 );
      91             :     }
      92             : 
      93           0 :     predBuf += N1;
      94             : 
      95             :     /* find the best lag */
      96           0 :     for ( i = N1; i <= N2; i++ )
      97             :     {
      98           0 :         corr = 0.0f;
      99             : 
     100             :         /* get the energy, remove the old and update with the new energy index */
     101           0 :         for ( j = 0, energy = 0.0f; j < fLen; j++, predBuf++ )
     102             :         {
     103           0 :             energy += *predBuf * *predBuf;
     104             :         }
     105             : 
     106           0 :         predBuf -= fLen;
     107             : 
     108             :         /* energy to be removed in the next lag */
     109           0 :         eOld = *predBuf;
     110           0 :         eOld *= eOld;
     111             : 
     112             :         /* get cross-correlation */
     113           0 :         if ( energy )
     114             :         {
     115           0 :             for ( j = 0, corr = 0.0f; j < nZero; j++ )
     116             :             {
     117           0 :                 corr += inBuf[G_item[j].gainIndex] * predBuf[G_item[j].gainIndex];
     118             :             }
     119             : 
     120           0 :             corr_sq = corr * corr;
     121             : 
     122           0 :             if ( (double) lagCorr_sq * (double) energy < (double) corr_sq * (double) lagEnergy )
     123             :             {
     124           0 :                 bestIdx = i;
     125           0 :                 lagCorr_sq = corr_sq;
     126           0 :                 lagEnergy = energy;
     127             :             }
     128             :         }
     129             : 
     130           0 :         predBuf++;
     131             :     }
     132             : 
     133           0 :     if ( lagCorr_sq == 0.0f && *prev_frame_bstindx < 0 )
     134             :     {
     135           0 :         bestIdx = 0;
     136             :     }
     137             :     else
     138             :     {
     139           0 :         if ( lagCorr_sq == 0.0f )
     140             :         {
     141           0 :             bestIdx = *prev_frame_bstindx;
     142             :         }
     143             :     }
     144             : 
     145           0 :     *prev_frame_bstindx = bestIdx;
     146             : 
     147           0 :     return bestIdx;
     148             : }
     149             : 
     150             : 
     151             : /*--------------------------------------------------------------------------*
     152             :  * getswbindices_har()
     153             :  *
     154             :  * Finds the pulse index of best correlation between highband (*yos) and lowband (*y2) for two groups of length sbLen
     155             :  *--------------------------------------------------------------------------*/
     156             : 
     157           0 : static void getswbindices_har(
     158             :     float *yos,                  /* i  : original input spectrum */
     159             :     float *y2,                   /* i  : decoded spectrum */
     160             :     const int16_t nBands_search, /* i  : number of bands */
     161             :     int16_t *lagIndices,         /* o  : pulse index */
     162             :     int16_t *prev_frame_bstindx, /* i/o: prev frame index */
     163             :     const int16_t swb_lowband,   /* i  : length of the LF spectrum */
     164             :     const int16_t *subband_offsets,
     165             :     const int16_t *sbWidth,
     166             :     const int16_t *subband_search_offset
     167             : 
     168             : )
     169             : {
     170             :     GainItem Nbiggest[(NB_SWB_SUBBANDS_HAR_SEARCH_SB) *N_NBIGGEST_PULSEARCH];
     171             :     const float *refBuf, *predBuf;
     172             :     int16_t search_offset[NB_SWB_SUBBANDS_HAR_SEARCH_SB];
     173             :     int16_t nlags[NB_SWB_SUBBANDS_HAR_SEARCH_SB];
     174             :     int16_t j, k, sb;
     175             :     int16_t n_nbiggestsearch[NB_SWB_SUBBANDS_HAR];
     176             :     float low_freqsgnl[L_FRAME32k];
     177             : 
     178             :     /* Initializations */
     179           0 :     predBuf = y2;
     180             : 
     181             :     /* Get the number of HF groups for performing Similarity search */
     182           0 :     for ( sb = 0; sb < nBands_search; sb++ )
     183             :     {
     184           0 :         nlags[sb] = (int16_t) pow( 2, bits_lagIndices_mode0_Har[sb] );
     185             :     }
     186             : 
     187           0 :     for ( sb = 0; sb < nBands_search; sb++ )
     188             :     {
     189           0 :         j = sb * N_NBIGGEST_PULSEARCH;
     190           0 :         refBuf = yos + swb_lowband + subband_offsets[sb];
     191             : 
     192             :         /* Find NBiggest samples in HF Groups */
     193           0 :         FindNBiggest2_simple( refBuf, Nbiggest + j, sbWidth[sb], &n_nbiggestsearch[sb], N_NBIGGEST_PULSEARCH );
     194           0 :         search_offset[sb] = subband_search_offset[sb];
     195             :     }
     196             : 
     197             :     /* Similarity Search for the HF spectrum */
     198           0 :     for ( sb = 0; sb < nBands_search; sb++ )
     199             :     {
     200           0 :         k = 0;
     201           0 :         if ( sb == 0 )
     202             :         {
     203             :             /* copy SSmoothed LF Spectrum */
     204           0 :             mvr2r( predBuf + search_offset[sb] - nlags[sb] / 2, low_freqsgnl, sbWidth[sb] + nlags[sb] );
     205             :         }
     206             :         else
     207             :         {
     208             :             /* copy SSmoothed LF Spectrum */
     209           0 :             for ( j = search_offset[sb] + nlags[sb] / 2; j > search_offset[sb] - sbWidth[sb] - nlags[sb] / 2; j-- )
     210             :             {
     211           0 :                 low_freqsgnl[k] = predBuf[j];
     212           0 :                 k++;
     213             :             }
     214             :         }
     215             :         /* correlation b/w HF spectrum Group1 of length sbLen and decoded LF spectrum */
     216           0 :         lagIndices[sb] = GetSubbandCorrIndex2_har( yos + swb_lowband + subband_offsets[sb], low_freqsgnl, sbWidth[sb], nlags[sb], Nbiggest + ( sb * N_NBIGGEST_PULSEARCH ), n_nbiggestsearch[sb], &prev_frame_bstindx[sb] );
     217             :     }
     218             : 
     219           0 :     return;
     220             : }
     221             : 
     222         124 : static int16_t GetSubbandCorrIndex2_pulsestep(
     223             :     const float *inBuf,
     224             :     const float *predBuf,
     225             :     const float *predBufMa,
     226             :     const int16_t fLen,
     227             :     const int16_t maxLag,
     228             :     const GainItem *G_item,
     229             :     const int16_t nZero,
     230             :     int16_t ssearch_buflim,
     231             :     const float *predBuf_ni )
     232             : {
     233             :     int16_t bestIdx, i, j;
     234             :     float corr, energy, corr_sq;
     235             :     float lagCorr_sq, lagEnergy;
     236             :     int16_t absPos;
     237         124 :     int16_t ib_flag = 0;
     238             : 
     239             : 
     240         124 :     absPos = 0;
     241         124 :     bestIdx = -1;
     242         124 :     lagCorr_sq = 0.0f;
     243         124 :     lagEnergy = 1e30f;
     244             : 
     245             :     /* Get the initial energy for zero lag */
     246         714 :     while ( *predBuf == 0.0f && absPos < ssearch_buflim )
     247             :     {
     248         590 :         predBuf++;
     249         590 :         absPos++;
     250         590 :         predBuf_ni++;
     251             :     }
     252             : 
     253         124 :     if ( absPos == ssearch_buflim )
     254             :     {
     255           0 :         predBuf--;
     256           0 :         absPos--;
     257           0 :         predBuf_ni--;
     258             :     }
     259        9796 :     for ( i = 0, energy = 0.0f; i < fLen; i++, predBuf_ni++ )
     260             :     {
     261        9672 :         energy += *predBuf_ni * *predBuf_ni;
     262             :     }
     263             : 
     264         124 :     predBuf_ni -= fLen;
     265         124 :     lagEnergy = energy;
     266             : 
     267             :     /* Find the best lag */
     268         496 :     for ( i = 0; i < maxLag; i++ )
     269             :     {
     270         372 :         corr = 0.0f;
     271             : 
     272             :         /* Get the energy, remove the old and update with the new energy index */
     273       27342 :         for ( j = 0, energy = 0.0f; j < fLen; j++, predBuf_ni++ )
     274             :         {
     275       26970 :             energy += *predBuf_ni * *predBuf_ni;
     276             :         }
     277         372 :         predBuf_ni -= fLen;
     278             : 
     279             :         /* Get cross-correlation */
     280         372 :         if ( energy )
     281             :         {
     282        7026 :             for ( j = 0, corr = 0.0f; j < nZero; j++ )
     283             :             {
     284        6654 :                 corr += inBuf[G_item[j].gainIndex] * predBufMa[G_item[j].gainIndex];
     285             :             }
     286             : 
     287         372 :             corr_sq = corr * corr;
     288             : 
     289         372 :             if ( ( lagCorr_sq == 0.0f && corr_sq == 0.0f ) || (double) lagCorr_sq * (double) energy < (double) corr_sq * (double) lagEnergy )
     290             :             {
     291         281 :                 bestIdx = i;
     292         281 :                 lagCorr_sq = corr_sq;
     293         281 :                 lagEnergy = energy;
     294             :             }
     295             :         }
     296             : 
     297         372 :         predBuf++;
     298         372 :         absPos++;
     299         372 :         predBuf_ni++;
     300        1456 :         while ( *predBuf == 0.0f && absPos < ssearch_buflim )
     301             :         {
     302        1084 :             predBuf++;
     303        1084 :             absPos++;
     304        1084 :             predBuf_ni++;
     305             :         }
     306             : 
     307         372 :         if ( absPos >= ssearch_buflim )
     308             :         {
     309           0 :             if ( bestIdx == -1 )
     310             :             {
     311           0 :                 ib_flag = 1;
     312             :             }
     313             : 
     314           0 :             break;
     315             :         }
     316             :     }
     317         124 :     if ( ib_flag )
     318             :     {
     319           0 :         bestIdx = 0;
     320             :     }
     321         124 :     return bestIdx;
     322             : }
     323             : 
     324             : 
     325             : /*--------------------------------------------------------------------------*
     326             :  * GetSWBIndices()
     327             :  *
     328             :  * Finds the subband lags for subband coding. Each lag corresponds to
     329             :  * the section that is copied and scaled from the low-frequency band
     330             :  * to form the high-frequency subband.
     331             :  *
     332             :  * The subbands are searched in two steps to reduce the complexity of
     333             :  * the search relative to full search. In first step, a most representative
     334             :  * subband is selected based on the similarity of the subbands.Full search
     335             :  * is performed for the selected subband.Based on the lagIndice value for
     336             :  * this subband, the region of highest interest is selected. A partial
     337             :  * search is performed for rest of the subbands around this region of the
     338             :  * low-frequency range.
     339             :  *--------------------------------------------------------------------------*/
     340             : 
     341          31 : static void GetSWBIndices(
     342             :     const float *predBuf,           /* i  : low-frequency band                  */
     343             :     const float *targetBuf,         /* i  : high-frequency band                 */
     344             :     const int16_t nBands_search,    /* i  : number of search subbands           */
     345             :     const int16_t *sbWidth,         /* i  : subband lengths                     */
     346             :     int16_t *lagIndices,            /* o  : selected lags for subband coding    */
     347             :     const int16_t predBufLen,       /* i  : low-frequency band length           */
     348             :     GainItem *Nbiggest,             /* o  : most representative region          */
     349             :     const int16_t *subband_offsets, /* o  : N biggest components                */
     350             :     float *predBuf_ni               /* i  : low-frequency band filled noise     */
     351             : )
     352             : {
     353             :     const float *refBuf;
     354             :     int16_t search_offset[NB_SWB_SUBBANDS];
     355             :     int16_t nlags[NB_SWB_SUBBANDS];
     356             :     int16_t sbLen;
     357             :     int16_t j, sb;
     358             :     int16_t n_nbiggestsearch[NB_SWB_SUBBANDS];
     359             :     int16_t ssearch_buflim;
     360             :     float sspectra_ma[L_FRAME32k];
     361             : 
     362             :     /* Initializations */
     363         155 :     for ( sb = 0; sb < nBands_search; sb++ )
     364             :     {
     365         124 :         j = sb * N_NBIGGEST_PULSEARCH;
     366         124 :         sbLen = sbWidth[sb];
     367         124 :         refBuf = targetBuf + subband_offsets[sb];
     368         124 :         FindNBiggest2_simple( refBuf, Nbiggest + j, sbLen, &n_nbiggestsearch[sb], N_NBIGGEST_PULSEARCH );
     369             :     }
     370             : 
     371             :     /* Selection of most representative subband (full search) */
     372         155 :     for ( sb = 0; sb < nBands_search; sb++ )
     373             :     {
     374         124 :         nlags[sb] = (int16_t) pow( 2, bits_lagIndices_modeNormal[sb] );
     375             :     }
     376             : 
     377         155 :     for ( sb = 0; sb < nBands_search; sb++ )
     378             :     {
     379         124 :         search_offset[sb] = subband_search_offsets[sb];
     380             :     }
     381          31 :     sspectra_ma[0] = ( predBuf_ni[0] + predBuf_ni[1] ) / 2.0f;
     382             : 
     383        7905 :     for ( sb = 1; sb < predBufLen - 1; sb++ )
     384             :     {
     385        7874 :         sspectra_ma[sb] = ( predBuf_ni[sb - 1] + predBuf_ni[sb] + predBuf_ni[sb + 1] ) / 3.0f;
     386             :     }
     387             : 
     388          31 :     sspectra_ma[sb] = ( predBuf_ni[sb - 1] + predBuf_ni[sb] ) / 2.0f;
     389             :     /* Partial search for rest of subbands except the last which is fixed */
     390         155 :     for ( sb = 0; sb < nBands_search; sb++ )
     391             :     {
     392         124 :         sbLen = sbWidth[sb];
     393         124 :         ssearch_buflim = predBufLen - ( sbLen + search_offset[sb] );
     394         124 :         lagIndices[sb] = GetSubbandCorrIndex2_pulsestep( targetBuf + subband_offsets[sb], predBuf + search_offset[sb], sspectra_ma + search_offset[sb], sbLen, nlags[sb], Nbiggest + ( sb * N_NBIGGEST_PULSEARCH ), n_nbiggestsearch[sb], ssearch_buflim, predBuf_ni + search_offset[sb] );
     395             :     }
     396             : 
     397          31 :     return;
     398             : }
     399             : 
     400             : 
     401           0 : static void gethar_noisegn(
     402             :     BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle            */
     403             :     float spectra[],
     404             :     float noise_flr[],
     405             :     float xSynth_har[],
     406             :     const int16_t sbWidth[],
     407             :     const int16_t lagIndices[],
     408             :     const int16_t bands,
     409             :     const int16_t har_bands,
     410             :     const int16_t fLenLow,
     411             :     const int16_t fLenHigh,
     412             :     const int16_t subband_offsets[],
     413             :     const int16_t subband_search_offset[],
     414             :     int16_t band_start[],
     415             :     int16_t band_end[],
     416             :     int16_t band_width[],
     417             :     float band_energy[],
     418             :     float be_tonal[],
     419             :     float *sspectra,
     420             :     const int16_t har_freq_est2,
     421             :     const int16_t pos_max_hfe2,
     422             :     int16_t *pul_res,
     423             :     GainItem pk_sf[] )
     424             : {
     425             :     GainItem get_pk[N_NBIGGEST_SEARCH_LRG_B];
     426             :     int16_t n_nbiggestsearch, imin, gqlevs;
     427             :     int16_t i;
     428             :     float hfspec[L_FRAME32k];
     429             :     float g, g1, g2, dmin, d;
     430             : 
     431             :     /*Generate HF noise*/
     432           0 :     genhf_noise( noise_flr, xSynth_har, sspectra, bands, har_bands, har_freq_est2, pos_max_hfe2, pul_res, pk_sf, fLenLow, fLenHigh, sbWidth, lagIndices, subband_offsets, subband_search_offset );
     433             : 
     434           0 :     mvr2r( spectra + fLenLow, hfspec, fLenHigh );
     435           0 :     FindNBiggest2_simple( hfspec, get_pk, fLenHigh, &n_nbiggestsearch, N_NBIGGEST_SEARCH_LRG_B );
     436           0 :     for ( i = 0; i < n_nbiggestsearch; i++ )
     437             :     {
     438           0 :         hfspec[get_pk[i].gainIndex] = 0.0f;
     439             :     }
     440             : 
     441           0 :     g1 = sum2_f( hfspec, fLenHigh );
     442           0 :     g2 = sum2_f( xSynth_har, fLenHigh );
     443           0 :     imin = 0;
     444           0 :     if ( g1 != 0.0 && g2 != 0.0 )
     445             :     {
     446           0 :         g = (float) log10( sqrt( g1 / g2 ) );
     447           0 :         gqlevs = 4;
     448           0 :         dmin = FLT_MAX;
     449           0 :         imin = 0;
     450             : 
     451           0 :         for ( i = 0; i < gqlevs; i++ )
     452             :         {
     453           0 :             d = (float) fabs( g - gain_table_SWB_BWE[i] );
     454           0 :             if ( d < dmin )
     455             :             {
     456           0 :                 dmin = d;
     457           0 :                 imin = i;
     458             :             }
     459             :         }
     460             :     }
     461           0 :     push_indice( hBstr, IND_NOISEG, imin, 2 );
     462           0 :     g = (float) pow( 10.0f, gain_table_SWB_BWE[imin] );
     463             : 
     464             :     /*Tonal energy estimation*/
     465           0 :     ton_ene_est( xSynth_har, be_tonal, band_energy, band_start, band_end, band_width, fLenLow, fLenHigh, bands, har_bands, g, pk_sf, pul_res );
     466             : 
     467           0 :     return;
     468             : }
     469             : 
     470             : 
     471             : /*--------------------------------------------------------------------------*
     472             :  * EncodeSWBSubbands()
     473             :  *
     474             :  * Main routine for generic SWB coding. High-frequency subband
     475             :  * replicated based on the lowband signal. A search is perform
     476             :  * find lowband indices denoting the selected lowband subband.
     477             :  *--------------------------------------------------------------------------*/
     478             : 
     479          31 : static void EncodeSWBSubbands(
     480             :     Encoder_State *st,                    /* i/o: encoder state structure                     */
     481             :     float *spectra,                       /* i/o: MDCT domain spectrum                        */
     482             :     const int16_t fLenLow,                /* i  : lowband length                              */
     483             :     const int16_t fLenHigh,               /* i  : highband length                             */
     484             :     const int16_t nBands,                 /* i  : number of subbands                          */
     485             :     const int16_t nBands_search,          /* i  : number of subbands to be searched for BWE   */
     486             :     const int16_t *sbWidth,               /* i  : subband lengths                             */
     487             :     const int16_t *subband_offsets,       /* i  : Subband offset for BWE                      */
     488             :     int16_t *lagIndices,                  /* o  : lowband index for each subband              */
     489             :     float *lagGains,                      /* o  : first gain for each subband                 */
     490             :     int16_t BANDS,                        /* i  : noise estimate from WB part                 */
     491             :     int16_t *band_start,                  /* i  : Number subbands/Frame                       */
     492             :     int16_t *band_end,                    /* i  : Band Start of each SB                       */
     493             :     float *band_energy,                   /* i  : Band end of each SB                         */
     494             :     const int16_t *p2a_flags,             /* i  : BAnd energy of each SB                      */
     495             :     const int16_t hqswb_clas,             /* i  : lowband synthesis                           */
     496             :     int16_t *prev_frm_index,              /* i  : clas information                            */
     497             :     const int16_t har_bands,              /* i/o: Index of the previous Frame                 */
     498             :     const int16_t *subband_search_offset, /* i  : Number of harmonic LF bands                 */
     499             :     int16_t *prev_frm_hfe2,
     500             :     int16_t *prev_stab_hfe2,
     501             :     int16_t band_width[],
     502             :     const float spectra_ni[], /* i  : coded MDCT domain spectrum + noise          */
     503             :     int16_t *ni_seed          /* i/o: random seed for search buffer NI            */
     504             : )
     505             : {
     506             :     GainItem Nbiggest[NB_SWB_SUBBANDS * N_NBIGGEST_PULSEARCH];
     507             :     int16_t i, k;
     508             :     float sspectra[L_FRAME32k];
     509             :     float sspectra_ni[L_FRAME32k], sspectra_diff[L_FRAME32k], be_tonal[SWB_HAR_RAN1], xSynth_har[L_FRAME32k];
     510          31 :     float ss_min = 1.0f, th_g[NB_SWB_SUBBANDS];
     511             :     GainItem pk_sf[(NB_SWB_SUBBANDS) *8];
     512             :     int16_t pul_res[NB_SWB_SUBBANDS];
     513          31 :     int16_t har_freq_est1 = 0, har_freq_est2 = 0;
     514          31 :     int16_t flag_dis = 1;
     515          31 :     int16_t pos_max_hfe2 = 0;
     516             : 
     517          31 :     HQ_ENC_HANDLE hHQ_core = st->hHQ_core;
     518          31 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     519             : 
     520          31 :     set_f( sspectra, 0.0f, fLenLow );
     521          31 :     set_f( sspectra_ni, 0.0f, fLenLow );
     522          31 :     set_f( xSynth_har, 0.0f, L_FRAME32k );
     523          31 :     set_s( pul_res, 0, NB_SWB_SUBBANDS );
     524             : 
     525             : 
     526          31 :     if ( hqswb_clas == HQ_HARMONIC )
     527             :     {
     528             :         /* Harmonic Structure analysis */
     529           0 :         pos_max_hfe2 = har_est( spectra, fLenLow, &har_freq_est1, &har_freq_est2, &flag_dis, prev_frm_hfe2, subband_search_offset, sbWidth, prev_stab_hfe2 );
     530             :         /* Spectrum normalization for the corecoder */
     531           0 :         noise_extr_corcod( spectra, spectra_ni, sspectra, sspectra_diff, sspectra_ni, fLenLow, hHQ_core->prev_hqswb_clas, &hHQ_core->prev_ni_ratio );
     532             : 
     533             :         /* Find best indices for each group */
     534           0 :         getswbindices_har( spectra, sspectra_ni, nBands_search, lagIndices, prev_frm_index, fLenLow, subband_offsets, sbWidth, subband_search_offset );
     535             :         /* Write the indices into the bitstream */
     536           0 :         for ( k = 0; k < nBands_search; k++ )
     537             :         {
     538           0 :             push_indice( hBstr, IND_LAGINDICES, lagIndices[k], bits_lagIndices_mode0_Har[k] );
     539             :         }
     540             : 
     541           0 :         if ( flag_dis == 0 )
     542             :         {
     543           0 :             if ( har_freq_est2 != SWB_HAR_RAN1 || har_freq_est2 != *prev_frm_hfe2 )
     544             :             {
     545           0 :                 har_freq_est2 += lagIndices[0];
     546             :             }
     547             :         }
     548             : 
     549             :         /*noise generation*/
     550           0 :         gethar_noisegn( hBstr, spectra, sspectra_diff, xSynth_har, sbWidth, lagIndices, BANDS, har_bands, fLenLow, fLenHigh, subband_offsets, subband_search_offset, band_start, band_end, band_width, band_energy, be_tonal, sspectra, har_freq_est2, pos_max_hfe2, pul_res, pk_sf );
     551             : 
     552             :         /*HF Spectrum Generation*/
     553           0 :         Gettonl_scalfact( xSynth_har, spectra_ni, fLenLow, fLenHigh, har_bands, BANDS, band_energy, band_start, band_end, p2a_flags, be_tonal, pk_sf, pul_res );
     554             : 
     555           0 :         if ( flag_dis == 0 )
     556             :         {
     557           0 :             *prev_frm_hfe2 = 0;
     558             :         }
     559             :         else
     560             :         {
     561           0 :             *prev_frm_hfe2 = har_freq_est2;
     562             :         }
     563             : 
     564           0 :         for ( k = har_bands; k < BANDS; k++ )
     565             :         {
     566           0 :             for ( i = band_start[k]; i <= band_end[k]; i++ )
     567             :             {
     568           0 :                 spectra[i] = xSynth_har[i - fLenLow];
     569             :             }
     570             :         }
     571             :     }
     572             :     else
     573             :     {
     574             :         /* Spectrum normalization for the corecoder*/
     575          31 :         ss_min = spectrumsmooth_noiseton( spectra, spectra_ni, sspectra, sspectra_diff, sspectra_ni, fLenLow, ni_seed );
     576             : 
     577             :         /* Get lag indices */
     578          31 :         GetSWBIndices( sspectra, spectra + fLenLow, nBands, sbWidth, lagIndices, fLenLow, Nbiggest, subband_offsets, sspectra );
     579             :         /* Bitstream operations */
     580         155 :         for ( k = 0; k < nBands; k++ )
     581             :         {
     582         124 :             if ( p2a_flags[BANDS - NB_SWB_SUBBANDS + k] == 0 )
     583             :             {
     584         122 :                 push_indice( hBstr, IND_LAGINDICES, lagIndices[k], bits_lagIndices_modeNormal[k] );
     585             :             }
     586             :             else
     587             :             {
     588           2 :                 lagIndices[k] = 0;
     589             :             }
     590             :         }
     591          31 :         convert_lagIndices_pls2smp( lagIndices, nBands, lagIndices, sspectra, sbWidth, fLenLow );
     592             :         /*get levels for missing bands*/
     593          31 :         GetlagGains( sspectra_ni, &band_energy[BANDS - NB_SWB_SUBBANDS], nBands, sbWidth, lagIndices, fLenLow, lagGains );
     594         155 :         for ( k = 0; k < NB_SWB_SUBBANDS; k++ )
     595             :         {
     596         124 :             lagGains[k] *= 0.9f;
     597             :         }
     598             : 
     599         155 :         for ( k = 0; k < NB_SWB_SUBBANDS; k++ )
     600             :         {
     601         124 :             th_g[k] = 0.0f;
     602         124 :             if ( p2a_flags[BANDS - NB_SWB_SUBBANDS + k] == 0 )
     603             :             {
     604         122 :                 th_g[k] = lagGains[k] * ss_min;
     605             :             }
     606             :         }
     607             : 
     608             :         /* Construct spectrum */
     609          31 :         GetSynthesizedSpecThinOut( sspectra_ni, xSynth_har, nBands, sbWidth, lagIndices, lagGains, fLenLow );
     610             :         /*Level adjustment for the missing bands*/
     611          31 :         noiseinj_hf( xSynth_har, th_g, band_energy, hHQ_core->prev_En_sb, p2a_flags, BANDS, band_start, band_end, fLenLow );
     612             : 
     613         155 :         for ( k = BANDS - NB_SWB_SUBBANDS; k < BANDS; k++ )
     614             :         {
     615         124 :             if ( p2a_flags[k] == 0 )
     616             :             {
     617        9605 :                 for ( i = band_start[k]; i <= band_end[k]; i++ )
     618             :                 {
     619        9483 :                     spectra[i] = xSynth_har[i - fLenLow];
     620             :                 }
     621             :             }
     622             :             else
     623             :             {
     624         191 :                 for ( i = band_start[k]; i <= band_end[k]; i++ )
     625             :                 {
     626         189 :                     spectra[i] = spectra_ni[i];
     627             :                 }
     628             :             }
     629             :         }
     630             :     }
     631             : 
     632          31 :     return;
     633             : }
     634             : 
     635             : /*--------------------------------------------------------------------------*
     636             :  * swb_bwe_enc_lr()
     637             :  *
     638             :  * Main encoding routine of  SWB BWE for the LR MDCT core
     639             :  *--------------------------------------------------------------------------*/
     640             : 
     641          31 : void swb_bwe_enc_lr(
     642             :     Encoder_State *st,         /* i/o: encoder state structure                      */
     643             :     const float m_core[],      /* i  : lowband synthesis                            */
     644             :     const float m_orig[],      /* i/o: scaled orig signal (MDCT)                    */
     645             :     float m[],                 /* o  : highband synthesis with lowband zeroed       */
     646             :     const int32_t total_brate, /* i  : total bitrate for selecting subband pattern  */
     647             :     int16_t BANDS,             /* i  : Total number of Subbands in a frame          */
     648             :     int16_t *band_start,       /* i  : band start of each SB                        */
     649             :     int16_t *band_end,         /* i  : band end of each SB                          */
     650             :     float *band_energy,        /* i  : band_energy of each SB                       */
     651             :     int16_t *p2a_flags,        /* i  : HF tonal indicator                           */
     652             :     const int16_t hqswb_clas,  /* i  : HQ_NORMAL or HQ_HARMONIC class               */
     653             :     int16_t lowlength,         /* i  : lowband length                               */
     654             :     int16_t highlength,        /* i  : highband length                              */
     655             :     int16_t *prev_frm_index,   /* i/o: previous frame lag index for harmonic mode   */
     656             :     const int16_t har_bands,   /* i  : Number of LF harmonic bands                  */
     657             :     int16_t *prev_frm_hfe2,
     658             :     int16_t *prev_stab_hfe2,
     659             :     int16_t band_width[], /* i  : subband bandwidths                           */
     660             :     const float y2_ni[],  /* i/o: Sparse filled core coder                     */
     661             :     int16_t *ni_seed      /* i/o: random seed for search buffer NI             */
     662             : )
     663             : {
     664             :     int16_t k;
     665             :     int16_t nBands;
     666             :     int16_t nBands_search;
     667             :     int16_t wBands[NB_SWB_SUBBANDS];
     668             :     int16_t lagIndices[NB_SWB_SUBBANDS];
     669             :     float lagGains[NB_SWB_SUBBANDS];
     670             :     const int16_t *subband_offsets;
     671             :     int16_t swb_lowband, swb_highband;
     672             :     const int16_t *subband_search_offset;
     673             : 
     674          31 :     subband_search_offset = subband_search_offsets_13p2kbps_Har;
     675          31 :     subband_offsets = subband_offsets_sub5_13p2kbps_Har;
     676             : 
     677          31 :     hf_parinitiz( total_brate, hqswb_clas, lowlength, highlength, wBands, &subband_search_offset, &subband_offsets, &nBands, &nBands_search, &swb_lowband, &swb_highband );
     678             : 
     679             :     /* Prepare m[], low part from WB core, high part from 32k input */
     680          31 :     mvr2r( m_core, m, swb_lowband );
     681          31 :     mvr2r( m_orig + swb_lowband, m + swb_lowband, swb_highband );
     682             : 
     683             :     /* SWB BWE encoding */
     684          31 :     EncodeSWBSubbands( st, m, swb_lowband, swb_highband, nBands, nBands_search, wBands, subband_offsets, lagIndices, lagGains, BANDS, band_start, band_end, band_energy, p2a_flags, hqswb_clas, prev_frm_index, har_bands, subband_search_offset, prev_frm_hfe2, prev_stab_hfe2, band_width, y2_ni, ni_seed );
     685             : 
     686          31 :     m[swb_lowband + swb_highband - 1] *= 0.0625f;
     687          31 :     m[swb_lowband + swb_highband - 2] *= 0.125f;
     688          31 :     m[swb_lowband + swb_highband - 3] *= 0.25f;
     689          31 :     m[swb_lowband + swb_highband - 4] *= 0.5f;
     690             : 
     691             :     /* set frequencies below 6.4 kHz to zero */
     692          31 :     if ( hqswb_clas == HQ_NORMAL )
     693             :     {
     694        7967 :         for ( k = 0; k < swb_lowband; k++ )
     695             :         {
     696        7936 :             m[k] = 0.0f;
     697             :         }
     698             :     }
     699             : 
     700          31 :     return;
     701             : }

Generated by: LCOV version 1.14