LCOV - code coverage report
Current view: top level - lib_dec - ivas_binRenderer_internal.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 411 542 75.8 %
Date: 2025-05-23 08:37:30 Functions: 14 16 87.5 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include <math.h>
      36             : #include "prot.h"
      37             : #include "ivas_prot.h"
      38             : #include "ivas_prot_rend.h"
      39             : #include "cnst.h"
      40             : #include "ivas_cnst.h"
      41             : #include "ivas_rom_rend.h"
      42             : #include "ivas_rom_dec.h"
      43             : #include "ivas_rom_com.h"
      44             : #include "ivas_rom_binauralRenderer.h"
      45             : #ifdef DEBUGGING
      46             : #include "debug.h"
      47             : #endif
      48             : #include "wmc_auto.h"
      49             : 
      50             : 
      51             : /*-------------------------------------------------------------------------
      52             :  * Local constants
      53             :  *------------------------------------------------------------------------*/
      54             : 
      55             : #define REVERB_INPUT_DOWNMIX_CHANNELS ( 11 )
      56             : /* Downmix table for sparse frequency domain reverberator */
      57             : const float dmxmtx_table[BINAURAL_CHANNELS][REVERB_INPUT_DOWNMIX_CHANNELS] = {
      58             :     { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
      59             :     { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f },
      60             : };
      61             : 
      62             : /*-------------------------------------------------------------------------
      63             :  * ivas_binRenderer_filterModule()
      64             :  *
      65             :  *
      66             :  *-------------------------------------------------------------------------*/
      67             : 
      68      483522 : static void ivas_binRenderer_filterModule(
      69             :     float out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : real part of Binaural signals     */
      70             :     float out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : imag part of Binaural signals     */
      71             :     float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                           /* i  : real part of LS signals           */
      72             :     float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                           /* i  : imag part of LS signals           */
      73             :     const int16_t numTimeSlots,                                                                       /* i  : number of time slots to process   */
      74             :     BINAURAL_RENDERER_HANDLE hBinRenderer,                                                            /* i/o: fastconv binaural renderer handle */
      75             :     const int16_t pos_idx                                                                             /* i  : pose index                        */
      76             : )
      77             : {
      78             :     int16_t bandIdx, k, chIdx, tapIdx;
      79             :     float *filterStatesLeftRealPtr, *filterStatesLeftImagPtr;
      80             :     const float *filterTapsLeftRealPtr, *filterTapsLeftImagPtr, *filterTapsRightRealPtr, *filterTapsRightImagPtr;
      81             : 
      82    22561812 :     for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
      83             :     {
      84   317447130 :         for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
      85             :         {
      86   295368840 :             filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx][0] );
      87   295368840 :             filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx][0] );
      88             : 
      89   295368840 :             filterTapsLeftRealPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx];
      90   295368840 :             filterTapsLeftImagPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx];
      91   295368840 :             filterTapsRightRealPtr = hBinRenderer->hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx];
      92   295368840 :             filterTapsRightImagPtr = hBinRenderer->hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx];
      93             : 
      94  1475459880 :             for ( k = 0; k < numTimeSlots; k++ )
      95             :             {
      96  1180091040 :                 float outRealLeft = 0.0f, outRealRight = 0.0f, outImagLeft = 0.0f, outImagRight = 0.0f;
      97             : 
      98 14682327360 :                 for ( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- )
      99             :                 {
     100 13502236320 :                     filterStatesLeftRealPtr[tapIdx] = filterStatesLeftRealPtr[tapIdx - 1];
     101 13502236320 :                     filterStatesLeftImagPtr[tapIdx] = filterStatesLeftImagPtr[tapIdx - 1];
     102             : 
     103             :                     /* Left Real and Imag */
     104 13502236320 :                     outRealLeft += ( filterStatesLeftRealPtr[tapIdx] * filterTapsLeftRealPtr[tapIdx] ) - ( filterStatesLeftImagPtr[tapIdx] * filterTapsLeftImagPtr[tapIdx] );
     105 13502236320 :                     outImagLeft += ( filterStatesLeftRealPtr[tapIdx] * filterTapsLeftImagPtr[tapIdx] ) + ( filterStatesLeftImagPtr[tapIdx] * filterTapsLeftRealPtr[tapIdx] );
     106             : 
     107             :                     /* Right Real and Imag*/
     108 13502236320 :                     outRealRight += ( filterStatesLeftRealPtr[tapIdx] * filterTapsRightRealPtr[tapIdx] ) - ( filterStatesLeftImagPtr[tapIdx] * filterTapsRightImagPtr[tapIdx] );
     109 13502236320 :                     outImagRight += ( filterStatesLeftRealPtr[tapIdx] * filterTapsRightImagPtr[tapIdx] ) + ( filterStatesLeftImagPtr[tapIdx] * filterTapsRightRealPtr[tapIdx] );
     110             :                 }
     111             : 
     112  1180091040 :                 filterStatesLeftRealPtr[0] = CLDFB_real[chIdx][k][bandIdx];
     113  1180091040 :                 filterStatesLeftImagPtr[0] = CLDFB_imag[chIdx][k][bandIdx];
     114             : 
     115             : 
     116             :                 /* Left Real and Imag */
     117  1180091040 :                 out_Conv_CLDFB_real[0][k][bandIdx] += outRealLeft + ( filterStatesLeftRealPtr[0] * filterTapsLeftRealPtr[0] ) - ( filterStatesLeftImagPtr[0] * filterTapsLeftImagPtr[0] );
     118  1180091040 :                 out_Conv_CLDFB_imag[0][k][bandIdx] += outImagLeft + ( filterStatesLeftRealPtr[0] * filterTapsLeftImagPtr[0] ) + ( filterStatesLeftImagPtr[0] * filterTapsLeftRealPtr[0] );
     119             : 
     120             :                 /* Right Real and Imag */
     121  1180091040 :                 out_Conv_CLDFB_real[1][k][bandIdx] += outRealRight + ( filterStatesLeftRealPtr[0] * filterTapsRightRealPtr[0] ) - ( filterStatesLeftImagPtr[0] * filterTapsRightImagPtr[0] );
     122  1180091040 :                 out_Conv_CLDFB_imag[1][k][bandIdx] += outImagRight + ( filterStatesLeftRealPtr[0] * filterTapsRightImagPtr[0] ) + ( filterStatesLeftImagPtr[0] * filterTapsRightRealPtr[0] );
     123             :             }
     124             :         }
     125             :     }
     126             : 
     127      483522 :     return;
     128             : }
     129             : 
     130             : 
     131             : /*-------------------------------------------------------------------------
     132             :  * ivas_binRenderer_convModuleOpen()
     133             :  *
     134             :  * Open convolution module handle of fastconv binaural renderer
     135             :  *-------------------------------------------------------------------------*/
     136             : 
     137        1065 : static ivas_error ivas_binRenderer_convModuleOpen(
     138             :     BINAURAL_RENDERER_HANDLE hBinRenderer,
     139             :     const int16_t renderer_type,
     140             :     const int16_t isLoudspeaker,
     141             :     const AUDIO_CONFIG input_config,
     142             :     const HRTFS_FASTCONV_HANDLE hHrtf,
     143             :     const int16_t num_poses )
     144             : {
     145             :     int16_t bandIdx, chIdx;
     146             :     BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule;
     147             :     int16_t pos_idx;
     148             : 
     149             :     /*-----------------------------------------------------------------*
     150             :      * prepare library opening
     151             :      *-----------------------------------------------------------------*/
     152             : 
     153        1065 :     if ( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE) malloc( sizeof( BINRENDERER_CONV_MODULE ) ) ) == NULL )
     154             :     {
     155           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     156             :     }
     157             : 
     158        1065 :     if ( !isLoudspeaker )
     159             :     {
     160         606 :         hBinRenderer->nInChannels = audioCfg2channels( input_config );
     161             :     }
     162             :     else
     163             :     {
     164             :         /* Note: needs to be revisited if multiple LFE support is required */
     165         459 :         hBinRenderer->nInChannels = ( audioCfg2channels( input_config ) - isLoudspeaker );
     166             :     }
     167             : 
     168        1065 :     hBinRenConvModule->numTaps = hHrtf->ntaps;
     169             : 
     170        1065 :     if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
     171             :     {
     172             :         /* Use variable order filtering */
     173         207 :         bandIdx = 0;
     174        1242 :         for ( ; bandIdx < 5; bandIdx++ )
     175             :         {
     176        1035 :             hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
     177             :         }
     178        1242 :         for ( ; bandIdx < 10; bandIdx++ )
     179             :         {
     180        1035 :             hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.6f * hBinRenConvModule->numTaps );
     181             :         }
     182        2277 :         for ( ; bandIdx < 20; bandIdx++ )
     183             :         {
     184        2070 :             hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.5f * hBinRenConvModule->numTaps );
     185             :         }
     186        2277 :         for ( ; bandIdx < 30; bandIdx++ )
     187             :         {
     188        2070 :             hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.4f * hBinRenConvModule->numTaps );
     189             :         }
     190        3957 :         for ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     191             :         {
     192        3750 :             hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.3f * hBinRenConvModule->numTaps );
     193             :         }
     194             :     }
     195             :     else
     196             :     {
     197             :         /* Use fixed order filtering */
     198         858 :         bandIdx = 0;
     199       35238 :         for ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     200             :         {
     201       34380 :             hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
     202             :         }
     203             :     }
     204             : 
     205             :     /* allocate memory for filter states */
     206        1065 :     if ( ( hBinRenConvModule->filterTapsLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     207             :     {
     208           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     209             :     }
     210             : 
     211        1065 :     if ( ( hBinRenConvModule->filterTapsLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     212             :     {
     213           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     214             :     }
     215             : 
     216        1065 :     if ( ( hBinRenConvModule->filterTapsRightReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     217             :     {
     218           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     219             :     }
     220             : 
     221        1065 :     if ( ( hBinRenConvModule->filterTapsRightImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     222             :     {
     223           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     224             :     }
     225             : 
     226       45315 :     for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     227             :     {
     228       44250 :         if ( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     229             :         {
     230           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     231             :         }
     232             : 
     233       44250 :         if ( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     234             :         {
     235           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     236             :         }
     237             : 
     238       44250 :         if ( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     239             :         {
     240           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     241             :         }
     242             : 
     243       44250 :         if ( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     244             :         {
     245           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     246             :         }
     247             :     }
     248             : 
     249        1065 :     if ( ( hBinRenConvModule->filterStatesLeftReal = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL )
     250             :     {
     251           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     252             :     }
     253             : 
     254        1065 :     if ( ( hBinRenConvModule->filterStatesLeftImag = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL )
     255             :     {
     256           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     257             :     }
     258             : 
     259        2130 :     for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
     260             :     {
     261        1065 :         if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     262             :         {
     263           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     264             :         }
     265             : 
     266        1065 :         if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
     267             :         {
     268           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     269             :         }
     270             : 
     271       45315 :         for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     272             :         {
     273       44250 :             if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     274             :             {
     275           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     276             :             }
     277             : 
     278       44250 :             if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
     279             :             {
     280           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     281             :             }
     282             : 
     283      572940 :             for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     284             :             {
     285      528690 :                 if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
     286             :                 {
     287           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     288             :                 }
     289             : 
     290      528690 :                 if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
     291             :                 {
     292           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     293             :                 }
     294             :             }
     295             :         }
     296             :     }
     297             : 
     298             :     /* set memories */
     299       45315 :     for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     300             :     {
     301      572940 :         for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     302             :         {
     303      528690 :             int16_t tmp = 0;
     304             : 
     305      528690 :             tmp = chIdx;
     306      528690 :             if ( isLoudspeaker )
     307             :             {
     308      102450 :                 if ( input_config == IVAS_AUDIO_CONFIG_5_1 )
     309             :                 {
     310       75450 :                     tmp = channelIndex_CICP6[chIdx];
     311             :                 }
     312       27000 :                 else if ( input_config == IVAS_AUDIO_CONFIG_7_1 )
     313             :                 {
     314           0 :                     tmp = channelIndex_CICP12[chIdx];
     315             :                 }
     316       27000 :                 else if ( input_config == IVAS_AUDIO_CONFIG_5_1_2 )
     317             :                 {
     318        1260 :                     tmp = channelIndex_CICP14[chIdx];
     319             :                 }
     320       25740 :                 else if ( input_config == IVAS_AUDIO_CONFIG_5_1_4 )
     321             :                 {
     322           0 :                     tmp = channelIndex_CICP16[chIdx];
     323             :                 }
     324       25740 :                 else if ( input_config == IVAS_AUDIO_CONFIG_7_1_4 )
     325             :                 {
     326       25740 :                     tmp = channelIndex_CICP19[chIdx];
     327             :                 }
     328             : #ifdef DEBUGGING
     329             :                 else
     330             :                 {
     331             :                     return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" );
     332             :                 }
     333             : #endif
     334             :             }
     335             : 
     336      528690 :             hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftReal[bandIdx][tmp];
     337      528690 :             hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftImag[bandIdx][tmp];
     338      528690 :             hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightReal[bandIdx][tmp];
     339      528690 :             hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightImag[bandIdx][tmp];
     340             :         }
     341             :     }
     342             : 
     343        2130 :     for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
     344             :     {
     345       45315 :         for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     346             :         {
     347      572940 :             for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     348             :             {
     349             :                 /* set the memories to zero */
     350      528690 :                 set_zero( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
     351      528690 :                 set_zero( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
     352             :             }
     353             :         }
     354             :     }
     355             : 
     356        1065 :     hBinRenderer->hBinRenConvModule = hBinRenConvModule;
     357             : 
     358        1065 :     return IVAS_ERR_OK;
     359             : }
     360             : 
     361             : 
     362             : /*-------------------------------------------------------------------------*
     363             :  * ivas_init_binaural_hrtf()
     364             :  *
     365             :  * initialize memory for HrtfFastConv structure elements
     366             :  *-------------------------------------------------------------------------*/
     367             : 
     368         342 : void ivas_init_binaural_hrtf(
     369             :     HRTFS_FASTCONV *HrtfFastConv /* i/o: FASTCONV HRTF structure */
     370             : )
     371             : {
     372             :     int16_t i;
     373             : 
     374         342 :     HrtfFastConv->leftReal = NULL;
     375         342 :     HrtfFastConv->leftImag = NULL;
     376         342 :     HrtfFastConv->rightReal = NULL;
     377         342 :     HrtfFastConv->rightImag = NULL;
     378         342 :     HrtfFastConv->FASTCONV_latency_s = 0x00;
     379             : 
     380         342 :     HrtfFastConv->n_channels = 0;
     381         342 :     HrtfFastConv->allocate_init_flag = 0x00;
     382         342 :     HrtfFastConv->ntaps = 0;
     383             : 
     384       20862 :     for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
     385             :     {
     386       20520 :         HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00;
     387       20520 :         HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00;
     388             :     }
     389             : 
     390         342 :     return;
     391             : }
     392             : 
     393             : 
     394             : /*-------------------------------------------------------------------------*
     395             :  * ivas_alloc_pppMem()
     396             :  *
     397             :  * Allocate memory for tripple pointer elements
     398             :  *-------------------------------------------------------------------------*/
     399             : 
     400        1368 : static ivas_error ivas_alloc_pppMem(
     401             :     float ****pppMem,
     402             :     const int16_t dim1,
     403             :     const int16_t dim2,
     404             :     const int16_t dim3,
     405             :     const int16_t allocate_init_flag )
     406             : {
     407             :     int16_t i, j;
     408        1368 :     float ***localMem = NULL;
     409             : 
     410        1368 :     if ( ( localMem = (float ***) malloc( dim1 * sizeof( float ** ) ) ) == NULL )
     411             :     {
     412           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     413             :     }
     414             : 
     415       69768 :     for ( i = 0; i < dim1; i++ )
     416             :     {
     417       68400 :         if ( ( localMem[i] = (float **) malloc( dim2 * sizeof( float * ) ) ) == NULL )
     418             :         {
     419           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     420             :         }
     421       68400 :         if ( allocate_init_flag == 0 )
     422             :         {
     423      689400 :             for ( j = 0; j < dim2; j++ )
     424             :             {
     425      648600 :                 if ( ( localMem[i][j] = (float *) malloc( dim3 * sizeof( float ) ) ) == NULL )
     426             :                 {
     427           0 :                     return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     428             :                 }
     429             :             }
     430             :         }
     431             :     }
     432             : 
     433        1368 :     *pppMem = localMem;
     434             : 
     435        1368 :     return IVAS_ERR_OK;
     436             : }
     437             : 
     438             : 
     439             : /*-------------------------------------------------------------------------*
     440             :  * ivas_allocate_binaural_hrtf()
     441             :  *
     442             :  * Allocate memory for HrtfFastConv structure elements
     443             :  *-------------------------------------------------------------------------*/
     444             : 
     445         357 : ivas_error ivas_allocate_binaural_hrtf(
     446             :     HRTFS_FASTCONV *HrtfFastConv,    /* i/o: FASTCONV HRTF structure     */
     447             :     const int16_t n_channels,        /* i : number of input channels     */
     448             :     const int16_t allocate_init_flag /* i  : Memory allocation flag      */
     449             : )
     450             : {
     451         357 :     HrtfFastConv->n_channels = n_channels;
     452             : 
     453         357 :     if ( ( HrtfFastConv->leftReal != NULL ) && ( HrtfFastConv->leftImag != NULL ) && ( HrtfFastConv->rightReal != NULL ) && ( HrtfFastConv->rightImag != NULL ) )
     454             :     {
     455          15 :         return IVAS_ERR_OK;
     456             :     }
     457             :     else
     458             :     {
     459         342 :         if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftReal, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
     460             :         {
     461           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->leftReal" );
     462             :         }
     463         342 :         if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftImag, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
     464             :         {
     465           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->leftImag" );
     466             :         }
     467         342 :         if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightReal, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
     468             :         {
     469           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->rightReal" );
     470             :         }
     471         342 :         if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightImag, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
     472             :         {
     473           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->rightImag" );
     474             :         }
     475             :     }
     476             : 
     477         342 :     return IVAS_ERR_OK;
     478             : }
     479             : 
     480             : 
     481             : /*-------------------------------------------------------------------------*
     482             :  * ivas_binaural_hrtf_open()
     483             :  *
     484             :  *
     485             :  *-------------------------------------------------------------------------*/
     486             : 
     487        1065 : static ivas_error ivas_binaural_hrtf_open(
     488             :     HRTFS_FASTCONV_HANDLE *hHrtfFastConv, /* i  : fastconv HRTF handle */
     489             :     const AUDIO_CONFIG input_config,      /* i  : output configuration */
     490             :     const RENDERER_TYPE renderer_type     /* i  : renderer type        */
     491             : )
     492             : {
     493             :     int16_t i, j;
     494             :     ivas_error error;
     495             :     int16_t n_channels;
     496             : 
     497        1065 :     if ( hHrtfFastConv != NULL && *hHrtfFastConv != NULL )
     498             :     {
     499             :         /* Tables already loaded from file */
     500         927 :         return IVAS_ERR_OK;
     501             :     }
     502             :     else
     503             :     {
     504             :         /* Initialise tables from ROM */
     505             :         HRTFS_FASTCONV *HrtfFastConv;
     506             : 
     507         138 :         if ( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL )
     508             :         {
     509           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" );
     510             :         }
     511             : 
     512         138 :         ivas_init_binaural_hrtf( HrtfFastConv );
     513             : 
     514         138 :         if ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV )
     515             :         {
     516          99 :             HrtfFastConv->FASTCONV_latency_s = FASTCONV_HRIR_latency_s;
     517          99 :             HrtfFastConv->ntaps = BINAURAL_NTAPS;
     518             :         }
     519         138 :         if ( input_config == IVAS_AUDIO_CONFIG_HOA2 )
     520             :         {
     521           0 :             HrtfFastConv->FASTCONV_latency_s = FASTCONV_HOA2_latency_s;
     522           0 :             HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
     523             :         }
     524         138 :         if ( input_config == IVAS_AUDIO_CONFIG_HOA3 )
     525             :         {
     526         105 :             HrtfFastConv->FASTCONV_latency_s = FASTCONV_HOA3_latency_s;
     527         105 :             HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
     528             :         }
     529         138 :         if ( input_config == IVAS_AUDIO_CONFIG_FOA )
     530             :         {
     531           0 :             HrtfFastConv->FASTCONV_latency_s = FASTCONV_FOA_latency_s;
     532           0 :             HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
     533             :         }
     534         138 :         if ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
     535             :         {
     536          39 :             HrtfFastConv->FASTCONV_latency_s = FASTCONV_BRIR_latency_s;
     537          39 :             HrtfFastConv->ntaps = BINAURAL_NTAPS_MAX;
     538             :         }
     539             : 
     540         138 :         HrtfFastConv->allocate_init_flag = 1;
     541             : 
     542         138 :         n_channels = 0;
     543         138 :         if ( ( renderer_type == RENDERER_BINAURAL_FASTCONV || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && input_config != IVAS_AUDIO_CONFIG_INVALID )
     544             :         {
     545         138 :             n_channels = HRTF_LS_CHANNELS;
     546             :         }
     547             : 
     548         138 :         if ( renderer_type == RENDERER_BINAURAL_FASTCONV )
     549             :         {
     550          99 :             if ( input_config == IVAS_AUDIO_CONFIG_HOA3 )
     551             :             {
     552          84 :                 n_channels = HOA3_CHANNELS;
     553             :             }
     554          15 :             else if ( input_config == IVAS_AUDIO_CONFIG_HOA2 )
     555             :             {
     556           0 :                 n_channels = HOA2_CHANNELS;
     557             :             }
     558          15 :             else if ( input_config == IVAS_AUDIO_CONFIG_FOA )
     559             :             {
     560           0 :                 n_channels = FOA_CHANNELS;
     561             :             }
     562             :         }
     563             : 
     564         138 :         if ( ( error = ivas_allocate_binaural_hrtf( HrtfFastConv, n_channels, HrtfFastConv->allocate_init_flag ) ) != IVAS_ERR_OK )
     565             :         {
     566           0 :             return error;
     567             :         }
     568             : 
     569        7038 :         for ( i = 0; i < BINAURAL_CONVBANDS; i++ )
     570             :         {
     571        6900 :             if ( renderer_type == RENDERER_BINAURAL_FASTCONV && HrtfFastConv->n_channels == HRTF_LS_CHANNELS )
     572             :             {
     573       12000 :                 for ( j = 0; j < HRTF_LS_CHANNELS; j++ )
     574             :                 {
     575       11250 :                     HrtfFastConv->leftReal[i][j] = leftHRIRReal[i][j];
     576       11250 :                     HrtfFastConv->leftImag[i][j] = leftHRIRImag[i][j];
     577       11250 :                     HrtfFastConv->rightReal[i][j] = rightHRIRReal[i][j];
     578       11250 :                     HrtfFastConv->rightImag[i][j] = rightHRIRImag[i][j];
     579             :                 }
     580             :             }
     581        6150 :             else if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && HrtfFastConv->n_channels == HRTF_LS_CHANNELS )
     582             :             {
     583       31200 :                 for ( j = 0; j < HRTF_LS_CHANNELS; j++ )
     584             :                 {
     585       29250 :                     HrtfFastConv->leftReal[i][j] = leftBRIRReal[i][j];
     586       29250 :                     HrtfFastConv->leftImag[i][j] = leftBRIRImag[i][j];
     587       29250 :                     HrtfFastConv->rightReal[i][j] = rightBRIRReal[i][j];
     588       29250 :                     HrtfFastConv->rightImag[i][j] = rightBRIRImag[i][j];
     589             :                 }
     590             :             }
     591             : 
     592        6900 :             if ( input_config == IVAS_AUDIO_CONFIG_HOA3 && HrtfFastConv->n_channels == HOA3_CHANNELS )
     593             :             {
     594       71400 :                 for ( j = 0; j < HOA3_CHANNELS; j++ )
     595             :                 {
     596       67200 :                     HrtfFastConv->leftReal[i][j] = leftHRIRReal_HOA3[i][j];
     597       67200 :                     HrtfFastConv->leftImag[i][j] = leftHRIRImag_HOA3[i][j];
     598       67200 :                     HrtfFastConv->rightReal[i][j] = rightHRIRReal_HOA3[i][j];
     599       67200 :                     HrtfFastConv->rightImag[i][j] = rightHRIRImag_HOA3[i][j];
     600             :                 }
     601             :             }
     602             : 
     603             :             /* Note: IVAS_AUDIO_CONFIG_HOA2 and IVAS_AUDIO_CONFIG_FOA input configs. are not relevant in internal renderer
     604             :             as SBA to binaural always synthesizes HOA3 output for binauralization. However, the external renderer can use them. */
     605        6900 :             if ( input_config == IVAS_AUDIO_CONFIG_HOA2 && HrtfFastConv->n_channels == HOA2_CHANNELS )
     606             :             {
     607           0 :                 for ( j = 0; j < HOA2_CHANNELS; j++ )
     608             :                 {
     609           0 :                     HrtfFastConv->leftReal[i][j] = leftHRIRReal_HOA2[i][j];
     610           0 :                     HrtfFastConv->leftImag[i][j] = leftHRIRImag_HOA2[i][j];
     611           0 :                     HrtfFastConv->rightReal[i][j] = rightHRIRReal_HOA2[i][j];
     612           0 :                     HrtfFastConv->rightImag[i][j] = rightHRIRImag_HOA2[i][j];
     613             :                 }
     614             :             }
     615             : 
     616        6900 :             if ( input_config == IVAS_AUDIO_CONFIG_FOA && HrtfFastConv->n_channels == FOA_CHANNELS )
     617             :             {
     618           0 :                 for ( j = 0; j < FOA_CHANNELS; j++ )
     619             :                 {
     620           0 :                     HrtfFastConv->leftReal[i][j] = leftHRIRReal_FOA[i][j];
     621           0 :                     HrtfFastConv->leftImag[i][j] = leftHRIRImag_FOA[i][j];
     622           0 :                     HrtfFastConv->rightReal[i][j] = rightHRIRReal_FOA[i][j];
     623           0 :                     HrtfFastConv->rightImag[i][j] = rightHRIRImag_FOA[i][j];
     624             :                 }
     625             :             }
     626             :         }
     627             : 
     628         138 :         mvr2r( fastconvReverberationTimes, HrtfFastConv->fastconvReverberationTimes, CLDFB_NO_CHANNELS_MAX );
     629         138 :         mvr2r( fastconvReverberationEneCorrections, HrtfFastConv->fastconvReverberationEneCorrections, CLDFB_NO_CHANNELS_MAX );
     630             : 
     631         138 :         *hHrtfFastConv = HrtfFastConv;
     632             : 
     633         138 :         return IVAS_ERR_OK;
     634             :     }
     635             : }
     636             : 
     637             : 
     638             : /*-------------------------------------------------------------------------*
     639             :  * ivas_binaural_obtain_DMX()
     640             :  *
     641             :  *
     642             :  *-------------------------------------------------------------------------*/
     643             : 
     644      302550 : static void ivas_binaural_obtain_DMX(
     645             :     const int16_t numTimeSlots,
     646             :     BINAURAL_RENDERER_HANDLE hBinRenderer,                               /* i/o: fastconv binaural renderer handle */
     647             :     float RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Contains the LS signals           */
     648             :     float ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Contains the LS signals           */
     649             :     float realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
     650             :     float imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] )
     651             : {
     652             :     int16_t chIdx, bandIdx, k;
     653             : 
     654      302550 :     if ( hBinRenderer->ivas_format == MC_FORMAT )
     655             :     {
     656             :         /* Obtain the downmix */
     657             :         float P_in[CLDFB_NO_CHANNELS_MAX];
     658             :         float P_out, factEQ;
     659             :         int16_t chOutIdx;
     660             :         float temp1, temp2;
     661             : 
     662      411600 :         for ( k = 0; k < numTimeSlots; k++ )
     663             :         {
     664      987840 :             for ( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
     665             :             {
     666      658560 :                 set_zero( realDMX[chOutIdx][k], CLDFB_NO_CHANNELS_MAX );
     667      658560 :                 set_zero( imagDMX[chOutIdx][k], CLDFB_NO_CHANNELS_MAX );
     668             :             }
     669             :         }
     670             : 
     671      246960 :         for ( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
     672             :         {
     673      164640 :             set_zero( P_in, hBinRenderer->conv_band );
     674             : 
     675     1442880 :             for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     676             :             {
     677     1278240 :                 float dmxConst = dmxmtx_table[chOutIdx][chIdx];
     678             : 
     679    61175040 :                 for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     680             :                 {
     681   299484000 :                     for ( k = 0; k < numTimeSlots; k++ )
     682             :                     {
     683   239587200 :                         temp1 = RealBuffer[chIdx][k][bandIdx] * dmxConst;
     684   239587200 :                         temp2 = ImagBuffer[chIdx][k][bandIdx] * dmxConst;
     685   239587200 :                         realDMX[chOutIdx][k][bandIdx] += temp1;
     686   239587200 :                         imagDMX[chOutIdx][k][bandIdx] += temp2;
     687             : 
     688   239587200 :                         P_in[bandIdx] += temp1 * temp1 + temp2 * temp2;
     689             :                     }
     690             :                 }
     691             :             }
     692             : 
     693     7890240 :             for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     694             :             {
     695     7725600 :                 P_out = 0.f;
     696    38628000 :                 for ( k = 0; k < numTimeSlots; k++ )
     697             :                 {
     698    30902400 :                     temp1 = realDMX[chOutIdx][k][bandIdx];
     699    30902400 :                     temp2 = imagDMX[chOutIdx][k][bandIdx];
     700    30902400 :                     P_out += temp1 * temp1 + temp2 * temp2;
     701             :                 }
     702     7725600 :                 factEQ = sqrtf( P_in[bandIdx] / ( P_out + 1e-20f ) );
     703     7725600 :                 if ( ( factEQ <= 1e-20f ) || ( P_in[bandIdx] <= 1e-20f ) || ( P_out <= 1e-20f ) )
     704             :                 {
     705      111012 :                     factEQ = 1.0f;
     706             :                 }
     707             : 
     708     7725600 :                 factEQ = max( min( factEQ, 2.0f ), 0.5f );
     709    38628000 :                 for ( k = 0; k < numTimeSlots; k++ )
     710             :                 {
     711    30902400 :                     realDMX[chOutIdx][k][bandIdx] *= factEQ;
     712    30902400 :                     imagDMX[chOutIdx][k][bandIdx] *= factEQ;
     713             :                 }
     714             :             }
     715             :         }
     716             :     }
     717      220230 :     else if ( hBinRenderer->ivas_format == SBA_FORMAT || hBinRenderer->ivas_format == MASA_FORMAT )
     718             :     {
     719             :         float *outRealLeftPtr, *outImagLeftPtr, *outRealRightPtr, *outImagRightPtr;
     720             :         float *inRealPtr, *inImagPtr;
     721             : 
     722             :         /*compute DMX */
     723     1099347 :         for ( k = 0; k < numTimeSlots; k++ )
     724             :         {
     725      879117 :             outRealLeftPtr = realDMX[0][k];
     726      879117 :             outImagLeftPtr = imagDMX[0][k];
     727      879117 :             outRealRightPtr = realDMX[1][k];
     728      879117 :             outImagRightPtr = imagDMX[1][k];
     729      879117 :             set_zero( outRealLeftPtr, CLDFB_NO_CHANNELS_MAX );
     730      879117 :             set_zero( outImagLeftPtr, CLDFB_NO_CHANNELS_MAX );
     731      879117 :             set_zero( outRealRightPtr, CLDFB_NO_CHANNELS_MAX );
     732      879117 :             set_zero( outImagRightPtr, CLDFB_NO_CHANNELS_MAX );
     733             : 
     734             :             /*Ambisonics input requires different processing*/
     735      879117 :             if ( hBinRenderer->nInChannels == HOA3_CHANNELS )
     736             :             {
     737             :                 float *inRealPtr_W, *inImagPtr_W;
     738             :                 float *inRealPtr_Y, *inImagPtr_Y;
     739             : 
     740      543165 :                 inRealPtr_W = (float *) &( RealBuffer[0][k][0] );
     741      543165 :                 inImagPtr_W = (float *) &( ImagBuffer[0][k][0] );
     742             : 
     743      543165 :                 inRealPtr_Y = (float *) &( RealBuffer[1][k][0] );
     744      543165 :                 inImagPtr_Y = (float *) &( ImagBuffer[1][k][0] );
     745             : 
     746    24096525 :                 for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     747             :                 {
     748    23553360 :                     outRealLeftPtr[bandIdx] = inRealPtr_W[bandIdx] + inRealPtr_Y[bandIdx];
     749    23553360 :                     outImagLeftPtr[bandIdx] = inImagPtr_W[bandIdx] + inImagPtr_Y[bandIdx];
     750             : 
     751    23553360 :                     outRealRightPtr[bandIdx] = inRealPtr_W[bandIdx] - inRealPtr_Y[bandIdx];
     752    23553360 :                     outImagRightPtr[bandIdx] = inImagPtr_W[bandIdx] - inImagPtr_Y[bandIdx];
     753             :                 }
     754             :             }
     755             :             else
     756             :             {
     757     4031424 :                 for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     758             :                 {
     759     3695472 :                     float foa_const = hBinRenderer->hReverb->foa_enc[chIdx][1];
     760             : 
     761     3695472 :                     inRealPtr = (float *) &( RealBuffer[chIdx][k][0] );
     762     3695472 :                     inImagPtr = (float *) &( ImagBuffer[chIdx][k][0] );
     763             : 
     764   156789072 :                     for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     765             :                     {
     766   153093600 :                         outRealLeftPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f + foa_const );
     767   153093600 :                         outImagLeftPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f + foa_const );
     768             : 
     769   153093600 :                         outRealRightPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f - foa_const );
     770   153093600 :                         outImagRightPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f - foa_const );
     771             :                     }
     772             :                 }
     773             :             }
     774             :         }
     775             :     }
     776             : 
     777      302550 :     return;
     778             : }
     779             : 
     780             : 
     781             : /*-------------------------------------------------------------------------
     782             :  * ivas_rend_openCldfbRend()
     783             :  *
     784             :  * Allocate and initialize CLDFB fast conv renderer handle
     785             :  *------------------------------------------------------------------------*/
     786             : 
     787           0 : ivas_error ivas_rend_openCldfbRend(
     788             :     CLDFB_REND_WRAPPER *pCldfbRend,
     789             :     const AUDIO_CONFIG inConfig,
     790             :     const AUDIO_CONFIG outConfig,
     791             :     const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
     792             :     const int32_t output_Fs )
     793             : {
     794             :     BINAURAL_RENDERER_HANDLE hBinRenderer;
     795             :     int16_t convBand;
     796             :     ivas_error error;
     797             : 
     798           0 :     error = IVAS_ERR_OK;
     799             : 
     800             :     /*-----------------------------------------------------------------*
     801             :      * prepare library opening
     802             :      *-----------------------------------------------------------------*/
     803             : 
     804           0 :     if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
     805             :     {
     806           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
     807             :     }
     808             : 
     809           0 :     if ( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL )
     810             :     {
     811           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) );
     812             :     }
     813             : 
     814           0 :     hBinRenderer->rotInCldfb = 1;
     815           0 :     hBinRenderer->ivas_format = SBA_FORMAT;
     816             : 
     817           0 :     hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 );
     818           0 :     convBand = hBinRenderer->max_band;
     819             : 
     820           0 :     hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
     821             : 
     822           0 :     if ( convBand > BINAURAL_CONVBANDS )
     823             :     {
     824           0 :         hBinRenderer->conv_band = BINAURAL_CONVBANDS;
     825             :     }
     826             :     else
     827             :     {
     828           0 :         hBinRenderer->conv_band = convBand;
     829             :     }
     830             : 
     831           0 :     ivas_output_init( hBinRenderer->hInputSetup, inConfig );
     832           0 :     if ( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK )
     833             :     {
     834           0 :         return error;
     835             :     }
     836             : 
     837           0 :     if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
     838             :     {
     839             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
     840             :         hBinRenderer->numPoses = pMultiBinPoseData->num_poses + 1;
     841             : #else
     842           0 :         hBinRenderer->numPoses = pMultiBinPoseData->num_poses;
     843             : #endif
     844             :     }
     845             :     else
     846             :     {
     847           0 :         hBinRenderer->numPoses = 1;
     848             :     }
     849             : 
     850             :     /* Load HRTF tables */
     851           0 :     if ( ( error = ivas_binaural_hrtf_open( &pCldfbRend->hHrtfFastConv, hBinRenderer->hInputSetup->output_config, RENDERER_BINAURAL_FASTCONV ) ) != IVAS_ERR_OK )
     852             :     {
     853           0 :         return error;
     854             :     }
     855             : 
     856             :     /* Allocate memories and buffers needed for convolutional module */
     857           0 :     if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, inConfig, pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
     858             :     {
     859           0 :         return error;
     860             :     }
     861             : 
     862           0 :     pCldfbRend->binaural_latency_ns = (int32_t) ( pCldfbRend->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
     863             : 
     864           0 :     hBinRenderer->hReverb = NULL;
     865           0 :     hBinRenderer->hEFAPdata = NULL;
     866             : 
     867           0 :     pCldfbRend->hCldfbRend = hBinRenderer;
     868             : 
     869           0 :     return error;
     870             : }
     871             : 
     872             : 
     873             : /*-------------------------------------------------------------------------
     874             :  * ivas_binRenderer_open()
     875             :  *
     876             :  * Open fastconv binaural renderer handle
     877             :  *-------------------------------------------------------------------------*/
     878             : 
     879        1065 : ivas_error ivas_binRenderer_open(
     880             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
     881             : )
     882             : {
     883             :     BINAURAL_RENDERER_HANDLE hBinRenderer;
     884             :     int16_t convBand, k;
     885             :     ivas_error error;
     886             :     const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics;
     887             : 
     888        1065 :     error = IVAS_ERR_OK;
     889             : 
     890             :     /*-----------------------------------------------------------------*
     891             :      * prepare library opening
     892             :      *-----------------------------------------------------------------*/
     893             : 
     894        1065 :     if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
     895             :     {
     896           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
     897             :     }
     898             : 
     899        1065 :     hBinRenderer->hInputSetup = &st_ivas->hIntSetup;
     900             : 
     901             :     /* Define of head rotation has to be done in binRendeder in CLDFB*/
     902        1065 :     hBinRenderer->rotInCldfb = 0;
     903        1065 :     if ( st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT )
     904             :     {
     905        1065 :         hBinRenderer->rotInCldfb = 1;
     906             :     }
     907             : 
     908        1065 :     if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
     909             :     {
     910             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
     911             :         hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses + 1;
     912             : #else
     913           0 :         hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
     914             : #endif
     915             :     }
     916             :     else
     917             :     {
     918        1065 :         hBinRenderer->numPoses = 1;
     919             :     }
     920             : 
     921             :     /* Declare some common variables needed for renderer */
     922             :     /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
     923        1065 :     if ( st_ivas->hIntSetup.is_loudspeaker_setup )
     924             :     {
     925         438 :         hBinRenderer->ivas_format = MC_FORMAT;
     926             :     }
     927             :     else
     928             :     {
     929         627 :         hBinRenderer->ivas_format = SBA_FORMAT;
     930             :     }
     931        1065 :     hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
     932        1065 :     convBand = hBinRenderer->max_band;
     933             : 
     934        1065 :     hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
     935             : 
     936        1065 :     if ( convBand > BINAURAL_CONVBANDS )
     937             :     {
     938         681 :         hBinRenderer->conv_band = BINAURAL_CONVBANDS;
     939             :     }
     940             :     else
     941             :     {
     942         384 :         hBinRenderer->conv_band = convBand;
     943             :     }
     944             : 
     945             :     /*LFE rendering switched off by default*/
     946        1065 :     hBinRenderer->render_lfe = 0;
     947             : 
     948        1065 :     if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup )
     949             :     {
     950         438 :         hBinRenderer->render_lfe = 1;
     951             :     }
     952             : 
     953        1065 :     if ( st_ivas->hHrtfFastConv == NULL && st_ivas->hDecoderConfig->Opt_HRTF_binary )
     954             :     {
     955           0 :         return IVAS_ERROR( IVAS_ERR_INTERNAL, "HRTF binary file present but not used in FastConv renderer" );
     956             :     }
     957             : 
     958             :     /* Load HRTF tables */
     959        1065 :     if ( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK )
     960             :     {
     961           0 :         return error;
     962             :     }
     963             : 
     964        1065 :     if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
     965          21 :     {
     966             :         IVAS_OUTPUT_SETUP out_setup;
     967             : 
     968             :         /* Allocate memories and buffers needed for convolutional module in CICP19 */
     969          21 :         if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
     970             :         {
     971           0 :             return error;
     972             :         }
     973             : 
     974          21 :         ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );
     975             : 
     976          21 :         if ( st_ivas->hoa_dec_mtx == NULL )
     977             :         {
     978          21 :             if ( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
     979             :             {
     980           0 :                 return error;
     981             :             }
     982             :         }
     983             : 
     984          21 :         hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
     985          21 :         st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
     986             :     }
     987             :     else
     988             :     {
     989             :         /* Allocate memories and buffers needed for convolutional module */
     990        1044 :         if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
     991             :         {
     992           0 :             return error;
     993             :         }
     994             : 
     995        1044 :         st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
     996             :     }
     997             : 
     998             :     /* Allocate memories needed for reverb module */
     999        1065 :     if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
    1000             :     {
    1001         576 :         pRoomAcoustics = ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ? &( st_ivas->hRenderConfig->roomAcoustics ) : NULL;
    1002         576 :         if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ),
    1003             :                                                   st_ivas->hHrtfStatistics,
    1004         576 :                                                   hBinRenderer->conv_band,
    1005         576 :                                                   hBinRenderer->timeSlots,
    1006             :                                                   pRoomAcoustics,
    1007         576 :                                                   st_ivas->hDecoderConfig->output_Fs,
    1008         576 :                                                   st_ivas->hHrtfFastConv->fastconvReverberationTimes,
    1009         576 :                                                   st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections,
    1010         576 :                                                   hBinRenderer->earlyPartEneCorrection ) ) != IVAS_ERR_OK )
    1011             :         {
    1012           0 :             return error;
    1013             :         }
    1014             :     }
    1015             :     else
    1016             :     {
    1017         489 :         hBinRenderer->hReverb = NULL;
    1018             :     }
    1019             : 
    1020        1065 :     hBinRenderer->hEFAPdata = NULL;
    1021             : 
    1022        1065 :     if ( hBinRenderer->hReverb != NULL && hBinRenderer->nInChannels != HOA3_CHANNELS )
    1023             :     {
    1024         375 :         if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
    1025             :         {
    1026         252 :             for ( k = 0; k < 11; k++ )
    1027             :             {
    1028         231 :                 ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 );
    1029             :             }
    1030             :         }
    1031         354 :         else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
    1032             :         {
    1033           6 :             if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
    1034             :             {
    1035           0 :                 return error;
    1036             :             }
    1037             : 
    1038             :             /* Copy handles to bin renderer handle*/
    1039           6 :             hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
    1040             :         }
    1041             :     }
    1042             : 
    1043             :     /* Copy the handles to main handle */
    1044        1065 :     st_ivas->hBinRenderer = hBinRenderer;
    1045             : 
    1046        1065 :     return error;
    1047             : }
    1048             : 
    1049             : 
    1050             : /*-------------------------------------------------------------------------
    1051             :  * ivas_binRenderer_convModuleClose()
    1052             :  *
    1053             :  * Close convolution module handle of fastconv binaural renderer
    1054             :  *------------------------------------------------------------------------*/
    1055             : 
    1056        1065 : static void ivas_binRenderer_convModuleClose(
    1057             :     BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle    */
    1058             :     const int16_t num_poses                 /* i  : number of poses                      */
    1059             : )
    1060             : {
    1061             :     int16_t bandIdx, chIdx;
    1062             :     int16_t posIdx;
    1063             :     BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule;
    1064             : 
    1065        1065 :     hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
    1066             : 
    1067        1065 :     if ( hBinRenConvModule == NULL )
    1068             :     {
    1069           0 :         return;
    1070             :     }
    1071             : 
    1072       45315 :     for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
    1073             :     {
    1074       44250 :         free( hBinRenConvModule->filterTapsLeftReal[bandIdx] );
    1075       44250 :         hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL;
    1076             : 
    1077       44250 :         free( hBinRenConvModule->filterTapsLeftImag[bandIdx] );
    1078       44250 :         hBinRenConvModule->filterTapsLeftImag[bandIdx] = NULL;
    1079             : 
    1080       44250 :         free( hBinRenConvModule->filterTapsRightReal[bandIdx] );
    1081       44250 :         hBinRenConvModule->filterTapsRightReal[bandIdx] = NULL;
    1082             : 
    1083       44250 :         free( hBinRenConvModule->filterTapsRightImag[bandIdx] );
    1084       44250 :         hBinRenConvModule->filterTapsRightImag[bandIdx] = NULL;
    1085             :     }
    1086             : 
    1087        1065 :     free( hBinRenConvModule->filterTapsLeftReal );
    1088        1065 :     hBinRenConvModule->filterTapsLeftReal = NULL;
    1089             : 
    1090        1065 :     free( hBinRenConvModule->filterTapsLeftImag );
    1091        1065 :     hBinRenConvModule->filterTapsLeftImag = NULL;
    1092             : 
    1093        1065 :     free( hBinRenConvModule->filterTapsRightReal );
    1094        1065 :     hBinRenConvModule->filterTapsRightReal = NULL;
    1095             : 
    1096        1065 :     free( hBinRenConvModule->filterTapsRightImag );
    1097        1065 :     hBinRenConvModule->filterTapsRightImag = NULL;
    1098             : 
    1099        2130 :     for ( posIdx = 0; posIdx < num_poses; posIdx++ )
    1100             :     {
    1101       45315 :         for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
    1102             :         {
    1103      572940 :             for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
    1104             :             {
    1105      528690 :                 free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] );
    1106      528690 :                 hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] = NULL;
    1107             : 
    1108      528690 :                 free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] );
    1109      528690 :                 hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] = NULL;
    1110             :             }
    1111             : 
    1112       44250 :             free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] );
    1113       44250 :             hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] = NULL;
    1114             : 
    1115       44250 :             free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] );
    1116       44250 :             hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] = NULL;
    1117             :         }
    1118             : 
    1119        1065 :         free( hBinRenConvModule->filterStatesLeftReal[posIdx] );
    1120        1065 :         hBinRenConvModule->filterStatesLeftReal[posIdx] = NULL;
    1121             : 
    1122        1065 :         free( hBinRenConvModule->filterStatesLeftImag[posIdx] );
    1123        1065 :         hBinRenConvModule->filterStatesLeftImag[posIdx] = NULL;
    1124             :     }
    1125        1065 :     free( hBinRenConvModule->filterStatesLeftReal );
    1126        1065 :     hBinRenConvModule->filterStatesLeftReal = NULL;
    1127             : 
    1128        1065 :     free( hBinRenConvModule->filterStatesLeftImag );
    1129        1065 :     hBinRenConvModule->filterStatesLeftImag = NULL;
    1130             : 
    1131        1065 :     free( ( *hBinRenderer )->hBinRenConvModule );
    1132        1065 :     ( *hBinRenderer )->hBinRenConvModule = NULL;
    1133             : 
    1134        1065 :     return;
    1135             : }
    1136             : 
    1137             : 
    1138             : /*-------------------------------------------------------------------------
    1139             :  * ivas_binRenderer_close()
    1140             :  *
    1141             :  * Close fastconv binaural renderer memories
    1142             :  *------------------------------------------------------------------------*/
    1143             : 
    1144        2805 : void ivas_binRenderer_close(
    1145             :     BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle    */
    1146             : )
    1147             : {
    1148        2805 :     if ( hBinRenderer == NULL || *hBinRenderer == NULL )
    1149             :     {
    1150        1740 :         return;
    1151             :     }
    1152             : 
    1153        1065 :     if ( ( *hBinRenderer )->hBinRenConvModule != NULL )
    1154             :     {
    1155        1065 :         ivas_binRenderer_convModuleClose( hBinRenderer, ( *hBinRenderer )->numPoses );
    1156             :     }
    1157             : 
    1158        1065 :     if ( ( *hBinRenderer )->hReverb != NULL )
    1159             :     {
    1160         576 :         ivas_binaural_reverb_close( &( ( *hBinRenderer )->hReverb ) );
    1161             :     }
    1162             : 
    1163        1065 :     free( *hBinRenderer );
    1164        1065 :     *hBinRenderer = NULL;
    1165             : 
    1166        1065 :     return;
    1167             : }
    1168             : 
    1169             : 
    1170             : /*-------------------------------------------------------------------------
    1171             :  * ivas_free_pppHrtfMem()
    1172             :  *
    1173             :  * Free fastconv binaural renderer hrtf memories
    1174             :  *------------------------------------------------------------------------*/
    1175             : 
    1176        1368 : static void ivas_free_pppHrtfMem(
    1177             :     float ****ppppHRIR,
    1178             :     const int16_t dim,
    1179             :     const int16_t alloc_init )
    1180             : {
    1181             :     int16_t i, j;
    1182             : 
    1183        1368 :     if ( *ppppHRIR != NULL )
    1184             :     {
    1185       69768 :         for ( i = 0; i < BINAURAL_CONVBANDS; i++ )
    1186             :         {
    1187       68400 :             if ( alloc_init == 0 )
    1188             :             {
    1189      689400 :                 for ( j = 0; j < dim; j++ )
    1190             :                 {
    1191      648600 :                     free( ( *ppppHRIR )[i][j] );
    1192      648600 :                     ( *ppppHRIR )[i][j] = NULL;
    1193             :                 }
    1194             :             }
    1195       68400 :             free( ( *ppppHRIR )[i] );
    1196       68400 :             ( *ppppHRIR )[i] = NULL;
    1197             :         }
    1198        1368 :         free( *ppppHRIR );
    1199        1368 :         *ppppHRIR = NULL;
    1200             :     }
    1201             : 
    1202        1368 :     return;
    1203             : }
    1204             : 
    1205             : 
    1206             : /*-------------------------------------------------------------------------
    1207             :  * ivas_binaural_hrtf_close()
    1208             :  *
    1209             :  * Close fastconv binaural renderer hrtf memories
    1210             :  *------------------------------------------------------------------------*/
    1211             : 
    1212        3644 : void ivas_binaural_hrtf_close(
    1213             :     HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i  : fastconv HRTF handle */
    1214             : )
    1215             : {
    1216             :     int16_t allocate_init_flag;
    1217             :     int16_t n_channels;
    1218             : 
    1219        3644 :     if ( hHrtfFastConv == NULL || *hHrtfFastConv == NULL )
    1220             :     {
    1221        3302 :         return;
    1222             :     }
    1223             : 
    1224         342 :     allocate_init_flag = ( *hHrtfFastConv )->allocate_init_flag;
    1225         342 :     n_channels = ( *hHrtfFastConv )->n_channels;
    1226             : 
    1227         342 :     ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftReal, n_channels, allocate_init_flag );
    1228         342 :     ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftImag, n_channels, allocate_init_flag );
    1229         342 :     ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightReal, n_channels, allocate_init_flag );
    1230         342 :     ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightImag, n_channels, allocate_init_flag );
    1231             : 
    1232         342 :     return;
    1233             : }
    1234             : 
    1235             : 
    1236             : /*-------------------------------------------------------------------------*
    1237             :  * ivas_binaural_add_LFE()
    1238             :  *
    1239             :  * The functions adds the LFE to the left and right channels after binaural rendering
    1240             :  *-------------------------------------------------------------------------*/
    1241             : 
    1242      117634 : void ivas_binaural_add_LFE(
    1243             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure                                 */
    1244             :     int16_t output_frame,    /* i  : length of input frame                                  */
    1245             :     float *input_f[],        /* i  : transport channels                                     */
    1246             :     float *output_f[]        /* o  : synthesized core-coder transport channels/DirAC output */
    1247             : )
    1248             : {
    1249             :     int16_t render_lfe, idx_lfe;
    1250             :     float gain;
    1251             :     float lfe_tc[L_FRAME48k];
    1252             : 
    1253      117634 :     if ( st_ivas->hBinRenderer != NULL )
    1254             :     {
    1255        1120 :         render_lfe = st_ivas->hBinRenderer->render_lfe;
    1256             :     }
    1257             :     else
    1258             :     {
    1259      116514 :         render_lfe = TRUE;
    1260             :     }
    1261             : 
    1262      117634 :     if ( render_lfe )
    1263             :     {
    1264      117634 :         if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
    1265             :         {
    1266       21882 :             gain = GAIN_LFE;
    1267             :         }
    1268             :         else
    1269             :         {
    1270       95752 :             gain = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE;
    1271             :         }
    1272             : 
    1273      233781 :         for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
    1274             :         {
    1275      116147 :             v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, lfe_tc, output_frame );
    1276             :             /* copy LFE to left and right channels */
    1277      116147 :             v_add( output_f[0], lfe_tc, output_f[0], output_frame );
    1278      116147 :             v_add( output_f[1], lfe_tc, output_f[1], output_frame );
    1279             :         }
    1280             :     }
    1281             : 
    1282      117634 :     return;
    1283             : }
    1284             : 
    1285             : 
    1286             : #ifdef DEBUGGING
    1287             : /*-------------------------------------------------------------------------*
    1288             :  * ivas_binaural_cldfb()
    1289             :  *
    1290             :  * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis
    1291             :  *-------------------------------------------------------------------------*/
    1292             : 
    1293             : void ivas_binaural_cldfb(
    1294             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure                                  */
    1295             :     float *output_f[]        /* i/o: synthesized core-coder transport channels/DirAC output  */
    1296             : )
    1297             : {
    1298             :     float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1299             :     float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1300             :     float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1301             :     float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1302             :     int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch;
    1303             : 
    1304             :     /* Implement a 5 msec loops */
    1305             :     maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
    1306             : 
    1307             :     for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ )
    1308             :     {
    1309             :         for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
    1310             :         {
    1311             :             index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
    1312             : 
    1313             :             /* Implement CLDFB analysis */
    1314             :             idx_in = 0;
    1315             :             idx_lfe = 0;
    1316             : 
    1317             :             for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
    1318             :             {
    1319             :                 if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) )
    1320             :                 {
    1321             :                     if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) )
    1322             :                     {
    1323             :                         idx_lfe++;
    1324             :                     }
    1325             :                 }
    1326             :                 else
    1327             :                 {
    1328             :                     cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
    1329             :                     idx_in++;
    1330             :                 }
    1331             :             }
    1332             :             /*LFE handling for split rendering cases*/
    1333             :             if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
    1334             :             {
    1335             :                 for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
    1336             :                 {
    1337             :                     ch = st_ivas->hIntSetup.index_lfe[idx_lfe];
    1338             :                     cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
    1339             :                     idx_in++;
    1340             :                 }
    1341             : 
    1342             :                 if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
    1343             :                 {
    1344             :                     for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
    1345             :                     {
    1346             :                         mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
    1347             :                         mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
    1348             :                     }
    1349             :                     st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
    1350             :                 }
    1351             :             }
    1352             :         }
    1353             : 
    1354             :         /* Implement binaural rendering */
    1355             :         ivas_binRenderer(
    1356             :             st_ivas->hBinRenderer,
    1357             :             &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
    1358             :             st_ivas->hCombinedOrientationData,
    1359             :             JBM_CLDFB_SLOTS_IN_SUBFRAME,
    1360             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1361             :             NULL,
    1362             : #endif
    1363             :             Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural,
    1364             :             Cldfb_RealBuffer, Cldfb_ImagBuffer );
    1365             : 
    1366             :         if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
    1367             :         {
    1368             :             int16_t pos_idx;
    1369             :             for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ )
    1370             :             {
    1371             :                 if ( st_ivas->hIntSetup.num_lfe > 0 )
    1372             :                 {
    1373             :                     v_multc( Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand );
    1374             :                     v_multc( Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand );
    1375             :                 }
    1376             :             }
    1377             : 
    1378             :             for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
    1379             :             {
    1380             :                 for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ )
    1381             :                 {
    1382             :                     for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
    1383             :                     {
    1384             :                         if ( st_ivas->hIntSetup.num_lfe > 0 )
    1385             :                         {
    1386             :                             v_add( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
    1387             :                                    Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx],
    1388             :                                    Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
    1389             :                                    maxBand );
    1390             : 
    1391             :                             v_add( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
    1392             :                                    Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx],
    1393             :                                    Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
    1394             :                                    maxBand );
    1395             :                         }
    1396             : 
    1397             :                         mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
    1398             :                         mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
    1399             :                     }
    1400             :                 }
    1401             :             }
    1402             :         }
    1403             : 
    1404             :         /* update combined orientation access index */
    1405             :         ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES );
    1406             : 
    1407             :         /* Implement CLDFB synthesis */
    1408             :         for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1409             :         {
    1410             :             float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
    1411             :             float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
    1412             : 
    1413             :             index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES;
    1414             : 
    1415             :             for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
    1416             :             {
    1417             :                 RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx];
    1418             :                 ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx];
    1419             :             }
    1420             : 
    1421             :             cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] );
    1422             :         }
    1423             :     }
    1424             : 
    1425             :     return;
    1426             : }
    1427             : 
    1428             : 
    1429             : /*-------------------------------------------------------------------------*
    1430             :  * ivas_binaural_cldfb_sf()
    1431             :  *
    1432             :  * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis
    1433             :  *-------------------------------------------------------------------------*/
    1434             : 
    1435             : void ivas_binaural_cldfb_sf(
    1436             :     Decoder_Struct *st_ivas,           /* i/o: IVAS decoder structure                                  */
    1437             :     const int16_t n_samples_to_render, /* i  : output frame length per channel                         */
    1438             :     const int16_t slot_size,           /* i  : JBM slot size                                           */
    1439             :     float *output_f[]                  /* i/o: synthesized core-coder transport channels/DirAC output  */
    1440             : )
    1441             : {
    1442             :     float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1443             :     float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1444             :     float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1445             :     float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1446             :     int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch;
    1447             :     int16_t slots_to_render, first_sf, last_sf;
    1448             :     int16_t slot_index_start, slot_index_start_cldfb;
    1449             : 
    1450             :     /* Implement a 5 msec loops */
    1451             :     maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
    1452             : 
    1453             :     /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
    1454             :     slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / slot_size );
    1455             :     first_sf = st_ivas->hTcBuffer->subframes_rendered;
    1456             :     last_sf = first_sf;
    1457             :     slot_index_start = st_ivas->hTcBuffer->slots_rendered;
    1458             :     slot_index_start_cldfb = 0;
    1459             :     st_ivas->hTcBuffer->slots_rendered += slots_to_render;
    1460             : 
    1461             :     while ( slots_to_render > 0 )
    1462             :     {
    1463             :         slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf];
    1464             :         last_sf++;
    1465             :     }
    1466             :     for ( subframeIdx = first_sf; subframeIdx < last_sf; subframeIdx++ )
    1467             :     {
    1468             :         for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
    1469             :         {
    1470             :             index_slot = slot_index_start + slot_idx;
    1471             : 
    1472             :             /* Implement CLDFB analysis */
    1473             :             idx_in = 0;
    1474             :             idx_lfe = 0;
    1475             : 
    1476             :             for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
    1477             :             {
    1478             :                 if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) )
    1479             :                 {
    1480             :                     if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) )
    1481             :                     {
    1482             :                         idx_lfe++;
    1483             :                     }
    1484             :                 }
    1485             :                 else
    1486             :                 {
    1487             :                     cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
    1488             :                     idx_in++;
    1489             :                 }
    1490             :             }
    1491             : 
    1492             :             /*LFE handling for split rendering cases*/
    1493             :             if ( ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ||
    1494             :                  ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
    1495             :             {
    1496             :                 for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
    1497             :                 {
    1498             :                     ch = st_ivas->hIntSetup.index_lfe[idx_lfe];
    1499             :                     cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
    1500             :                     idx_in++;
    1501             :                 }
    1502             : 
    1503             :                 if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
    1504             :                 {
    1505             :                     for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
    1506             :                     {
    1507             :                         mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand );
    1508             :                         mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand );
    1509             :                     }
    1510             :                     st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
    1511             :                 }
    1512             :             }
    1513             :         }
    1514             : 
    1515             :         /* Implement binaural rendering */
    1516             :         ivas_binRenderer(
    1517             :             st_ivas->hBinRenderer,
    1518             :             &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
    1519             :             st_ivas->hCombinedOrientationData,
    1520             :             st_ivas->hTcBuffer->subframe_nbslots[subframeIdx],
    1521             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1522             :             NULL,
    1523             : #endif
    1524             :             Cldfb_RealBuffer_Binaural,
    1525             :             Cldfb_ImagBuffer_Binaural,
    1526             :             Cldfb_RealBuffer,
    1527             :             Cldfb_ImagBuffer );
    1528             : 
    1529             :         if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
    1530             :         {
    1531             :             int16_t pos_idx;
    1532             :             for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
    1533             :             {
    1534             :                 for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
    1535             :                 {
    1536             :                     for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
    1537             :                     {
    1538             :                         mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
    1539             :                         mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
    1540             :                     }
    1541             :                 }
    1542             :             }
    1543             :         }
    1544             : 
    1545             :         /* update combined orientation access index */
    1546             :         ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] );
    1547             : 
    1548             :         /* Implement CLDFB synthesis */
    1549             :         for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
    1550             :         {
    1551             :             float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
    1552             :             float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
    1553             : 
    1554             :             for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
    1555             :             {
    1556             :                 RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx];
    1557             :                 ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx];
    1558             :             }
    1559             : 
    1560             :             cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] );
    1561             :         }
    1562             :         slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx];
    1563             :         slot_index_start_cldfb += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx];
    1564             :     }
    1565             : 
    1566             :     st_ivas->hTcBuffer->subframes_rendered = last_sf;
    1567             : 
    1568             :     return;
    1569             : }
    1570             : #endif
    1571             : 
    1572             : 
    1573             : /*-------------------------------------------------------------------------
    1574             :  * ivas_binRenderer()
    1575             :  *
    1576             :  * Fastconv binaural renderer main function
    1577             :  *-------------------------------------------------------------------------*/
    1578             : 
    1579      483522 : void ivas_binRenderer(
    1580             :     BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle                     */
    1581             :     const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
    1582             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i  : combined head and external orientation handle*/
    1583             :     const int16_t numTimeSlots,                           /* i  : number of time slots to render               */
    1584             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1585             :     HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData,
    1586             : #endif
    1587             :     float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : Rotated Binaural signals */
    1588             :     float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : Rotated Binaural signals */
    1589             :     float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                                   /* i  : LS signals       */
    1590             :     float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]                                    /* i  : LS signals       */
    1591             : )
    1592             : {
    1593             :     int16_t chIdx, k;
    1594             :     int16_t pos_idx, num_poses;
    1595             :     float RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1596             :     float ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1597             : 
    1598      483522 :     push_wmops( "fastconv_binaural_rendering" );
    1599      483522 :     num_poses = hBinRenderer->numPoses;
    1600             : 
    1601             :     /* Compute Convolution */
    1602             :     /* memory reset for the binaural output */
    1603      967044 :     for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
    1604             :     {
    1605     1450566 :         for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1606             :         {
    1607     4831614 :             for ( k = 0; k < numTimeSlots; k++ )
    1608             :             {
    1609     3864570 :                 set_zero( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1610     3864570 :                 set_zero( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1611             :             }
    1612             :         }
    1613             :     }
    1614             : 
    1615     7369266 :     for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
    1616             :     {
    1617    34399872 :         for ( k = 0; k < numTimeSlots; k++ )
    1618             :         {
    1619    27514128 :             mvr2r( RealBuffer[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1620    27514128 :             mvr2r( ImagBuffer[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1621             :         }
    1622             :     }
    1623             : 
    1624             :     /* Head rotation in HOA3 or CICPx */
    1625      483522 :     if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb )
    1626             :     {
    1627      192333 :         if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
    1628             :         {
    1629             :             /* Rotation in SHD (HOA3) */
    1630      168333 :             if ( hCombinedOrientationData->shd_rot_max_order == -1 )
    1631             :             {
    1632       56733 :                 rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
    1633             :             }
    1634      111600 :             else if ( hCombinedOrientationData->shd_rot_max_order > 0 )
    1635             :             {
    1636        1200 :                 rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order );
    1637             :             }
    1638             :         }
    1639             :         else
    1640             :         {
    1641             :             /* Rotation in SD (CICPx) */
    1642       24000 :             rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
    1643             :         }
    1644             :     }
    1645             : 
    1646             :     /* HOA decoding to CICP19 if needed*/
    1647      483522 :     if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 &&
    1648      385314 :          ( hBinRenderer->nInChannels != HOA3_CHANNELS && hBinRenderer->nInChannels != HOA2_CHANNELS && hBinRenderer->nInChannels != FOA_CHANNELS ) )
    1649             :     {
    1650       83988 :         ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx );
    1651             :     }
    1652             : 
    1653      483522 :     ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, 0 );
    1654             : 
    1655      483522 :     if ( pMultiBinPoseData != NULL )
    1656             :     {
    1657           0 :         if ( pMultiBinPoseData->num_poses > 1 )
    1658             :         {
    1659             :             IVAS_QUATERNION Quaternions_rel, Quaternions_abs, *Quaternions_ref;
    1660             :             float Rmat_local[3][3];
    1661             : 
    1662           0 :             if ( hCombinedOrientationData && hBinRenderer->rotInCldfb )
    1663             :             {
    1664           0 :                 Quaternions_ref = &hCombinedOrientationData->Quaternions[0];
    1665           0 :                 Quaternions_rel.w = -3.0f; /*euler*/
    1666           0 :                 Quaternions_abs.w = -3.0f;
    1667             : 
    1668           0 :                 if ( hCombinedOrientationData->shd_rot_max_order == 0 )
    1669             :                 {
    1670             :                     /*HOA signal already rotated by DirAC*/
    1671           0 :                     Quaternions_abs.x = 0.0f;
    1672           0 :                     Quaternions_abs.y = 0.0f;
    1673           0 :                     Quaternions_abs.z = 0.0f;
    1674             :                 }
    1675             :                 else
    1676             :                 {
    1677             :                     /*euler*/
    1678           0 :                     Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/
    1679             :                 }
    1680             : 
    1681           0 :                 for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ )
    1682             :                 {
    1683           0 :                     for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
    1684             :                     {
    1685           0 :                         for ( k = 0; k < numTimeSlots; k++ )
    1686             :                         {
    1687           0 :                             mvr2r( RealBuffer_local[chIdx][k], RealBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1688           0 :                             mvr2r( ImagBuffer_local[chIdx][k], ImagBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX );
    1689             :                         }
    1690             :                     }
    1691           0 :                     Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0];
    1692           0 :                     Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1];
    1693           0 :                     Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2];
    1694           0 :                     Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x;
    1695           0 :                     Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y;
    1696           0 :                     Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z;
    1697             : 
    1698           0 :                     QuatToRotMat( Quaternions_abs, Rmat_local );
    1699             : 
    1700           0 :                     if ( hBinRenderer->hInputSetup->is_loudspeaker_setup )
    1701             :                     {
    1702           0 :                         rotateFrame_sd_cldfb( Rmat_local, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
    1703             :                     }
    1704             :                     else
    1705             :                     {
    1706           0 :                         rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hBinRenderer->hInputSetup->ambisonics_order );
    1707             :                     }
    1708             : 
    1709           0 :                     ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx );
    1710             :                 }
    1711             :             }
    1712             :         }
    1713             :     }
    1714             : 
    1715             :     /* Obtain the binaural dmx and compute the reverb */
    1716      483522 :     if ( hBinRenderer->hReverb != NULL )
    1717             :     {
    1718             :         float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1719             :         float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1720             :         float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1721             :         float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1722             : 
    1723      302550 :         ivas_binaural_obtain_DMX( numTimeSlots, hBinRenderer, RealBuffer, ImagBuffer, inRe, inIm );
    1724             : 
    1725      907650 :         for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1726             :         {
    1727     3021894 :             for ( k = 0; k < numTimeSlots; k++ )
    1728             :             {
    1729     2416794 :                 set_zero( reverbRe[chIdx][k], hBinRenderer->max_band );
    1730     2416794 :                 set_zero( reverbIm[chIdx][k], hBinRenderer->max_band );
    1731             :             }
    1732             :         }
    1733             : 
    1734      302550 :         ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe, inIm, reverbRe, reverbIm );
    1735             : 
    1736             :         /* Add the conv module and reverb module output */
    1737      907650 :         for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1738             :         {
    1739     3021894 :             for ( k = 0; k < numTimeSlots; k++ )
    1740             :             {
    1741     4833588 :                 for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
    1742             :                 {
    1743             :                     /* Combine first and second parts to generate binaural output signal with room effect */
    1744     2416794 :                     v_add( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band );
    1745     2416794 :                     v_add( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band );
    1746             :                 }
    1747             :             }
    1748             :         }
    1749             :     }
    1750             : 
    1751      483522 :     pop_wmops();
    1752      483522 :     return;
    1753             : }
    1754             : 
    1755             : 
    1756             : /*-------------------------------------------------------------------------
    1757             :  * ivas_rend_CldfbMultiBinRendProcess()
    1758             :  *
    1759             :  *
    1760             :  *-------------------------------------------------------------------------*/
    1761             : 
    1762           0 : void ivas_rend_CldfbMultiBinRendProcess(
    1763             :     const BINAURAL_RENDERER_HANDLE hCldfbRend,
    1764             :     const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData,
    1765             :     const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
    1766             :     float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
    1767             :     float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
    1768             :     float Cldfb_Out_Real[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o  : Binaural signals */
    1769             :     float Cldfb_Out_Imag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
    1770             :     const int16_t low_res_pre_rend_rot,
    1771             :     const int16_t num_subframes )
    1772             : {
    1773             :     int16_t slot_idx, ch_idx, idx, pose_idx, i, j;
    1774             :     int16_t sf_idx;
    1775             :     float Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1776             :     float Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1777             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1778             :     HEAD_TRACK_DATA head_track_post;
    1779             :     float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1780             :     float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1781             : #else
    1782             :     float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1783             :     float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1784             : #endif
    1785             : 
    1786           0 :     for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
    1787             :     {
    1788           0 :         for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
    1789             :         {
    1790           0 :             idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
    1791           0 :             for ( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ )
    1792             :             {
    1793           0 :                 mvr2r( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
    1794           0 :                 mvr2r( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
    1795             :             }
    1796             :         }
    1797             : 
    1798           0 :         if ( ( *pCombinedOrientationData ) != NULL )
    1799             :         {
    1800           0 :             if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
    1801             :             {
    1802           0 :                 ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0];
    1803           0 :                 for ( i = 0; i < 3; i++ )
    1804             :                 {
    1805           0 :                     for ( j = 0; j < 3; j++ )
    1806             :                     {
    1807           0 :                         ( *pCombinedOrientationData )->Rmat[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat[0][i][j];
    1808             :                     }
    1809             :                 }
    1810             :             }
    1811           0 :             ( *pCombinedOrientationData )->shd_rot_max_order = -1;
    1812             :         }
    1813             : 
    1814             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1815             :         head_track_post.num_quaternions = 0;
    1816             :         head_track_post.shd_rot_max_order = -1;
    1817             :         head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx );
    1818             : 
    1819             : #endif
    1820             : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
    1821             :         ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn );
    1822             : #else
    1823           0 :         ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn );
    1824             : #endif
    1825             : 
    1826           0 :         for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ )
    1827             :         {
    1828           0 :             for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
    1829             :             {
    1830           0 :                 idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
    1831           0 :                 for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
    1832             :                 {
    1833           0 :                     mvr2r( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
    1834           0 :                     mvr2r( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
    1835             :                 }
    1836             :             }
    1837             :         }
    1838             :     }
    1839             : 
    1840           0 :     return;
    1841             : }

Generated by: LCOV version 1.14