LCOV - code coverage report
Current view: top level - lib_dec - ivas_sba_dirac_stereo_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 338 344 98.3 %
Date: 2025-05-23 08:37:30 Functions: 11 11 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 <math.h>
      35             : #include "options.h"
      36             : #include "cnst.h"
      37             : #include "ivas_cnst.h"
      38             : #include "prot.h"
      39             : #include "ivas_prot.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_dec.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------*
      49             :  * ivas_get_sba_dirac_stereo_flag()
      50             :  *
      51             :  * Set sba_dirac_stereo_flag
      52             :  *-------------------------------------------------------------------*/
      53             : 
      54        9987 : int16_t ivas_get_sba_dirac_stereo_flag(
      55             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure        */
      56             : )
      57             : {
      58             :     int16_t sba_dirac_stereo_flag;
      59             :     AUDIO_CONFIG output_config;
      60             : 
      61        9987 :     sba_dirac_stereo_flag = 0;
      62        9987 :     output_config = st_ivas->hDecoderConfig->output_config;
      63             : 
      64        9987 :     if ( st_ivas->ivas_format == SBA_FORMAT || ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) )
      65             :     {
      66        5481 :         if ( st_ivas->ivas_format == SBA_FORMAT )
      67             :         {
      68        3792 :             if ( output_config == IVAS_AUDIO_CONFIG_STEREO || ( output_config == IVAS_AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) )
      69             :             {
      70         396 :                 sba_dirac_stereo_flag = 1;
      71             :             }
      72             :         }
      73             :         else
      74             :         {
      75        1689 :             if ( st_ivas->nchan_transport == 1 && output_config == IVAS_AUDIO_CONFIG_STEREO )
      76             :             {
      77          21 :                 sba_dirac_stereo_flag = 1;
      78             :             }
      79             :         }
      80             :     }
      81        4506 :     else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
      82             :     {
      83        2070 :         if ( output_config == IVAS_AUDIO_CONFIG_STEREO )
      84             :         {
      85         282 :             sba_dirac_stereo_flag = 1;
      86             :         }
      87             :     }
      88             : 
      89        9987 :     return sba_dirac_stereo_flag;
      90             : }
      91             : 
      92             : 
      93             : /*-------------------------------------------------------------------*
      94             :  * ivas_sba_dirac_stereo_config()
      95             :  *
      96             :  * DFT Stereo Configuration for SBA DirAC stereo output
      97             :  *-------------------------------------------------------------------*/
      98             : 
      99       32652 : void ivas_sba_dirac_stereo_config(
     100             :     STEREO_DFT_CONFIG_DATA_HANDLE hConfig /* o  : DFT stereo configuration                */
     101             : )
     102             : {
     103       32652 :     if ( hConfig != NULL )
     104             :     {
     105             : #ifndef DEBUG_STEREO_DFT_NOSTEREO
     106       32652 :         hConfig->dmx_active = STEREO_DFT_DMX_ACTIVE;
     107             : #else
     108             :         hConfig->dmx_active = 0;
     109             : #endif
     110       32652 :         hConfig->band_res = STEREO_DFT_BAND_RES_HIGH;
     111       32652 :         hConfig->prm_res = 2;
     112             : 
     113             : #ifdef DEBUG_MODE_DFT
     114             :         hConfig->itd_mode = 0;
     115             :         hConfig->gipd_mode = 0;
     116             : #endif
     117       32652 :         hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF;
     118             : 
     119       32652 :         hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF;
     120       32652 :         hConfig->ada_wb_res_cod_mode = 0;
     121             : 
     122       32652 :         hConfig->hybrid_itd_flag = 0;
     123             :     }
     124             : 
     125       32652 :     return;
     126             : }
     127             : 
     128             : 
     129             : /*-------------------------------------------------------------------*
     130             :  * ivas_sba_dirac_stereo_band_config()
     131             :  *
     132             :  * Band Configuration for SBA DirAC stereo output
     133             :  *-------------------------------------------------------------------*/
     134             : 
     135       32364 : static int16_t ivas_sba_dirac_stereo_band_config(
     136             :     int16_t *band_limits,    /* o  : DFT band limits                     */
     137             :     const int32_t output_Fs, /* i  : output sampling rate                */
     138             :     const int16_t NFFT,      /* i  : analysis/synthesis window length    */
     139             :     const int16_t spar_flag  /* i  : SPAR or DirAC band grouping         */
     140             : )
     141             : {
     142             :     int16_t i;
     143             :     int16_t bins_per_cldfb_band;
     144             :     int16_t nbands, num_cldfb_bands;
     145             : 
     146       32364 :     nbands = SBA_DIRAC_STEREO_NUM_BANDS;
     147             : 
     148       32364 :     if ( spar_flag )
     149             :     {
     150       28830 :         nbands = IVAS_MAX_NUM_BANDS;
     151             :     }
     152             :     else
     153             :     {
     154        3534 :         nbands = 5;
     155             :     }
     156             : 
     157       32364 :     num_cldfb_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
     158             : 
     159       32364 :     bins_per_cldfb_band = NFFT / ( 2 * num_cldfb_bands );
     160             : 
     161       32364 :     band_limits[0] = 1;
     162      345630 :     for ( i = 1; i < nbands; i++ )
     163             :     {
     164      331266 :         if ( spar_flag )
     165             :         {
     166      317130 :             band_limits[i] = DirAC_band_grouping_12[i] * bins_per_cldfb_band;
     167             :         }
     168             :         else
     169             :         {
     170       14136 :             band_limits[i] = DirAC_band_grouping_5[i] * bins_per_cldfb_band;
     171             :         }
     172      331266 :         if ( band_limits[i] >= NFFT / 2 )
     173             :         {
     174       18000 :             nbands = i;
     175       18000 :             break;
     176             :         }
     177             :     }
     178       32364 :     band_limits[nbands] = NFFT / 2;
     179             : 
     180       32364 :     return nbands;
     181             : }
     182             : 
     183             : 
     184       70680 : static float get_panning(
     185             :     const int16_t aziDeg,
     186             :     const int16_t eleDeg )
     187             : {
     188             :     float aziRad, eleRad, y, mappedX, aziRadMapped, panning;
     189             :     float A, A2, A3;
     190       70680 :     const float LsAngleRad = 30.0f * PI_OVER_180;
     191             : 
     192       70680 :     aziRad = aziDeg * PI_OVER_180;
     193       70680 :     eleRad = eleDeg * PI_OVER_180;
     194       70680 :     y = ( sinf( aziRad ) * cosf( eleRad ) );
     195       70680 :     mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) );
     196       70680 :     aziRadMapped = atan2f( y, mappedX );
     197             : 
     198             :     /* Determine the real valued amplitude panning gains */
     199       70680 :     panning = 0.0f;
     200       70680 :     if ( aziRadMapped >= LsAngleRad )
     201             :     { /* Left side */
     202        1728 :         panning = 1.0f;
     203             :     }
     204       68952 :     else if ( aziRadMapped <= -LsAngleRad )
     205             :     { /* Right side */
     206       13629 :         panning = -1.0f;
     207             :     }
     208             :     else /* Tangent panning law */
     209             :     {
     210       55323 :         A = tanf( aziRadMapped ) / tanf( LsAngleRad );
     211       55323 :         A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f );
     212       55323 :         A3 = 1.0f / ( A2 * A2 + 1.0f );
     213       55323 :         panning = 2 * A3 - 1.0f;
     214             :     }
     215       70680 :     return panning;
     216             : }
     217             : 
     218             : 
     219             : /*-------------------------------------------------------------------*
     220             :  * map_params_dirac_to_stereo()
     221             :  *
     222             :  * Compute DFT Stereo parameters from DirAC parameters
     223             :  *-------------------------------------------------------------------*/
     224             : 
     225       32364 : static void map_params_dirac_to_stereo(
     226             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft,  /* i/o: decoder DFT stereo handle           */
     227             :     const IVAS_QMETADATA_HANDLE hQMetaData, /* i  : frame of MASA q_metadata            */
     228             :     float synth[],                          /* i  : decoded downmix signal              */
     229             :     float DFT[STEREO_DFT_BUF_MAX],          /* i/o: DFT buffer                          */
     230             :     const uint8_t b_wide_panning,           /* i  : flag indicating wider panning       */
     231             :     const int16_t L_frame,                  /* i  : core signal length                  */
     232             :     const int16_t mcmasa                    /* i  : McMASA flag                         */
     233             : )
     234             : {
     235             :     int16_t i, b, k;
     236             :     int16_t k_offset;
     237             :     int16_t nbands, nBlocks;
     238             :     int16_t block;
     239             :     int16_t block_len;
     240             :     int16_t azimuth[MAX_PARAM_SPATIAL_SUBFRAMES][SBA_DIRAC_STEREO_NUM_BANDS];
     241             :     int16_t elevation[MAX_PARAM_SPATIAL_SUBFRAMES][SBA_DIRAC_STEREO_NUM_BANDS];
     242             :     float diffuseness[SBA_DIRAC_STEREO_NUM_BANDS];
     243             :     float block_nrg[MAX_PARAM_SPATIAL_SUBFRAMES];
     244             :     float nrg_norm1, nrg_norm2;
     245             :     float *pSynth;
     246             :     float surrCoh[SBA_DIRAC_STEREO_NUM_BANDS];
     247             :     float *pDFT;
     248             :     float subframe_band_nrg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
     249             :     float smooth_long_avg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
     250             :     float smooth_short_avg[NB_DIV][SBA_DIRAC_STEREO_NUM_BANDS];
     251             :     float *side_gain, *res_pred_gain;
     252             :     IVAS_QDIRECTION *q_direction;
     253             : 
     254       32364 :     nBlocks = MAX_PARAM_SPATIAL_SUBFRAMES;
     255       32364 :     nbands = hStereoDft->nbands;
     256       32364 :     k_offset = STEREO_DFT_OFFSET;
     257       32364 :     side_gain = hStereoDft->side_gain + k_offset * STEREO_DFT_BAND_MAX;
     258       32364 :     res_pred_gain = hStereoDft->res_pred_gain + k_offset * STEREO_DFT_BAND_MAX;
     259       32364 :     q_direction = &( hQMetaData->q_direction[0] );
     260             : 
     261             :     /* gain smoothing factor */
     262       32364 :     pDFT = DFT;
     263       97092 :     for ( k = 0; k < NB_DIV; k++ )
     264             :     {
     265      755988 :         for ( b = 0; b < hStereoDft->nbands; b++ )
     266             :         {
     267             :             /* calculate band-wise subframe energies */
     268      691260 :             subframe_band_nrg[k][b] = 0.f;
     269    25908132 :             for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ )
     270             :             {
     271    25216872 :                 subframe_band_nrg[k][b] += pDFT[2 * i] * pDFT[2 * i] + pDFT[2 * i + 1] * pDFT[2 * i + 1];
     272             :             }
     273      691260 :             subframe_band_nrg[k][b] = sqrtf( subframe_band_nrg[k][b] );
     274      691260 :             hStereoDft->smooth_buf[b][NB_DIV - 1 - k] = subframe_band_nrg[k][b];
     275             : 
     276             :             /* calculate short and long energy averages */
     277      691260 :             smooth_short_avg[k][b] = EPSILON;
     278     2765040 :             for ( i = NB_DIV - 1 - k; i < SBA_DIRAC_NRG_SMOOTH_SHORT + NB_DIV - 1 - k; i++ )
     279             :             {
     280     2073780 :                 smooth_short_avg[k][b] += hStereoDft->smooth_buf[b][i];
     281             :             }
     282             : 
     283      691260 :             smooth_long_avg[k][b] = smooth_short_avg[k][b];
     284     5530080 :             for ( i = NB_DIV - 1 - k + SBA_DIRAC_NRG_SMOOTH_SHORT; i < SBA_DIRAC_NRG_SMOOTH_LONG + NB_DIV - 1 - k; i++ )
     285             :             {
     286     4838820 :                 smooth_long_avg[k][b] += hStereoDft->smooth_buf[b][i];
     287             :             }
     288      691260 :             smooth_short_avg[k][b] /= SBA_DIRAC_NRG_SMOOTH_SHORT;
     289      691260 :             smooth_long_avg[k][b] /= SBA_DIRAC_NRG_SMOOTH_LONG;
     290             : 
     291             :             /* calculate smoothing factor based on energy averages */
     292             :             /* reduce factor for higher short-term energy */
     293      691260 :             hStereoDft->smooth_fac[k][b] = min( 1.f, smooth_long_avg[k][b] / smooth_short_avg[k][b] );
     294             :             /* map factor to range [0;1] */
     295      691260 :             hStereoDft->smooth_fac[k][b] = max( 0.f, hStereoDft->smooth_fac[k][b] - (float) SBA_DIRAC_NRG_SMOOTH_SHORT / SBA_DIRAC_NRG_SMOOTH_LONG ) * ( (float) SBA_DIRAC_NRG_SMOOTH_LONG / ( SBA_DIRAC_NRG_SMOOTH_LONG - SBA_DIRAC_NRG_SMOOTH_SHORT ) );
     296             :             /* compress factor (higher compression in lowest bands) */
     297      691260 :             if ( b < 2 )
     298             :             {
     299      129456 :                 hStereoDft->smooth_fac[k][b] = powf( hStereoDft->smooth_fac[k][b], 0.25f );
     300             :             }
     301             :             else
     302             :             {
     303      561804 :                 hStereoDft->smooth_fac[k][b] = powf( hStereoDft->smooth_fac[k][b], 0.5f );
     304             :             }
     305             : 
     306             :             /* apply upper bounds depending on band */
     307      691260 :             hStereoDft->smooth_fac[0][b] = max( hStereoDft->min_smooth_gains[b], min( hStereoDft->max_smooth_gains[b], hStereoDft->smooth_fac[0][b] ) );
     308      691260 :             hStereoDft->smooth_fac[1][b] = max( hStereoDft->min_smooth_gains[b], min( hStereoDft->max_smooth_gains[b], hStereoDft->smooth_fac[1][b] ) );
     309             :         }
     310       64728 :         pDFT += STEREO_DFT32MS_N_MAX;
     311             :     }
     312             : 
     313       32364 :     if ( mcmasa )
     314             :     {
     315             :         /* calculate block energies for side gain weighting (combine angles of 2 DirAC blocks to side gain for 1 DFT Stereo subframe; 4 blocks and 2 subframes overall) */
     316        3534 :         pSynth = synth;
     317        3534 :         block_len = L_frame / nBlocks;
     318       17670 :         for ( block = 0; block < nBlocks; block++ )
     319             :         {
     320       14136 :             block_nrg[block] = 0.f;
     321     1145016 :             for ( i = 0; i < block_len; i++ )
     322             :             {
     323     1130880 :                 block_nrg[block] += pSynth[i] * pSynth[i];
     324             :             }
     325       14136 :             block_nrg[block] = sqrtf( block_nrg[block] );
     326       14136 :             pSynth += block_len;
     327             :         }
     328        3534 :         nrg_norm1 = 1 / ( block_nrg[0] + block_nrg[1] + EPSILON );
     329        3534 :         nrg_norm2 = 1 / ( block_nrg[2] + block_nrg[3] + EPSILON );
     330             : 
     331             :         /* extract DirAC parameters from metadata */
     332       21204 :         for ( b = 0; b < nbands; b++ )
     333             :         {
     334       17670 :             diffuseness[b] = 1.0f - q_direction->band_data[b].energy_ratio[0];
     335       17670 :             if ( hQMetaData->surcoh_band_data != NULL )
     336             :             {
     337       17670 :                 surrCoh[b] = hQMetaData->surcoh_band_data[b].surround_coherence[0] / 255.0f;
     338             :             }
     339             :             else
     340             :             {
     341           0 :                 surrCoh[b] = 0.0f;
     342             :             }
     343             : 
     344       88350 :             for ( block = 0; block < nBlocks; block++ )
     345             :             {
     346             :                 int16_t block_metadata;
     347             : 
     348       70680 :                 if ( hQMetaData->useLowerRes )
     349             :                 {
     350           0 :                     block_metadata = 0;
     351             :                 }
     352             :                 else
     353             :                 {
     354       70680 :                     block_metadata = block;
     355             :                 }
     356       70680 :                 if ( q_direction->band_data[b].azimuth[block_metadata] < 0.f )
     357             :                 {
     358       27327 :                     q_direction->band_data[b].azimuth[block_metadata] += 360.f;
     359             :                 }
     360       70680 :                 azimuth[block][b] = (int16_t) q_direction->band_data[b].azimuth[block_metadata];
     361       70680 :                 elevation[block][b] = (int16_t) q_direction->band_data[b].elevation[block_metadata];
     362             :             }
     363             :         }
     364             : 
     365             :         /* map angles (azi, ele), surround coherence, and diffuseness to DFT Stereo side and prediction gains */
     366       21204 :         for ( b = 0; b < hStereoDft->nbands; b++ )
     367             :         {
     368             :             /* combine angles of first 2 blocks to side gain of first subframe */
     369       17670 :             side_gain[b] = 0.f;
     370       53010 :             for ( block = 0; block < nBlocks / 2; block++ )
     371             :             {
     372       35340 :                 if ( b_wide_panning == 1 )
     373             :                 {
     374             :                     /* panning between left and ride, saturate at the stereo ls positions (+/- 30deg azi) */
     375       35340 :                     side_gain[b] += nrg_norm1 * block_nrg[block] * get_panning( azimuth[block][b], elevation[block][b] );
     376             :                 }
     377             :                 else
     378             :                 {
     379           0 :                     side_gain[b] += nrg_norm1 * block_nrg[block] * sinf( azimuth[block][b] * EVS_PI / 180 ) * cosf( elevation[block][b] * EVS_PI / 180 );
     380             :                 }
     381             :             }
     382             : 
     383             :             /* combine angles of last 2 blocks to side gain of second subframe */
     384       17670 :             side_gain[b + STEREO_DFT_BAND_MAX] = 0.f;
     385       53010 :             for ( block = nBlocks / 2; block < nBlocks; block++ )
     386             :             {
     387       35340 :                 if ( b_wide_panning == 1 )
     388             :                 {
     389             :                     /* panning between left and ride, saturate at the stereo ls positions (+/- 30deg azi) */
     390       35340 :                     side_gain[b + STEREO_DFT_BAND_MAX] += nrg_norm2 * block_nrg[block] * get_panning( azimuth[block][b], elevation[block][b] );
     391             :                 }
     392             :                 else
     393             :                 {
     394           0 :                     side_gain[b + STEREO_DFT_BAND_MAX] += nrg_norm2 * block_nrg[block] * sinf( azimuth[block][b] * EVS_PI / 180 ) * cosf( elevation[block][b] * EVS_PI / 180 );
     395             :                 }
     396             :             }
     397             : 
     398             :             /* Clamp values here. [-1, 1] is the allowed range, but due to precision issues they can be slightly off which can cause problems later. */
     399       17670 :             side_gain[b] *= sqrtf( 1.f - diffuseness[b] );
     400       17670 :             side_gain[b] = max( min( side_gain[b], 1 ), -1 );
     401       17670 :             side_gain[b + STEREO_DFT_BAND_MAX] *= sqrtf( 1.f - diffuseness[b] );
     402       17670 :             side_gain[b + STEREO_DFT_BAND_MAX] = max( min( side_gain[b + STEREO_DFT_BAND_MAX], 1 ), -1 );
     403             :             /* for residual prediction gain, allowed range is [0, 1]*/
     404       17670 :             res_pred_gain[b] = diffuseness[b] * ( 1.0f - surrCoh[b] );
     405       17670 :             res_pred_gain[b] = max( min( res_pred_gain[b], 1 ), 0 );
     406       17670 :             res_pred_gain[b + STEREO_DFT_BAND_MAX] = diffuseness[b] * ( 1.0f - surrCoh[b] );
     407       17670 :             res_pred_gain[b + STEREO_DFT_BAND_MAX] = max( min( res_pred_gain[b + STEREO_DFT_BAND_MAX], 1 ), 0 );
     408             :         }
     409             :     }
     410             : 
     411       32364 :     hStereoDft->frame_nodata = 0;
     412       32364 :     hStereoDft->frame_sid_nodata = 0;
     413       32364 :     hStereoDft->frame_sid = 0;
     414             : 
     415       32364 :     return;
     416             : }
     417             : 
     418             : 
     419             : /*-------------------------------------------------------------------*
     420             :  * ivas_sba_dirac_stereo_compute_td_stefi_nrgs()
     421             :  *
     422             :  * Compute energies for TD stereo filling
     423             :  *-------------------------------------------------------------------*/
     424             : 
     425       13536 : static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs(
     426             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle           */
     427             :     const float hb_synth[L_FRAME48k],      /* i  : HB signal                           */
     428             :     const int16_t core,                    /* i  : core decision                       */
     429             :     const int16_t output_frame,            /* i  : output frame length per channel     */
     430             :     const int16_t fd_cng_flag              /* i  : FD-CNG indicator                    */
     431             : )
     432             : {
     433             :     int16_t i;
     434       13536 :     float hb_nrg = EPSILON;
     435       13536 :     float hb_nrg2 = EPSILON;
     436             : 
     437       13536 :     if ( ( core == ACELP_CORE && !fd_cng_flag ) || hStereoDft->core_hist[1] == ACELP_CORE )
     438             :     {
     439     2540073 :         for ( i = 0; i < output_frame / 2; i++ )
     440             :         {
     441     2533440 :             hb_nrg2 += hb_synth[i] * hb_synth[i];
     442             :         }
     443             : 
     444        6633 :         hStereoDft->hb_nrg_subr[0] = hb_nrg2;
     445        6633 :         hb_nrg += hb_nrg2;
     446        6633 :         hb_nrg2 = EPSILON;
     447             : 
     448     2540073 :         for ( ; i < output_frame; i++ )
     449             :         {
     450     2533440 :             hb_nrg2 += hb_synth[i] * hb_synth[i];
     451             :         }
     452             : 
     453        6633 :         hStereoDft->hb_nrg_subr[1] = hb_nrg2;
     454        6633 :         hb_nrg += hb_nrg2;
     455             : 
     456        6633 :         mvr2r( hb_synth, hStereoDft->hb_stefi_sig + hStereoDft->hb_stefi_delay, output_frame );
     457             :     }
     458             :     else
     459             :     {
     460        6903 :         set_zero( hStereoDft->hb_stefi_sig + hStereoDft->hb_stefi_delay, output_frame );
     461             :     }
     462             : 
     463       13536 :     hStereoDft->hb_nrg_subr[0] *= hStereoDft->NFFT / 2;
     464       13536 :     hStereoDft->hb_nrg_subr[1] *= hStereoDft->NFFT / 2;
     465       13536 :     hStereoDft->hb_nrg[0] = hb_nrg;
     466       13536 :     hStereoDft->td_gain[0] = 0;
     467       13536 :     hStereoDft->core_hist[0] = ( fd_cng_flag ) ? TCX_20_CORE : core; /* full signal available for DTX with FD-CNG, thus apply stereo filling on full spectrum like in TCX */
     468             : 
     469       13536 :     return;
     470             : }
     471             : 
     472             : 
     473             : /*-------------------------------------------------------------------*
     474             :  * ivas_sba_dirac_stereo_compute_hb_gain()
     475             :  *
     476             :  * Compute HB gains
     477             :  *-------------------------------------------------------------------*/
     478             : 
     479        6147 : static void ivas_sba_dirac_stereo_compute_hb_gain(
     480             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle           */
     481             :     float hb_gain[NB_DIV]                  /* o  : side gains for HB signal            */
     482             : )
     483             : {
     484             :     int16_t k_offset;
     485             : 
     486        6147 :     k_offset = STEREO_DFT_OFFSET;
     487             : 
     488             :     /* last band covers whole HB range, no averaging needed */
     489        6147 :     hb_gain[0] = hStereoDft->side_gain[k_offset * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1];
     490        6147 :     hb_gain[1] = hStereoDft->side_gain[( k_offset + 1 ) * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1];
     491             : 
     492        6147 :     return;
     493             : }
     494             : 
     495             : 
     496             : /*-------------------------------------------------------------------*
     497             :  * ivas_sba_dirac_stereo_upmix_hb()
     498             :  *
     499             :  * Apply panning to HB signal
     500             :  *-------------------------------------------------------------------*/
     501             : 
     502        6147 : static void ivas_sba_dirac_stereo_upmix_hb(
     503             :     float hb_stereo_synth[CPE_CHANNELS][L_FRAME48k], /* i/o: stereo HB synthesis signal           */
     504             :     float hb_synth[L_FRAME48k],                      /* i  : HB signal                            */
     505             :     float hb_gain[NB_DIV],                           /* i  : side gains for HB signal             */
     506             :     const int16_t output_frame,                      /* i  : output frame length per channel      */
     507             :     const int16_t mcmasa,                            /* i  : McMASA flag                          */
     508             :     const int16_t sba_mono_flag,                     /* i  : flag for mono output                 */
     509             :     const int16_t bwidth,                            /* i  : bandwidth of signal                  */
     510             :     const STEREO_DFT_DEC_DATA_HANDLE hStereoDft      /* i  : Stereo DFT handle for mixing matrix  */
     511             : )
     512             : {
     513             :     int16_t i;
     514             :     float gp, gm;
     515             :     float gain_fac;
     516             : 
     517        6147 :     if ( !mcmasa )
     518             :     {
     519        5079 :         gain_fac = ( bwidth == FB ) ? 0.25f : 0.33f; /* last matrix element not used for SWB, divide by 3 instead of 4*/
     520        5079 :         if ( sba_mono_flag )
     521             :         {
     522         633 :             gp = hStereoDft->mixer_mat_smooth[0][0][8] + hStereoDft->mixer_mat_smooth[0][0][9] +
     523         633 :                  hStereoDft->mixer_mat_smooth[0][0][10];
     524         633 :             if ( bwidth == FB )
     525             :             {
     526          54 :                 gp += hStereoDft->mixer_mat_smooth[0][0][11];
     527             :             }
     528      304473 :             for ( i = 0; i < output_frame / 2; i++ )
     529             :             {
     530      303840 :                 hb_stereo_synth[0][i] = hb_synth[i] * gain_fac * gp;
     531             :             }
     532         633 :             gp = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] +
     533         633 :                  hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS];
     534         633 :             if ( bwidth == FB )
     535             :             {
     536          54 :                 gp += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS];
     537             :             }
     538      304473 :             for ( i = output_frame / 2; i < output_frame; i++ )
     539             :             {
     540      303840 :                 hb_stereo_synth[0][i] = hb_synth[i] * gain_fac * gp;
     541             :             }
     542             :         }
     543             :         else
     544             :         {
     545        4446 :             gp = hStereoDft->mixer_mat_smooth[0][0][8] + hStereoDft->mixer_mat_smooth[1][0][8] +
     546        4446 :                  hStereoDft->mixer_mat_smooth[0][0][9] + hStereoDft->mixer_mat_smooth[1][0][9] +
     547        4446 :                  hStereoDft->mixer_mat_smooth[0][0][10] + hStereoDft->mixer_mat_smooth[1][0][10];
     548        4446 :             if ( bwidth == FB )
     549             :             {
     550          99 :                 gp += hStereoDft->mixer_mat_smooth[0][0][11] + hStereoDft->mixer_mat_smooth[1][0][11];
     551             :             }
     552             : 
     553        4446 :             gm = hStereoDft->mixer_mat_smooth[0][0][8] - hStereoDft->mixer_mat_smooth[1][0][8] +
     554        4446 :                  hStereoDft->mixer_mat_smooth[0][0][9] - hStereoDft->mixer_mat_smooth[1][0][9] +
     555        4446 :                  hStereoDft->mixer_mat_smooth[0][0][10] - hStereoDft->mixer_mat_smooth[1][0][10];
     556        4446 :             if ( bwidth == FB )
     557             :             {
     558          99 :                 gm += hStereoDft->mixer_mat_smooth[0][0][11] - hStereoDft->mixer_mat_smooth[1][0][11];
     559             :             }
     560             : 
     561     1526526 :             for ( i = 0; i < output_frame / 2; i++ )
     562             :             {
     563     1522080 :                 hb_stereo_synth[0][i] = 0.5f * hb_synth[i] * gain_fac * gp;
     564     1522080 :                 hb_stereo_synth[1][i] = 0.5f * hb_synth[i] * gain_fac * gm;
     565             :             }
     566             : 
     567        4446 :             gp = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][8 + IVAS_MAX_NUM_BANDS] +
     568        4446 :                  hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][9 + IVAS_MAX_NUM_BANDS] +
     569        4446 :                  hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][10 + IVAS_MAX_NUM_BANDS];
     570        4446 :             if ( bwidth == FB )
     571             :             {
     572          99 :                 gp += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][0][11 + IVAS_MAX_NUM_BANDS];
     573             :             }
     574             : 
     575        4446 :             gm = hStereoDft->mixer_mat_smooth[0][0][8 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][8 + IVAS_MAX_NUM_BANDS] +
     576        4446 :                  hStereoDft->mixer_mat_smooth[0][0][9 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][9 + IVAS_MAX_NUM_BANDS] +
     577        4446 :                  hStereoDft->mixer_mat_smooth[0][0][10 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][10 + IVAS_MAX_NUM_BANDS];
     578        4446 :             if ( bwidth == FB )
     579             :             {
     580          99 :                 gm += hStereoDft->mixer_mat_smooth[0][0][11 + IVAS_MAX_NUM_BANDS] - hStereoDft->mixer_mat_smooth[1][0][11 + IVAS_MAX_NUM_BANDS];
     581             :             }
     582             : 
     583     1526526 :             for ( i = output_frame / 2; i < output_frame; i++ )
     584             :             {
     585     1522080 :                 hb_stereo_synth[0][i] = 0.5f * hb_synth[i] * gain_fac * gp;
     586     1522080 :                 hb_stereo_synth[1][i] = 0.5f * hb_synth[i] * gain_fac * gm;
     587             :             }
     588             :         }
     589             :     }
     590             :     else
     591             :     {
     592      511308 :         for ( i = 0; i < output_frame / 2; i++ )
     593             :         {
     594      510240 :             hb_stereo_synth[0][i] = 0.5f * hb_synth[i] + 0.5f * hb_gain[0] * hb_synth[i];
     595      510240 :             hb_stereo_synth[1][i] = 0.5f * hb_synth[i] - 0.5f * hb_gain[0] * hb_synth[i];
     596             :         }
     597             : 
     598      511308 :         for ( i = output_frame / 2; i < output_frame; i++ )
     599             :         {
     600      510240 :             hb_stereo_synth[0][i] = 0.5f * hb_synth[i] + 0.5f * hb_gain[1] * hb_synth[i];
     601      510240 :             hb_stereo_synth[1][i] = 0.5f * hb_synth[i] - 0.5f * hb_gain[1] * hb_synth[i];
     602             :         }
     603             :     }
     604             : 
     605        6147 :     return;
     606             : }
     607             : 
     608             : 
     609             : /*-------------------------------------------------------------------*
     610             :  * ivas_sba_dirac_stereo_apply_td_stefi()
     611             :  *
     612             :  * Apply TD stereo filling for ACELP HB
     613             :  *-------------------------------------------------------------------*/
     614             : 
     615        5514 : static void ivas_sba_dirac_stereo_apply_td_stefi(
     616             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle       */
     617             :     float *output[CPE_CHANNELS],           /* i/o: output synthesis signal         */
     618             :     const int16_t output_frame,            /* i  : output frame length per channel */
     619             :     const int16_t spar_flag                /* i  : SPAR flag                       */
     620             : )
     621             : {
     622             :     int16_t i;
     623             :     int16_t dftOvlLen;
     624             :     float win_in, win_out;
     625             :     float tmp;
     626             :     const float *win_dft;
     627             : 
     628        5514 :     if ( spar_flag )
     629             :     {
     630        4446 :         win_dft = hStereoDft->win32ms;
     631        4446 :         dftOvlLen = hStereoDft->dft32ms_ovl;
     632             : 
     633             :         float g_W_1, g_Y_1;
     634             :         float g_W_2, g_Y_2;
     635             :         float g_L, g_R;
     636             :         float stefi_L, stefi_R;
     637             : 
     638        4446 :         g_W_1 = ( hStereoDft->mixer_mat_smooth[0][1][8] + hStereoDft->mixer_mat_smooth[0][2][8] + hStereoDft->mixer_mat_smooth[0][3][8] ) + ( hStereoDft->mixer_mat_smooth[0][1][9] + hStereoDft->mixer_mat_smooth[0][2][9] + hStereoDft->mixer_mat_smooth[0][3][9] ) + ( hStereoDft->mixer_mat_smooth[0][1][10] + hStereoDft->mixer_mat_smooth[0][2][10] + hStereoDft->mixer_mat_smooth[0][3][10] );
     639             : 
     640        4446 :         g_Y_1 = ( hStereoDft->mixer_mat_smooth[1][1][8] + hStereoDft->mixer_mat_smooth[1][2][8] + hStereoDft->mixer_mat_smooth[1][3][8] ) + ( hStereoDft->mixer_mat_smooth[1][1][9] + hStereoDft->mixer_mat_smooth[1][2][9] + hStereoDft->mixer_mat_smooth[1][3][9] ) + ( hStereoDft->mixer_mat_smooth[1][1][10] + hStereoDft->mixer_mat_smooth[1][2][10] + hStereoDft->mixer_mat_smooth[1][3][10] );
     641             : 
     642        4446 :         g_W_2 = ( hStereoDft->mixer_mat_smooth[0][1][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][8 + IVAS_MAX_NUM_BANDS] ) + ( hStereoDft->mixer_mat_smooth[0][1][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][9 + IVAS_MAX_NUM_BANDS] ) + ( hStereoDft->mixer_mat_smooth[0][1][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][2][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[0][3][10 + IVAS_MAX_NUM_BANDS] );
     643             : 
     644        4446 :         g_Y_2 = ( hStereoDft->mixer_mat_smooth[1][1][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][8 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][8 + IVAS_MAX_NUM_BANDS] ) + ( hStereoDft->mixer_mat_smooth[1][1][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][9 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][9 + IVAS_MAX_NUM_BANDS] ) + ( hStereoDft->mixer_mat_smooth[1][1][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][2][10 + IVAS_MAX_NUM_BANDS] + hStereoDft->mixer_mat_smooth[1][3][10 + IVAS_MAX_NUM_BANDS] );
     645             : 
     646        4446 :         g_L = 0.16f * ( g_W_1 + g_W_2 - g_Y_1 - g_Y_2 );
     647        4446 :         g_R = 0.16f * ( g_W_1 + g_W_2 + g_Y_1 + g_Y_2 );
     648             : 
     649      480096 :         for ( i = 0; i < dftOvlLen; i++ )
     650             :         {
     651      475650 :             win_in = win_dft[STEREO_DFT32MS_STEP * i] * win_dft[STEREO_DFT32MS_STEP * i];
     652      475650 :             win_out = 1 - win_in;
     653             : 
     654      475650 :             stefi_L = ( win_out * hStereoDft->g_L_prev + win_in * g_L ) * 0.5f * hStereoDft->hb_stefi_sig[i];
     655      475650 :             stefi_R = ( win_out * hStereoDft->g_R_prev + win_in * g_R ) * 0.5f * hStereoDft->hb_stefi_sig[i];
     656             : 
     657      475650 :             output[0][i] += stefi_L;
     658      475650 :             output[1][i] += stefi_R;
     659             :         }
     660     2572956 :         for ( i = dftOvlLen; i < output_frame; i++ )
     661             :         {
     662             : 
     663     2568510 :             stefi_L = g_L * 0.5f * hStereoDft->hb_stefi_sig[i];
     664     2568510 :             stefi_R = g_R * 0.5f * hStereoDft->hb_stefi_sig[i];
     665             : 
     666     2568510 :             output[0][i] += stefi_L;
     667     2568510 :             output[1][i] += stefi_R;
     668             :         }
     669        4446 :         hStereoDft->g_L_prev = g_L;
     670        4446 :         hStereoDft->g_R_prev = g_R;
     671             :     }
     672        1068 :     else if ( max( hStereoDft->td_gain[0], hStereoDft->td_gain[1] ) > 0 )
     673             :     {
     674         975 :         win_dft = hStereoDft->win32ms;
     675         975 :         dftOvlLen = hStereoDft->dft32ms_ovl;
     676             : 
     677      147225 :         for ( i = 0; i < dftOvlLen; i++ )
     678             :         {
     679      146250 :             win_in = win_dft[STEREO_DFT32MS_STEP * i] * win_dft[STEREO_DFT32MS_STEP * i];
     680      146250 :             win_out = 1 - win_in;
     681      146250 :             tmp = ( win_in * hStereoDft->td_gain[0] + win_out * hStereoDft->td_gain[1] ) * 0.5f * hStereoDft->hb_stefi_sig[i];
     682             : 
     683      146250 :             output[0][i] += tmp;
     684      146250 :             output[1][i] -= tmp;
     685             :         }
     686      790725 :         for ( i = dftOvlLen; i < output_frame; i++ )
     687             :         {
     688      789750 :             tmp = hStereoDft->td_gain[0] * 0.5f * hStereoDft->hb_stefi_sig[i];
     689      789750 :             output[0][i] += tmp;
     690      789750 :             output[1][i] -= tmp;
     691             :         }
     692             :     }
     693             : 
     694        5514 :     return;
     695             : }
     696             : 
     697             : 
     698             : /*-------------------------------------------------------------------*
     699             :  * ivas_sba_dirac_stereo_smooth_parameters()
     700             :  *
     701             :  * Smooth DFT Stereo parameters
     702             :  *-------------------------------------------------------------------*/
     703             : 
     704       32043 : void ivas_sba_dirac_stereo_smooth_parameters(
     705             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle            */
     706             :     ivas_spar_md_dec_state_t *hMdDec,      /* i/o: SPAR MD handle for upmixing          */
     707             :     const int16_t cross_fade_start_offset, /* i  : SPAR mixer delay compensation        */
     708             :     const int32_t output_Fs,               /* i  : Fs for delay calculation             */
     709             :     const int16_t num_md_sub_frames        /* i  : number of subframes in mixing matrix */
     710             : )
     711             : {
     712             :     int16_t i, j, k, i_sf;
     713             :     int16_t b;
     714             :     int16_t k_offset;
     715             :     float *side_gain, *prev_side_gain;
     716             :     float *res_pred_gain, *prev_res_pred_gain;
     717             : 
     718       32043 :     k_offset = STEREO_DFT_OFFSET;
     719       32043 :     prev_side_gain = hStereoDft->side_gain;
     720       32043 :     side_gain = hStereoDft->side_gain + k_offset * STEREO_DFT_BAND_MAX;
     721       32043 :     prev_res_pred_gain = hStereoDft->res_pred_gain;
     722       32043 :     res_pred_gain = hStereoDft->res_pred_gain + k_offset * STEREO_DFT_BAND_MAX;
     723             : 
     724       32043 :     if ( !hMdDec )
     725             :     {
     726             :         /* Smoothing of side and prediction gains between ftrames */
     727       21078 :         for ( b = hStereoDft->res_pred_band_min; b < hStereoDft->nbands; b++ )
     728             :         {
     729       17565 :             if ( hStereoDft->attackPresent )
     730             :             {
     731           0 :                 res_pred_gain[b] *= 0.8f;
     732           0 :                 res_pred_gain[b + STEREO_DFT_BAND_MAX] *= 0.8f;
     733             :             }
     734             :             else
     735             :             {
     736       17565 :                 side_gain[b] = hStereoDft->smooth_fac[0][b] * prev_side_gain[b] + ( 1.f - hStereoDft->smooth_fac[0][b] ) * side_gain[b];
     737       17565 :                 side_gain[b + STEREO_DFT_BAND_MAX] = hStereoDft->smooth_fac[1][b] * side_gain[b] + ( 1.f - hStereoDft->smooth_fac[1][b] ) * side_gain[b + STEREO_DFT_BAND_MAX];
     738       17565 :                 res_pred_gain[b] = hStereoDft->smooth_fac[0][b] * prev_res_pred_gain[b] + ( 1.f - hStereoDft->smooth_fac[0][b] ) * res_pred_gain[b];
     739       17565 :                 res_pred_gain[b + STEREO_DFT_BAND_MAX] = hStereoDft->smooth_fac[1][b] * res_pred_gain[b] + ( 1.f - hStereoDft->smooth_fac[1][b] ) * res_pred_gain[b + STEREO_DFT_BAND_MAX];
     740             :             }
     741             :         }
     742             :     }
     743             : 
     744       32043 :     if ( hMdDec != 0 )
     745             :     {
     746             :         float xfade_start_ns;
     747             :         int16_t xfade_delay_subframes;
     748             :         int16_t i_hist;
     749             :         int16_t md_sf;
     750             : 
     751       28530 :         xfade_start_ns = cross_fade_start_offset / (float) output_Fs * 1000000000.f - IVAS_FB_ENC_DELAY_NS;
     752       28530 :         xfade_delay_subframes = (int16_t) ( xfade_start_ns / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) );
     753             : 
     754       28530 :         i_hist = 4 - xfade_delay_subframes;
     755             : 
     756       85590 :         for ( k = 0; k < 2; k++ )
     757             :         {
     758      171180 :             for ( i_sf = k * 2; i_sf < ( k + 1 ) * 2; i_sf++ )
     759             :             {
     760             : 
     761      114120 :                 md_sf = ( num_md_sub_frames == MAX_PARAM_SPATIAL_SUBFRAMES ) ? i_sf : 0;
     762             : 
     763      114120 :                 if ( hStereoDft->first_frame )
     764             :                 {
     765        3276 :                     for ( i = 0; i < 2; i++ )
     766             :                     {
     767       10920 :                         for ( j = 0; j < 4; j++ )
     768             :                         {
     769      110400 :                             for ( b = 0; b < hStereoDft->nbands; b++ )
     770             :                             {
     771      101664 :                                 hStereoDft->mixer_mat_smooth[i][j][b + k * IVAS_MAX_NUM_BANDS] = hMdDec->mixer_mat[i][j][b];
     772             :                             }
     773       11904 :                             for ( ; b < IVAS_MAX_NUM_BANDS; b++ )
     774             :                             {
     775        3168 :                                 hStereoDft->mixer_mat_smooth[i][j][b + k * IVAS_MAX_NUM_BANDS] = 0.f;
     776             :                             }
     777             :                         }
     778             :                     }
     779             :                 }
     780             :                 else
     781             :                 {
     782      339084 :                     for ( i = 0; i < 2; i++ )
     783             :                     {
     784     1130280 :                         for ( j = 0; j < 4; j++ )
     785             :                         {
     786    11191680 :                             for ( b = 0; b < hStereoDft->nbands; b++ )
     787             :                             {
     788    10287456 :                                 float beta = hStereoDft->smooth_fac[k][b];
     789    10287456 :                                 hStereoDft->mixer_mat_smooth[i][j][b + k * IVAS_MAX_NUM_BANDS] =
     790    10287456 :                                     beta * hStereoDft->mixer_mat_smooth[i][j][b + k * IVAS_MAX_NUM_BANDS] + ( 1 - beta ) * hMdDec->mixer_mat_prev[i_hist][i][j][b];
     791             :                             }
     792             :                         }
     793             :                     }
     794             :                 }
     795             : 
     796      114120 :                 mvr2r( hMdDec->mixer_mat_prev[1][0][0], hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
     797      114120 :                 mvr2r( hMdDec->mixer_mat_prev[2][0][0], hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
     798      114120 :                 mvr2r( hMdDec->mixer_mat_prev[3][0][0], hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
     799      114120 :                 mvr2r( hMdDec->mixer_mat_prev[4][0][0], hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
     800             : 
     801      342360 :                 for ( i = 0; i < 2; i++ )
     802             :                 {
     803     1141200 :                     for ( j = 0; j < 4; j++ )
     804             :                     {
     805    11302080 :                         for ( b = 0; b < hStereoDft->nbands; b++ )
     806             :                         {
     807    10389120 :                             hMdDec->mixer_mat_prev[4][i][j][b] = hMdDec->mixer_mat[i][j][b + md_sf * IVAS_MAX_NUM_BANDS];
     808             :                         }
     809             :                     }
     810             :                 }
     811             :             }
     812             :         }
     813             : 
     814       28530 :         hStereoDft->first_frame = 0;
     815             :     }
     816             : 
     817       32043 :     return;
     818             : }
     819             : 
     820             : 
     821             : /*-------------------------------------------------------------------*
     822             :  * ivas_sba_dirac_stereo_dec()
     823             :  *
     824             :  * Create stereo output for SBA DirAC via DFT stereo
     825             :  *-------------------------------------------------------------------*/
     826             : 
     827       32364 : void ivas_sba_dirac_stereo_dec(
     828             :     Decoder_Struct *st_ivas,     /* i/o: IVAS decoder structure              */
     829             :     float *output[CPE_CHANNELS], /* i/o: output synthesis signal             */
     830             :     const int16_t output_frame,  /* i  : output frame length per channel     */
     831             :     const int16_t mcmasa         /* i  : McMASA flag                         */
     832             : )
     833             : {
     834             :     int16_t dtx_flag, fd_cng_flag;
     835             :     int16_t sba_mono_flag;
     836             :     int16_t memOffset;
     837             :     float tmp_buf[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )];
     838             :     float tmp_synth[L_FRAME16k];
     839             :     float hb_gain[NB_DIV];
     840             :     float hb_synth_stereo[CPE_CHANNELS][L_FRAME48k];
     841             :     float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX];
     842             :     SCE_DEC_HANDLE hSCE;
     843             :     CPE_DEC_HANDLE hCPE;
     844             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
     845             : 
     846       32364 :     hSCE = st_ivas->hSCE[0];
     847       32364 :     hCPE = st_ivas->hCPE[0];
     848       32364 :     hStereoDft = hCPE->hStereoDft;
     849             : 
     850       32364 :     if ( st_ivas->nchan_transport > 1 && !mcmasa )
     851             :     {
     852       18828 :         dtx_flag = 0;
     853       18828 :         fd_cng_flag = 0;
     854             :     }
     855             :     else
     856             :     {
     857       13536 :         dtx_flag = ( hSCE->hCoreCoder[0]->core_brate <= SID_2k40 );
     858       13536 :         fd_cng_flag = ( dtx_flag && hSCE->hCoreCoder[0]->cng_type == FD_CNG );
     859             :     }
     860       32364 :     sba_mono_flag = ( st_ivas->hDecoderConfig->nchan_out == 1 ) ? 1 : 0;
     861             : 
     862       32364 :     memOffset = NS2SA( output_frame * FRAMES_PER_SEC, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS );
     863             : 
     864       32364 :     ivas_sba_dirac_stereo_config( hStereoDft->hConfig );
     865       32364 :     hStereoDft->nbands = ivas_sba_dirac_stereo_band_config( hStereoDft->band_limits, st_ivas->hDecoderConfig->output_Fs, hStereoDft->NFFT, ( ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) && !mcmasa ) );
     866       32364 :     stereo_dft_dec_update( hStereoDft, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/ );
     867       32364 :     if ( st_ivas->nchan_transport > 1 )
     868             :     {
     869       18828 :         stereo_dft_dec_analyze( hCPE, output[0], DFT, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0 );
     870       18828 :         stereo_dft_dec_analyze( hCPE, output[1], DFT, 1, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0 );
     871       18828 :         hStereoDft->core_hist[0] = hCPE->hCoreCoder[0]->core;
     872             :     }
     873             :     else
     874             :     {
     875             :         /* nrg calculation for TD Stereo Filling, as done in ICBWE which is not used in this case */
     876       13536 :         ivas_sba_dirac_stereo_compute_td_stefi_nrgs( hStereoDft, hSCE->save_hb_synth, hSCE->hCoreCoder[0]->core, output_frame, fd_cng_flag );
     877             : 
     878             :         /* do DFT Stereo core switching (including DFT analysis) here as CPE element was not available in SCE decoder */
     879       13536 :         mvr2r( hSCE->save_synth, tmp_synth, hSCE->hCoreCoder[0]->L_frame );
     880       13536 :         stereo_dft_dec_core_switching( hCPE, output[0] /*hSCE->save_output*/, hSCE->save_synth, hSCE->save_hb_synth, DFT, output_frame, 0, dtx_flag );
     881             : 
     882             :         /* do updates here after skipping this in SCE decoder (needs to be done after core switching) */
     883       13536 :         updt_dec_common( hSCE->hCoreCoder[0], NORMAL_HQ_CORE, -1, hSCE->save_synth );
     884             :     }
     885             : 
     886             :     /* mapping of DirAC parameters (azimuth, elevation, diffuseness) to DFT Stereo parameters (side gain, prediction gain) */
     887       32364 :     map_params_dirac_to_stereo( hStereoDft, st_ivas->hQMetaData, tmp_synth, DFT[0], st_ivas->ivas_format == MC_FORMAT,
     888       32364 :                                 ( ( st_ivas->ivas_format != SBA_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT ) || mcmasa ) ? hSCE->hCoreCoder[0]->L_frame : output_frame,
     889       32364 :                                 ( ( st_ivas->ivas_format != SBA_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT ) || mcmasa ) );
     890             : 
     891       32364 :     if ( ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) && !mcmasa )
     892             :     {
     893       28830 :         set_f( hStereoDft->res_pred_gain, 1.f, 3 * STEREO_DFT_BAND_MAX );
     894             :     }
     895             : 
     896             :     /* DFT Stereo upmix */
     897       32364 :     stereo_dft_dec( hStereoDft, hCPE->hCoreCoder[0], DFT, NULL, NULL, 1 /*st_ivas->sba_dirac_stereo_flag*/, sba_mono_flag, ( st_ivas->hSpar != NULL && !mcmasa ) ? st_ivas->hSpar->hMdDec : NULL, ( st_ivas->hSpar != NULL && !mcmasa ) ? st_ivas->hSpar->hFbMixer->cross_fade_start_offset : 0,
     898       32364 :                     st_ivas->hDecoderConfig->output_Fs, st_ivas->nchan_transport, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
     899             : 
     900             :     /* DFT synthesis */
     901       32364 :     stereo_dft_dec_synthesize( hCPE, DFT, 0, output[0], output_frame );
     902       32364 :     if ( !sba_mono_flag )
     903             :     {
     904       30534 :         stereo_dft_dec_synthesize( hCPE, DFT, 1, output[1], output_frame );
     905             :     }
     906             : 
     907       32364 :     synchro_synthesis( st_ivas->hDecoderConfig->ivas_total_brate, hCPE, output, output_frame, 1 /*st_ivas->sba_dirac_stereo_flag*/ );
     908             : 
     909             :     /* output scaling */
     910       32364 :     if ( !sba_mono_flag )
     911             :     {
     912       30534 :         v_multc( output[0], 0.5f, output[0], output_frame );
     913       30534 :         v_multc( output[1], 0.5f, output[1], output_frame );
     914             :     }
     915             : 
     916             :     /* delay HB synth */
     917       32364 :     if ( st_ivas->nchan_transport == 1 )
     918             :     {
     919       13536 :         mvr2r( hSCE->save_hb_synth + output_frame - memOffset, tmp_buf, memOffset );
     920       13536 :         mvr2r( hSCE->save_hb_synth, hSCE->save_hb_synth + memOffset, output_frame - memOffset );
     921       13536 :         mvr2r( hSCE->prev_hb_synth, hSCE->save_hb_synth, memOffset );
     922       13536 :         mvr2r( tmp_buf, hSCE->prev_hb_synth, memOffset );
     923             :     }
     924             : 
     925       32364 :     if ( ( hCPE->hCoreCoder[0]->core == ACELP_CORE || hCPE->hCoreCoder[0]->last_core == ACELP_CORE ) && !fd_cng_flag && st_ivas->nchan_transport == 1 )
     926             :     {
     927             :         /* upmix ACELP BWE */
     928        6147 :         ivas_sba_dirac_stereo_compute_hb_gain( hStereoDft, hb_gain );
     929             : 
     930        6147 :         ivas_sba_dirac_stereo_upmix_hb( hb_synth_stereo, hSCE->save_hb_synth, hb_gain, output_frame, ( ( st_ivas->ivas_format != SBA_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT ) || mcmasa ), sba_mono_flag, hSCE->hCoreCoder[0]->bwidth, hStereoDft );
     931             : 
     932             :         /* add HB to ACELP core */
     933        6147 :         v_add( output[0], hb_synth_stereo[0], output[0], output_frame );
     934        6147 :         if ( !sba_mono_flag )
     935             :         {
     936        5514 :             v_add( output[1], hb_synth_stereo[1], output[1], output_frame );
     937             : 
     938             :             /* apply TD Stereo Filling as is done in ICBWE */
     939        5514 :             ivas_sba_dirac_stereo_apply_td_stefi( hStereoDft, output, output_frame, ( ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) && !mcmasa ) );
     940             :         }
     941             :     }
     942             : 
     943             :     /* reset the other channels to 0 (they are not used since here) */
     944       54441 :     for ( int16_t ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ )
     945             :     {
     946       22077 :         set_zero( output[ch], output_frame );
     947             :     }
     948             : 
     949       32364 :     return;
     950             : }

Generated by: LCOV version 1.14