LCOV - code coverage report
Current view: top level - lib_dec - ivas_binRenderer_internal_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 517 711 72.7 %
Date: 2025-06-27 02:59:36 Functions: 13 14 92.9 %

          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_fx.h"
      37             : #include "ivas_prot_rend_fx.h"
      38             : #include "cnst.h"
      39             : #include "ivas_cnst.h"
      40             : #include "ivas_rom_rend.h"
      41             : #include "ivas_rom_dec.h"
      42             : #include "ivas_rom_com.h"
      43             : #include "ivas_rom_binauralRenderer.h"
      44             : #include "wmc_auto.h"
      45             : #include "ivas_prot_fx.h"
      46             : #include "ivas_rom_com_fx.h"
      47             : #include "debug.h"
      48             : #define NUM_TAPS_F0_6 ( Word16 )( 58 ) // (Word16) ceil( 0.6f * hBinRenConvModule->numTaps )
      49             : #define NUM_TAPS_F0_5 ( Word16 )( 48 ) // (Word16) ceil( 0.5f * hBinRenConvModule->numTaps )
      50             : #define NUM_TAPS_F0_4 ( Word16 )( 39 ) // (Word16) ceil( 0.4f * hBinRenConvModule->numTaps )
      51             : #define NUM_TAPS_F0_3 ( Word16 )( 29 ) // (Word16) ceil( 0.3f * hBinRenConvModule->numTaps )
      52             : /*-------------------------------------------------------------------------
      53             :  * ivas_binRenderer_filterModule_fx()
      54             :  *
      55             :  *
      56             :  *-------------------------------------------------------------------------*/
      57      136305 : static void ivas_binRenderer_filterModule_fx(
      58             :     Word32 out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : real part of Binaural signals    Q6 */
      59             :     Word32 out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : imag part of Binaural signals    Q6 */
      60             :     Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                           /* i  : real part of LS signals           Q_curr*/
      61             :     Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                           /* i  : imag part of LS signals           Q_curr*/
      62             :     const Word16 numTimeSlots,                                                                         /* i  : number of time slots to process   */
      63             :     BINAURAL_RENDERER_HANDLE hBinRenderer,                                                             /* i/o: fastconv binaural renderer handle */
      64             :     Word16 Q_curr )
      65             : {
      66             :     Word16 bandIdx, k, chIdx, tapIdx;
      67             :     Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx;
      68             :     Word16 Q_filterStates;
      69             :     const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx;
      70             :     Word16 shift_q;
      71      136305 :     Word16 shift_q6 = sub( -29 + 6, Q_curr );
      72      136305 :     Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft;
      73      136305 :     move16();
      74             : 
      75             :     // to be checked: feasibility with 32 bit buffers
      76             :     Word64 Cldfb_RealBuffer_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES];
      77             :     Word64 Cldfb_ImagBuffer_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES];
      78             : 
      79     6310355 :     FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
      80             :     {
      81     6174050 :         set64_fx( &Cldfb_RealBuffer_64fx[0][0], 0, BINAURAL_CHANNELS * MAX_PARAM_SPATIAL_SUBFRAMES );
      82     6174050 :         set64_fx( &Cldfb_ImagBuffer_64fx[0][0], 0, BINAURAL_CHANNELS * MAX_PARAM_SPATIAL_SUBFRAMES );
      83             : 
      84    88510050 :         FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
      85             :         {
      86    82336000 :             filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] );
      87    82336000 :             filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] );
      88             : 
      89    82336000 :             filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx];   // Q29
      90    82336000 :             filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx];   // Q29
      91    82336000 :             filterTapsRightRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx]; // Q29
      92    82336000 :             filterTapsRightImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx]; // Q29
      93             : 
      94   410464000 :             FOR( k = 0; k < numTimeSlots; k++ )
      95             :             {
      96   328128000 :                 Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0;
      97   328128000 :                 move64();
      98   328128000 :                 move64();
      99   328128000 :                 move64();
     100   328128000 :                 move64();
     101             : 
     102  4698766400 :                 FOR( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- )
     103             :                 {
     104  4370638400 :                     filterStatesLeftRealPtr_fx[tapIdx] = filterStatesLeftRealPtr_fx[tapIdx - 1];
     105  4370638400 :                     move32();
     106  4370638400 :                     filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1];
     107  4370638400 :                     move32();
     108  4370638400 :                     Word32 neg_filterStatesLeftImagPtr_fx = L_negate( filterStatesLeftImagPtr_fx[tapIdx] );
     109             : 
     110             : 
     111  4370638400 :                     outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     112  4370638400 :                     outRealLeft_fx = W_mac_32_32( outRealLeft_fx, neg_filterStatesLeftImagPtr_fx, filterTapsLeftImagPtr_fx[tapIdx] );     // Q30 + Q_filterStates
     113             : 
     114  4370638400 :                     outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     115  4370638400 :                     outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     116             : 
     117  4370638400 :                     outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     118  4370638400 :                     outRealRight_fx = W_mac_32_32( outRealRight_fx, neg_filterStatesLeftImagPtr_fx, filterTapsRightImagPtr_fx[tapIdx] );     // Q30 + Q_filterStates
     119             : 
     120  4370638400 :                     outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     121  4370638400 :                     outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
     122             :                 }
     123             : 
     124   328128000 :                 shift_q = add( sub( Q_filterStates, Q_curr ), 1 );
     125             : 
     126   328128000 :                 IF( shift_q != 0 )
     127             :                 {
     128   328128000 :                     outRealLeft_fx = W_shr( outRealLeft_fx, shift_q );   // Q_curr + Q29
     129   328128000 :                     outImagLeft_fx = W_shr( outImagLeft_fx, shift_q );   // Q_curr + Q29
     130   328128000 :                     outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr + Q29
     131   328128000 :                     outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr + Q29
     132   328128000 :                     hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr;
     133   328128000 :                     move16();
     134             :                 }
     135             : 
     136   328128000 :                 filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx];
     137   328128000 :                 move32();
     138   328128000 :                 filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx];
     139   328128000 :                 move32();
     140             : 
     141             : 
     142             :                 /* Left Real and Imag */
     143             : 
     144   328128000 :                 Word32 temp1 = L_shr( filterStatesLeftRealPtr_fx[0], 1 ); // Q_curr -1
     145   328128000 :                 Word32 temp2 = L_shr( filterStatesLeftImagPtr_fx[0], 1 ); // Q_curr -1
     146   328128000 :                 Word32 neg_temp2 = L_negate( temp2 );                     // Q_curr -1
     147             : 
     148             : 
     149   328128000 :                 outRealLeft_fx = W_mac_32_32( outRealLeft_fx, temp1, filterTapsLeftRealPtr_fx[0] );
     150   328128000 :                 outRealLeft_fx = W_mac_32_32( outRealLeft_fx, neg_temp2, filterTapsLeftImagPtr_fx[0] );
     151   328128000 :                 Cldfb_RealBuffer_64fx[0][k] = W_add( Cldfb_RealBuffer_64fx[0][k], outRealLeft_fx ); // Q29 + Q_curr
     152   328128000 :                 move64();
     153             : 
     154   328128000 :                 outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp1, filterTapsLeftImagPtr_fx[0] );
     155   328128000 :                 outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp2, filterTapsLeftRealPtr_fx[0] );
     156   328128000 :                 Cldfb_ImagBuffer_64fx[0][k] = W_add( Cldfb_ImagBuffer_64fx[0][k], outImagLeft_fx ); // Q29 + Q_curr
     157   328128000 :                 move64();
     158             : 
     159             :                 /* Right Real and Imag */
     160   328128000 :                 outRealRight_fx = W_mac_32_32( outRealRight_fx, temp1, filterTapsRightRealPtr_fx[0] );
     161   328128000 :                 outRealRight_fx = W_mac_32_32( outRealRight_fx, neg_temp2, filterTapsRightImagPtr_fx[0] );
     162   328128000 :                 Cldfb_RealBuffer_64fx[1][k] = W_add( Cldfb_RealBuffer_64fx[1][k], outRealRight_fx ); // Q29 + Q_curr
     163   328128000 :                 move64();
     164             : 
     165   328128000 :                 outImagRight_fx = W_mac_32_32( outImagRight_fx, temp1, filterTapsRightImagPtr_fx[0] );
     166   328128000 :                 outImagRight_fx = W_mac_32_32( outImagRight_fx, temp2, filterTapsRightRealPtr_fx[0] );
     167   328128000 :                 Cldfb_ImagBuffer_64fx[1][k] = W_add( Cldfb_ImagBuffer_64fx[1][k], outImagRight_fx ); // Q29 + Q_curr
     168   328128000 :                 move64();
     169             :             }
     170             :         }
     171    18522150 :         FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
     172             :         {
     173    61740500 :             FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
     174             :             {
     175    49392400 :                 out_Conv_CLDFB_real[chIdx][k][bandIdx] = W_shl_sat_l( Cldfb_RealBuffer_64fx[chIdx][k], shift_q6 ); // Q6
     176    49392400 :                 move32();
     177    49392400 :                 out_Conv_CLDFB_imag[chIdx][k][bandIdx] = W_shl_sat_l( Cldfb_ImagBuffer_64fx[chIdx][k], shift_q6 ); // Q6
     178    49392400 :                 move32();
     179             :             }
     180             :         }
     181             :     }
     182             : 
     183             : 
     184      136305 :     return;
     185             : }
     186             : 
     187             : /*-------------------------------------------------------------------------
     188             :  * ivas_binRenderer_convModuleOpen()
     189             :  *
     190             :  * Open convolution module handle of fastconv binaural renderer
     191             :  *-------------------------------------------------------------------------*/
     192         271 : static ivas_error ivas_binRenderer_convModuleOpen(
     193             :     BINAURAL_RENDERER_HANDLE hBinRenderer,
     194             :     const Word16 renderer_type,
     195             :     const Word16 isLoudspeaker,
     196             :     const AUDIO_CONFIG input_config,
     197             :     const HRTFS_FASTCONV_HANDLE hHrtf )
     198             : {
     199             :     Word16 bandIdx, chIdx;
     200             : 
     201             :     BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
     202             : 
     203             :     /*-----------------------------------------------------------------*
     204             :      * prepare library opening
     205             :      *-----------------------------------------------------------------*/
     206             : 
     207         271 :     IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE_FX) malloc( sizeof( BINRENDERER_CONV_MODULE_FX ) ) ) == NULL )
     208             :     {
     209           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     210             :     }
     211             : 
     212         271 :     IF( !isLoudspeaker )
     213             :     {
     214         140 :         hBinRenderer->nInChannels = audioCfg2channels( input_config );
     215         140 :         move16();
     216             :     }
     217             :     ELSE
     218             :     {
     219             :         /* Note: needs to be revisited if multiple LFE support is required */
     220         131 :         hBinRenderer->nInChannels = sub( audioCfg2channels( input_config ), isLoudspeaker );
     221         131 :         move16();
     222             :     }
     223             : 
     224         271 :     IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
     225             :     {
     226          69 :         hBinRenConvModule->numTaps = BINAURAL_NTAPS_MAX;
     227          69 :         move16();
     228             : 
     229             :         /* Use variable order filtering */
     230          69 :         bandIdx = 0;
     231          69 :         move16();
     232         414 :         FOR( ; bandIdx < 5; bandIdx++ )
     233             :         {
     234         345 :             hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
     235         345 :             move16();
     236             :         }
     237         414 :         FOR( ; bandIdx < 10; bandIdx++ )
     238             :         {
     239         345 :             hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_6;
     240         345 :             move16();
     241             :         }
     242         759 :         FOR( ; bandIdx < 20; bandIdx++ )
     243             :         {
     244         690 :             hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_5;
     245         690 :             move16();
     246             :         }
     247         759 :         FOR( ; bandIdx < 30; bandIdx++ )
     248             :         {
     249         690 :             hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_4;
     250         690 :             move16();
     251             :         }
     252        1319 :         FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     253             :         {
     254        1250 :             hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_3;
     255        1250 :             move16();
     256             :         }
     257             :     }
     258             :     ELSE
     259             :     {
     260         202 :         IF( EQ_16( hBinRenderer->ivas_format, SBA_FORMAT ) )
     261             :         {
     262         140 :             hBinRenConvModule->numTaps = BINAURAL_NTAPS_SBA;
     263         140 :             move16();
     264             :         }
     265             :         ELSE
     266             :         {
     267          62 :             hBinRenConvModule->numTaps = BINAURAL_NTAPS;
     268          62 :             move16();
     269             :         }
     270             : 
     271             :         /* Use fixed order filtering */
     272         202 :         bandIdx = 0;
     273         202 :         move16();
     274        8312 :         FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     275             :         {
     276        8110 :             hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
     277        8110 :             move16();
     278             :         }
     279             :     }
     280             : 
     281             :     /* allocate memory for filter states */
     282         271 :     IF( ( hBinRenConvModule->filterTapsLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     283             :     {
     284           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     285             :     }
     286             : 
     287         271 :     IF( ( hBinRenConvModule->filterTapsLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     288             :     {
     289           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     290             :     }
     291             : 
     292         271 :     IF( ( hBinRenConvModule->filterTapsRightReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     293             :     {
     294           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     295             :     }
     296             : 
     297         271 :     IF( ( hBinRenConvModule->filterTapsRightImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     298             :     {
     299           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     300             :     }
     301             : 
     302       11671 :     FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     303             :     {
     304       11400 :         IF( ( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     305             :         {
     306           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     307             :         }
     308             : 
     309       11400 :         IF( ( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     310             :         {
     311           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     312             :         }
     313             : 
     314       11400 :         IF( ( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     315             :         {
     316           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     317             :         }
     318             : 
     319       11400 :         IF( ( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     320             :         {
     321           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     322             :         }
     323             :     }
     324             : 
     325             : 
     326         271 :     IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     327             :     {
     328           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     329             :     }
     330             : 
     331         271 :     IF( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
     332             :     {
     333           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     334             :     }
     335             : 
     336             : 
     337       11671 :     FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     338             :     {
     339       11400 :         IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     340             :         {
     341           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     342             :         }
     343             : 
     344       11400 :         IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
     345             :         {
     346           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     347             :         }
     348             : 
     349             : 
     350      146130 :         FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     351             :         {
     352      134730 :             IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
     353             :             {
     354           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     355             :             }
     356             : 
     357      134730 :             IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
     358             :             {
     359           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
     360             :             }
     361             :         }
     362             :     }
     363             :     /* set memories */
     364       11671 :     FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     365             :     {
     366      146130 :         FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     367             :         {
     368      134730 :             Word16 tmp = 0;
     369      134730 :             move16();
     370             : 
     371      134730 :             IF( isLoudspeaker )
     372             :             {
     373       28650 :                 IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1 ) )
     374             :                 {
     375       19650 :                     tmp = channelIndex_CICP6[chIdx];
     376       19650 :                     move16();
     377             :                 }
     378        9000 :                 ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1 ) )
     379             :                 {
     380           0 :                     tmp = channelIndex_CICP12[chIdx];
     381           0 :                     move16();
     382             :                 }
     383        9000 :                 ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_2 ) )
     384             :                 {
     385         420 :                     tmp = channelIndex_CICP14[chIdx];
     386         420 :                     move16();
     387             :                 }
     388        8580 :                 ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_4 ) )
     389             :                 {
     390           0 :                     tmp = channelIndex_CICP16[chIdx];
     391           0 :                     move16();
     392             :                 }
     393        8580 :                 ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1_4 ) )
     394             :                 {
     395        8580 :                     tmp = channelIndex_CICP19[chIdx];
     396        8580 :                     move16();
     397             :                 }
     398             :             }
     399             : 
     400      134730 :             IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
     401             :             {
     402             :                 /* set the memories to zero */
     403       19150 :                 set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
     404       19150 :                 set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
     405       19150 :                 hBinRenConvModule->Q_filterStatesLeft = 31;
     406       19150 :                 move16();
     407       19150 :                 IF( isLoudspeaker )
     408             :                 {
     409       19150 :                     hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp];
     410       19150 :                     hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftBRIRImag_fx[bandIdx][tmp];
     411       19150 :                     hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightBRIRReal_fx[bandIdx][tmp];
     412       19150 :                     hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightBRIRImag_fx[bandIdx][tmp];
     413             :                 }
     414             :             }
     415             :             ELSE
     416             :             {
     417             :                 /* set the memories to zero */
     418      115580 :                 set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
     419      115580 :                 set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
     420      115580 :                 hBinRenConvModule->Q_filterStatesLeft = 31;
     421      115580 :                 move16();
     422      115580 :                 IF( isLoudspeaker )
     423             :                 {
     424        9500 :                     hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp];
     425        9500 :                     hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_fx[bandIdx][tmp];
     426        9500 :                     hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_fx[bandIdx][tmp];
     427        9500 :                     hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_fx[bandIdx][tmp];
     428             :                 }
     429             :                 ELSE
     430             :                 {
     431      106080 :                     IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
     432             :                     {
     433             :                         /* HOA3 filter coefficients */
     434      106080 :                         hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA3_fx[bandIdx][chIdx];
     435      106080 :                         hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA3_fx[bandIdx][chIdx];
     436      106080 :                         hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA3_fx[bandIdx][chIdx];
     437      106080 :                         hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA3_fx[bandIdx][chIdx];
     438             :                     }
     439           0 :                     ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
     440             :                     {
     441             :                         /* HOA2 filter coefficients */
     442           0 :                         hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA2_fx[bandIdx][chIdx];
     443           0 :                         hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA2_fx[bandIdx][chIdx];
     444           0 :                         hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA2_fx[bandIdx][chIdx];
     445           0 :                         hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA2_fx[bandIdx][chIdx];
     446             :                     }
     447           0 :                     ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_FOA ) )
     448             :                     {
     449             :                         /* FOA filter coefficients */
     450           0 :                         hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_FOA_fx[bandIdx][chIdx];
     451           0 :                         hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_FOA_fx[bandIdx][chIdx];
     452           0 :                         hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_FOA_fx[bandIdx][chIdx];
     453           0 :                         hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_FOA_fx[bandIdx][chIdx];
     454             :                     }
     455             :                     ELSE
     456             :                     {
     457           0 :                         return IVAS_ERR_INVALID_INPUT_FORMAT;
     458             :                     }
     459             :                 }
     460             :             }
     461             :         }
     462             :     }
     463             : 
     464             : 
     465         271 :     hBinRenderer->hBinRenConvModule = hBinRenConvModule;
     466             : 
     467         271 :     return IVAS_ERR_OK;
     468             : }
     469             : 
     470             : /*-------------------------------------------------------------------------*
     471             :  * ivas_init_binaural_hrtf()
     472             :  *
     473             :  * initialize memory for HrtfFastConv structure elements
     474             :  *-------------------------------------------------------------------------*/
     475          61 : void ivas_init_binaural_hrtf_fx(
     476             :     HRTFS_FASTCONV *HrtfFastConv /* i/o: FASTCONV HRTF structure */
     477             : )
     478             : {
     479             :     Word16 i;
     480             : 
     481          61 :     HrtfFastConv->leftHRIRReal_HOA3_fx = NULL;
     482          61 :     HrtfFastConv->leftHRIRImag_HOA3_fx = NULL;
     483          61 :     HrtfFastConv->rightHRIRReal_HOA3_fx = NULL;
     484          61 :     HrtfFastConv->rightHRIRImag_HOA3_fx = NULL;
     485          61 :     HrtfFastConv->FASTCONV_HOA3_latency_s_fx = 0;
     486          61 :     move32();
     487             : 
     488          61 :     HrtfFastConv->leftHRIRReal_fx = NULL;
     489          61 :     HrtfFastConv->leftHRIRImag_fx = NULL;
     490          61 :     HrtfFastConv->rightHRIRReal_fx = NULL;
     491          61 :     HrtfFastConv->rightHRIRImag_fx = NULL;
     492          61 :     HrtfFastConv->FASTCONV_HRIR_latency_s_fx = 0;
     493          61 :     move32();
     494             : 
     495          61 :     HrtfFastConv->leftBRIRReal_fx = NULL;
     496          61 :     HrtfFastConv->leftBRIRImag_fx = NULL;
     497          61 :     HrtfFastConv->rightBRIRReal_fx = NULL;
     498          61 :     HrtfFastConv->rightBRIRImag_fx = NULL;
     499          61 :     HrtfFastConv->FASTCONV_BRIR_latency_s_fx = 0;
     500          61 :     move32();
     501             : 
     502          61 :     HrtfFastConv->leftHRIRReal_HOA2_fx = NULL;
     503          61 :     HrtfFastConv->leftHRIRImag_HOA2_fx = NULL;
     504          61 :     HrtfFastConv->rightHRIRReal_HOA2_fx = NULL;
     505          61 :     HrtfFastConv->rightHRIRImag_HOA2_fx = NULL;
     506          61 :     HrtfFastConv->FASTCONV_HOA2_latency_s_fx = 0;
     507          61 :     move32();
     508             : 
     509          61 :     HrtfFastConv->leftHRIRReal_FOA_fx = NULL;
     510          61 :     HrtfFastConv->leftHRIRImag_FOA_fx = NULL;
     511          61 :     HrtfFastConv->rightHRIRReal_FOA_fx = NULL;
     512          61 :     HrtfFastConv->rightHRIRImag_FOA_fx = NULL;
     513          61 :     HrtfFastConv->FASTCONV_FOA_latency_s_fx = 0;
     514          61 :     move32();
     515             : 
     516          61 :     HrtfFastConv->allocate_init_flag = 0;
     517          61 :     move16();
     518             : 
     519        3721 :     FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
     520             :     {
     521        3660 :         HrtfFastConv->fastconvReverberationTimes_fx[i] = 0;
     522        3660 :         move32();
     523        3660 :         HrtfFastConv->fastconvReverberationEneCorrections_fx[i] = 0;
     524        3660 :         move32();
     525             :     }
     526             : 
     527          61 :     return;
     528             : }
     529             : 
     530             : /*-------------------------------------------------------------------------*
     531             :  * ivas_alloc_pppMem()
     532             :  *
     533             :  * Allocate memory for tripple pointer elements
     534             :  *-------------------------------------------------------------------------*/
     535         728 : static ivas_error ivas_alloc_pppMem_fx(
     536             :     Word32 ****pppMem, /*Qx*/
     537             :     const Word16 dim1,
     538             :     const Word16 dim2,
     539             :     const Word16 dim3,
     540             :     const Word16 allocate_init_flag )
     541             : {
     542             :     Word16 i, j;
     543         728 :     Word32 ***localMem = NULL;
     544             : 
     545         728 :     IF( ( localMem = (Word32 ***) malloc( dim1 * sizeof( Word32 ** ) ) ) == NULL )
     546             :     {
     547           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     548             :     }
     549             : 
     550       37128 :     FOR( i = 0; i < dim1; i++ ){
     551       36400 :         IF( ( localMem[i] = (Word32 **) malloc( dim2 * sizeof( Word32 * ) ) ) == NULL ){
     552           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     553             : }
     554       36400 : IF( allocate_init_flag == 0 )
     555             : {
     556      294400 :     FOR( j = 0; j < dim2; j++ )
     557             :     {
     558      271400 :         IF( ( localMem[i][j] = (Word32 *) malloc( dim3 * sizeof( Word32 ) ) ) == NULL )
     559             :         {
     560           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
     561             :         }
     562             :     }
     563             : }
     564             : }
     565             : 
     566         728 : *pppMem = localMem;
     567             : 
     568         728 : return IVAS_ERR_OK;
     569             : }
     570             : 
     571             : /*-------------------------------------------------------------------------*
     572             :  * ivas_allocate_binaural_hrtf()
     573             :  *
     574             :  * Allocate memory for HrtfFastConv structure elements
     575             :  *-------------------------------------------------------------------------*/
     576         153 : ivas_error ivas_allocate_binaural_hrtf_fx(
     577             :     HRTFS_FASTCONV *HrtfFastConv,                       /* i/o: FASTCONV HRTF structure     */
     578             :     const AUDIO_CONFIG input_config,                    /* i  : input audio configuration   */
     579             :     const BINAURAL_INPUT_AUDIO_CONFIG bin_input_config, /* i  : binaural input audio config */
     580             :     const RENDERER_TYPE renderer_type,                  /* i  : renderer type               */
     581             :     const Word16 allocate_init_flag                     /* i  : Memory allocation flag      */
     582             : )
     583             : {
     584         153 :     test();
     585         153 :     IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) )
     586             :     {
     587          52 :         test();
     588          52 :         test();
     589          52 :         test();
     590          52 :         IF( ( HrtfFastConv->leftHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3_fx != NULL ) )
     591             :         {
     592           0 :             return IVAS_ERR_OK;
     593             :         }
     594             :         ELSE
     595             :         {
     596          52 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     597             :             {
     598           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA3" );
     599             :             }
     600          52 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     601             :             {
     602           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA3" );
     603             :             }
     604          52 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     605             :             {
     606           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA3" );
     607             :             }
     608          52 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     609             :             {
     610           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3" );
     611             :             }
     612             :         }
     613             :     }
     614             : 
     615         153 :     test();
     616         153 :     IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) )
     617             :     {
     618          23 :         test();
     619          23 :         test();
     620          23 :         test();
     621          23 :         IF( ( HrtfFastConv->leftHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2_fx != NULL ) )
     622             :         {
     623           0 :             return IVAS_ERR_OK;
     624             :         }
     625             :         ELSE
     626             :         {
     627          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     628             :             {
     629           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA2" );
     630             :             }
     631          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     632             :             {
     633           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA2" );
     634             :             }
     635          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     636             :             {
     637           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA2" );
     638             :             }
     639          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     640             :             {
     641           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2" );
     642             :             }
     643             :         }
     644             :     }
     645             : 
     646         153 :     test();
     647         153 :     IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_FOA ) )
     648             :     {
     649          23 :         test();
     650          23 :         test();
     651          23 :         test();
     652          23 :         IF( ( HrtfFastConv->leftHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA_fx != NULL ) )
     653             :         {
     654           0 :             return IVAS_ERR_OK;
     655             :         }
     656             :         ELSE
     657             :         {
     658          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     659             :             {
     660           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_FOA" );
     661             :             }
     662          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     663             :             {
     664           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_FOA" );
     665             :             }
     666          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     667             :             {
     668           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_FOA" );
     669             :             }
     670          23 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
     671             :             {
     672           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" );
     673             :             }
     674             :         }
     675             :     }
     676             : 
     677         153 :     test();
     678         153 :     IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
     679             :     {
     680         140 :         test();
     681         140 :         test();
     682         140 :         test();
     683         140 :         IF( ( HrtfFastConv->leftHRIRReal_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_fx != NULL ) )
     684             :         {
     685          92 :             return IVAS_ERR_OK;
     686             :         }
     687             :         ELSE
     688             :         {
     689          48 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
     690             :             {
     691           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal" );
     692             :             }
     693          48 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
     694             :             {
     695           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag" );
     696             :             }
     697          48 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
     698             :             {
     699           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal" );
     700             :             }
     701          48 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
     702             :             {
     703           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag" );
     704             :             }
     705             :         }
     706             :     }
     707             : 
     708          61 :     test();
     709          61 :     IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
     710             :     {
     711          36 :         test();
     712          36 :         test();
     713          36 :         test();
     714          36 :         IF( ( HrtfFastConv->leftBRIRReal_fx != NULL ) && ( HrtfFastConv->leftBRIRImag_fx != NULL ) && ( HrtfFastConv->rightBRIRReal_fx != NULL ) && ( HrtfFastConv->rightBRIRImag_fx != NULL ) )
     715             :         {
     716           0 :             return IVAS_ERR_OK;
     717             :         }
     718             :         ELSE
     719             :         {
     720          36 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
     721             :             {
     722           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRReal" );
     723             :             }
     724          36 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
     725             :             {
     726           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRImag" );
     727             :             }
     728          36 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
     729             :             {
     730           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRReal" );
     731             :             }
     732          36 :             IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
     733             :             {
     734           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag" );
     735             :             }
     736             :         }
     737             :     }
     738             : 
     739          61 :     return IVAS_ERR_OK;
     740             : }
     741             : 
     742             : /*-------------------------------------------------------------------------*
     743             :  * ivas_binaural_HRTF_open()
     744             :  *
     745             :  *
     746             :  *-------------------------------------------------------------------------*/
     747         271 : static ivas_error ivas_binaural_hrtf_open_fx(
     748             :     HRTFS_FASTCONV_HANDLE *hHrtfFastConv, /* i  : fastconv HRTF handle */
     749             :     const AUDIO_CONFIG input_config,      /* i  : output configuration */
     750             :     const RENDERER_TYPE renderer_type     /* i  : renderer type        */
     751             : )
     752             : {
     753             :     Word16 i, j;
     754             :     ivas_error error;
     755             : 
     756         271 :     test();
     757         271 :     IF( hHrtfFastConv != NULL && *hHrtfFastConv != NULL )
     758             :     {
     759             :         /* Tables already loaded from file */
     760         233 :         return IVAS_ERR_OK;
     761             :     }
     762             :     ELSE
     763             :     {
     764             :         /* Initialise tables from ROM */
     765             :         HRTFS_FASTCONV *HrtfFastConv;
     766             : 
     767          38 :         IF( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL )
     768             :         {
     769           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" );
     770             :         }
     771             : 
     772          38 :         ivas_init_binaural_hrtf_fx( HrtfFastConv );
     773             : 
     774          38 :         test();
     775          38 :         IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
     776             :         {
     777          25 :             HrtfFastConv->FASTCONV_HRIR_latency_s_fx = FASTCONV_HRIR_latency_s_fx;
     778          25 :             move32();
     779             :         }
     780          38 :         if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
     781             :         {
     782           0 :             HrtfFastConv->FASTCONV_HOA2_latency_s_fx = FASTCONV_HOA2_latency_s_fx;
     783           0 :             move32();
     784             :         }
     785          38 :         if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
     786             :         {
     787          29 :             HrtfFastConv->FASTCONV_HOA3_latency_s_fx = FASTCONV_HOA3_latency_s_fx;
     788          29 :             move32();
     789             :         }
     790          38 :         if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
     791             :         {
     792           0 :             HrtfFastConv->FASTCONV_FOA_latency_s_fx = FASTCONV_FOA_latency_s_fx;
     793           0 :             move32();
     794             :         }
     795          38 :         test();
     796          38 :         IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
     797             :         {
     798          13 :             HrtfFastConv->FASTCONV_BRIR_latency_s_fx = FASTCONV_BRIR_latency_s_fx;
     799          13 :             move32();
     800             :         }
     801             : 
     802          38 :         HrtfFastConv->allocate_init_flag = 1;
     803          38 :         move16();
     804             : 
     805          38 :         IF( NE_32( ( error = ivas_allocate_binaural_hrtf_fx( HrtfFastConv, input_config, BINAURAL_INPUT_AUDIO_CONFIG_INVALID, renderer_type, HrtfFastConv->allocate_init_flag ) ), IVAS_ERR_OK ) )
     806             :         {
     807           0 :             return error;
     808             :         }
     809        1938 :         FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
     810             :         {
     811        1900 :             IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
     812             :             {
     813       20000 :                 FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
     814             :                 {
     815       18750 :                     HrtfFastConv->leftHRIRReal_fx[i][j] = leftHRIRReal_fx[i][j];
     816       18750 :                     HrtfFastConv->leftHRIRImag_fx[i][j] = leftHRIRImag_fx[i][j];
     817       18750 :                     HrtfFastConv->rightHRIRReal_fx[i][j] = rightHRIRReal_fx[i][j];
     818       18750 :                     HrtfFastConv->rightHRIRImag_fx[i][j] = rightHRIRImag_fx[i][j];
     819             :                 }
     820             :             }
     821         650 :             ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
     822             :             {
     823       10400 :                 FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
     824             :                 {
     825        9750 :                     HrtfFastConv->leftBRIRReal_fx[i][j] = leftBRIRReal_fx[i][j];
     826        9750 :                     HrtfFastConv->leftBRIRImag_fx[i][j] = leftBRIRImag_fx[i][j];
     827        9750 :                     HrtfFastConv->rightBRIRReal_fx[i][j] = rightBRIRReal_fx[i][j];
     828        9750 :                     HrtfFastConv->rightBRIRImag_fx[i][j] = rightBRIRImag_fx[i][j];
     829             :                 }
     830             :             }
     831        1900 :             IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
     832             :             {
     833       24650 :                 FOR( j = 0; j < HOA3_CHANNELS; j++ )
     834             :                 {
     835       23200 :                     HrtfFastConv->leftHRIRReal_HOA3_fx[i][j] = leftHRIRReal_HOA3_fx[i][j];
     836       23200 :                     HrtfFastConv->leftHRIRImag_HOA3_fx[i][j] = leftHRIRImag_HOA3_fx[i][j];
     837       23200 :                     HrtfFastConv->rightHRIRReal_HOA3_fx[i][j] = rightHRIRReal_HOA3_fx[i][j];
     838       23200 :                     HrtfFastConv->rightHRIRImag_HOA3_fx[i][j] = rightHRIRImag_HOA3_fx[i][j];
     839             :                 }
     840             :             }
     841        1900 :             IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
     842             :             {
     843           0 :                 FOR( j = 0; j < HOA2_CHANNELS; j++ )
     844             :                 {
     845           0 :                     HrtfFastConv->leftHRIRReal_HOA2_fx[i][j] = leftHRIRReal_HOA2_fx[i][j];
     846           0 :                     HrtfFastConv->leftHRIRImag_HOA2_fx[i][j] = leftHRIRImag_HOA2_fx[i][j];
     847           0 :                     HrtfFastConv->rightHRIRReal_HOA2_fx[i][j] = rightHRIRReal_HOA2_fx[i][j];
     848           0 :                     HrtfFastConv->rightHRIRImag_HOA2_fx[i][j] = rightHRIRImag_HOA2_fx[i][j];
     849             :                 }
     850             :             }
     851        1900 :             IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
     852             :             {
     853           0 :                 FOR( j = 0; j < FOA_CHANNELS; j++ )
     854             :                 {
     855           0 :                     HrtfFastConv->leftHRIRReal_FOA_fx[i][j] = leftHRIRReal_FOA_fx[i][j];
     856           0 :                     HrtfFastConv->leftHRIRImag_FOA_fx[i][j] = leftHRIRImag_FOA_fx[i][j];
     857           0 :                     HrtfFastConv->rightHRIRReal_FOA_fx[i][j] = rightHRIRReal_FOA_fx[i][j];
     858           0 :                     HrtfFastConv->rightHRIRImag_FOA_fx[i][j] = rightHRIRImag_FOA_fx[i][j];
     859             :                 }
     860             :             }
     861             :         }
     862          38 :         Copy32( fastconvReverberationTimes_fx, HrtfFastConv->fastconvReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX );
     863          38 :         Copy32( fastconvReverberationEneCorrections_fx, HrtfFastConv->fastconvReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX );
     864             : 
     865          38 :         *hHrtfFastConv = HrtfFastConv;
     866             :     }
     867             : 
     868          38 :     return IVAS_ERR_OK;
     869             : }
     870             : /*-------------------------------------------------------------------------*
     871             :  * ivas_binaural_obtain_DMX_fx()
     872             :  *
     873             :  *
     874             :  *-------------------------------------------------------------------------*/
     875             : 
     876           0 : static void ivas_binaural_obtain_DMX_fx(
     877             :     const Word16 numTimeSlots,
     878             :     BINAURAL_RENDERER_HANDLE hBinRenderer,                                /* i/o: fastconv binaural renderer handle */
     879             :     Word32 RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Contains the LS signals         Q_in  */
     880             :     Word32 ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i  : Contains the LS signals         Q_in  */
     881             :     Word32 realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],    /*Q_in-1*/
     882             :     Word32 imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] )   /*Q_in-1*/
     883             : {
     884             :     Word16 chIdx, bandIdx, k;
     885             : 
     886           0 :     test();
     887           0 :     IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
     888             :     {
     889             :         /* Obtain the downmix */
     890             :         Word32 P_in_fx[CLDFB_NO_CHANNELS_MAX];
     891             :         Word32 P_out_fx, factEQ_fx;
     892             :         Word16 chOutIdx;
     893             :         Word32 temp1_fx, temp2_fx;
     894             : 
     895           0 :         FOR( k = 0; k < numTimeSlots; k++ )
     896             :         {
     897           0 :             FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
     898             :             {
     899           0 :                 set32_fx( realDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
     900           0 :                 set32_fx( imagDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
     901             :             }
     902             :         }
     903             : 
     904           0 :         FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
     905             :         {
     906           0 :             set32_fx( P_in_fx, 0, hBinRenderer->conv_band );
     907             : 
     908           0 :             FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     909             :             {
     910           0 :                 Word32 dmxConst = hBinRenderer->hReverb->dmxmtx_fx[chOutIdx][chIdx];
     911           0 :                 move32();
     912             : 
     913           0 :                 FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     914             :                 {
     915           0 :                     FOR( k = 0; k < numTimeSlots; k++ )
     916             :                     {
     917           0 :                         temp1_fx = Mpy_32_32( RealBuffer[chIdx][k][bandIdx], dmxConst );                  // Q_in
     918           0 :                         temp2_fx = Mpy_32_32( ImagBuffer[chIdx][k][bandIdx], dmxConst );                  // Q_in
     919           0 :                         realDMX[chOutIdx][k][bandIdx] = L_add( realDMX[chOutIdx][k][bandIdx], temp1_fx ); // Q_in
     920           0 :                         move32();
     921           0 :                         imagDMX[chOutIdx][k][bandIdx] = L_add( imagDMX[chOutIdx][k][bandIdx], temp2_fx ); // Q_in
     922           0 :                         move32();
     923             : 
     924           0 :                         P_in_fx[bandIdx] = L_add( P_in_fx[bandIdx], L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); // Q31-2*Q_in
     925           0 :                         move32();
     926             :                     }
     927             :                 }
     928             :             }
     929             : 
     930           0 :             FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     931             :             {
     932           0 :                 P_out_fx = 0;
     933           0 :                 move32();
     934           0 :                 FOR( k = 0; k < numTimeSlots; k++ )
     935             :                 {
     936           0 :                     temp1_fx = realDMX[chOutIdx][k][bandIdx];
     937           0 :                     move32();
     938           0 :                     temp2_fx = imagDMX[chOutIdx][k][bandIdx];
     939           0 :                     move32();
     940           0 :                     P_out_fx = L_add( P_out_fx, L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); // Q31-2*Q_in
     941             :                 }
     942           0 :                 test();
     943           0 :                 IF( ( P_in_fx[bandIdx] <= 0 ) || ( P_out_fx <= 0 ) )
     944             :                 {
     945           0 :                     factEQ_fx = 0x40000000; // 1.0f in Q30
     946           0 :                     move32();
     947             :                 }
     948             :                 ELSE
     949             :                 {
     950           0 :                     Word16 div = divide3232( P_in_fx[bandIdx], P_out_fx );
     951           0 :                     Word16 exp = norm_l( div );
     952           0 :                     factEQ_fx = Sqrt32( L_shl( div, Q16 ), &exp );
     953           0 :                     factEQ_fx = L_shl( factEQ_fx, sub( exp, 1 ) ); // Q30
     954             :                 }
     955           0 :                 if ( factEQ_fx <= 0 )
     956             :                 {
     957           0 :                     factEQ_fx = 0x40000000; // 1.0f in Q30
     958           0 :                     move32();
     959             :                 }
     960             : 
     961           0 :                 factEQ_fx = L_max( L_min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 , 0x7fffffff -> (1.0f in Q31)-1, 0x20000000 ->1.0f in Q29
     962           0 :                 FOR( k = 0; k < numTimeSlots; k++ )
     963             :                 {
     964           0 :                     realDMX[chOutIdx][k][bandIdx] = Mpy_32_32( realDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in - 1
     965           0 :                     move32();
     966           0 :                     imagDMX[chOutIdx][k][bandIdx] = Mpy_32_32( imagDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in - 1
     967           0 :                     move32();
     968             :                 }
     969             :             }
     970             :         }
     971             :     }
     972           0 :     ELSE IF( EQ_32( hBinRenderer->ivas_format, SBA_FORMAT ) || EQ_32( hBinRenderer->ivas_format, MASA_FORMAT ) )
     973             :     {
     974             :         Word32 *outRealLeftPtr_fx, *outImagLeftPtr_fx, *outRealRightPtr_fx, *outImagRightPtr_fx;
     975             :         Word32 *inRealPtr_fx, *inImagPtr_fx;
     976             : 
     977             :         /*compute DMX */
     978           0 :         FOR( k = 0; k < numTimeSlots; k++ )
     979             :         {
     980           0 :             outRealLeftPtr_fx = realDMX[0][k];
     981           0 :             outImagLeftPtr_fx = imagDMX[0][k];
     982           0 :             outRealRightPtr_fx = realDMX[1][k];
     983           0 :             outImagRightPtr_fx = imagDMX[1][k];
     984           0 :             set32_fx( outRealLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
     985           0 :             set32_fx( outImagLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
     986           0 :             set32_fx( outRealRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
     987           0 :             set32_fx( outImagRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
     988             : 
     989           0 :             FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
     990             :             {
     991           0 :                 Word32 foa_const_fx = L_shl( hBinRenderer->hReverb->foa_enc_fx[chIdx][1], 1 ); // Q30
     992             : 
     993           0 :                 inRealPtr_fx = (Word32 *) &( RealBuffer[chIdx][k][0] );
     994           0 :                 inImagPtr_fx = (Word32 *) &( ImagBuffer[chIdx][k][0] );
     995             : 
     996           0 :                 FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
     997             :                 {
     998           0 :                     outRealLeftPtr_fx[bandIdx] = L_add( outRealLeftPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
     999           0 :                     move32();
    1000           0 :                     outImagLeftPtr_fx[bandIdx] = L_add( outImagLeftPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
    1001           0 :                     move32();
    1002             : 
    1003           0 :                     outRealRightPtr_fx[bandIdx] = L_add( outRealRightPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
    1004           0 :                     move32();
    1005           0 :                     outImagRightPtr_fx[bandIdx] = L_add( outImagRightPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
    1006           0 :                     move32();
    1007             :                 }
    1008             :             }
    1009             :         }
    1010             :     }
    1011             : 
    1012           0 :     return;
    1013             : }
    1014             : 
    1015             : /*-------------------------------------------------------------------------
    1016             :  * ivas_binRenderer_open()
    1017             :  *
    1018             :  * Open fastconv binaural renderer handle
    1019             :  *-------------------------------------------------------------------------*/
    1020         271 : ivas_error ivas_binRenderer_open_fx(
    1021             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure  */
    1022             : )
    1023             : {
    1024             :     BINAURAL_RENDERER_HANDLE hBinRenderer;
    1025             :     Word16 convBand, chIdx, k;
    1026             :     ivas_error error;
    1027             : 
    1028         271 :     error = IVAS_ERR_OK;
    1029         271 :     move32();
    1030             : 
    1031             :     /*-----------------------------------------------------------------*
    1032             :      * prepare library opening
    1033             :      *-----------------------------------------------------------------*/
    1034             : 
    1035         271 :     IF( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
    1036             :     {
    1037           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
    1038             :     }
    1039             : 
    1040         271 :     hBinRenderer->hInputSetup = &st_ivas->hIntSetup;
    1041             : 
    1042             :     /* Define of head rotation has to be done in binRendeder in CLDFB*/
    1043         271 :     hBinRenderer->rotInCldfb = 0;
    1044         271 :     move16();
    1045         271 :     test();
    1046         271 :     if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
    1047             :     {
    1048         178 :         hBinRenderer->rotInCldfb = 1;
    1049         178 :         move16();
    1050             :     }
    1051             : 
    1052             : 
    1053             :     /* Declare some common variables needed for renderer */
    1054             :     /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
    1055         271 :     IF( st_ivas->hIntSetup.is_loudspeaker_setup )
    1056             :     {
    1057         124 :         hBinRenderer->ivas_format = MC_FORMAT;
    1058         124 :         move32();
    1059             :     }
    1060             :     ELSE
    1061             :     {
    1062         147 :         hBinRenderer->ivas_format = SBA_FORMAT;
    1063         147 :         move32();
    1064             :     }
    1065         271 :     hBinRenderer->max_band = extract_l( Mpy_32_32( Mpy_32_32( BINAURAL_MAXBANDS_Q25, L_shl( st_ivas->hDecoderConfig->output_Fs, Q6 ) ), ONE_BY_48000_Q31 ) );
    1066         271 :     move16();
    1067             : 
    1068         271 :     convBand = hBinRenderer->max_band;
    1069         271 :     move16();
    1070             : 
    1071         271 :     hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
    1072         271 :     move16();
    1073             : 
    1074         271 :     IF( GT_16( convBand, BINAURAL_CONVBANDS ) )
    1075             :     {
    1076         174 :         hBinRenderer->conv_band = BINAURAL_CONVBANDS;
    1077         174 :         move16();
    1078             :     }
    1079             :     ELSE
    1080             :     {
    1081          97 :         hBinRenderer->conv_band = convBand;
    1082          97 :         move16();
    1083             :     }
    1084             : 
    1085             :     /*LFE rendering switched off by default*/
    1086         271 :     hBinRenderer->render_lfe = 0;
    1087         271 :     move16();
    1088             : 
    1089         271 :     test();
    1090         271 :     if ( NE_32( st_ivas->ivas_format, ISM_FORMAT ) && st_ivas->hIntSetup.is_loudspeaker_setup )
    1091             :     {
    1092         124 :         hBinRenderer->render_lfe = 1;
    1093         124 :         move16();
    1094             :     }
    1095             : 
    1096             :     /* Load HRTF tables */
    1097         271 :     IF( NE_32( ( error = ivas_binaural_hrtf_open_fx( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ), IVAS_ERR_OK ) )
    1098             :     {
    1099           0 :         return error;
    1100             :     }
    1101             : 
    1102         271 :     test();
    1103         271 :     IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
    1104           7 :     {
    1105             :         IVAS_OUTPUT_SETUP out_setup;
    1106             : 
    1107             :         /* Allocate memories and buffers needed for convolutional module in CICP19 */
    1108           7 :         IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
    1109             :         {
    1110           0 :             return error;
    1111             :         }
    1112             : 
    1113           7 :         ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );
    1114             : 
    1115           7 :         IF( st_ivas->hoa_dec_mtx == NULL )
    1116             :         {
    1117           7 :             IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
    1118             :             {
    1119           0 :                 return error;
    1120             :             }
    1121             :         }
    1122             : 
    1123           7 :         hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
    1124           7 :         st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
    1125           7 :         move32();
    1126             :     }
    1127             :     ELSE
    1128             :     {
    1129             :         /* Allocate memories and buffers needed for convolutional module */
    1130         264 :         IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
    1131             :         {
    1132           0 :             return error;
    1133             :         }
    1134             : 
    1135         264 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
    1136             :         {
    1137         202 :             IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
    1138             :             {
    1139          62 :                 st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s_fx;
    1140          62 :                 move32();
    1141             :             }
    1142             :             ELSE
    1143             :             {
    1144         140 :                 IF( EQ_16( hBinRenderer->nInChannels, 16 ) )
    1145             :                 {
    1146         140 :                     st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx;
    1147         140 :                     move32();
    1148             :                 }
    1149           0 :                 ELSE IF( EQ_16( hBinRenderer->nInChannels, 9 ) )
    1150             :                 {
    1151           0 :                     st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s_fx;
    1152           0 :                     move32();
    1153             :                 }
    1154           0 :                 ELSE IF( EQ_16( hBinRenderer->nInChannels, 4 ) )
    1155             :                 {
    1156           0 :                     st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s_fx;
    1157           0 :                     move32();
    1158             :                 }
    1159             :                 ELSE
    1160             :                 {
    1161           0 :                     return IVAS_ERR_INVALID_INPUT_FORMAT;
    1162             :                 }
    1163             :             }
    1164             :         }
    1165             :         ELSE
    1166             :         {
    1167             :             /* same value for MC or HOA both use MC BRIR*/
    1168          62 :             st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
    1169          62 :             move32();
    1170             :         }
    1171             :     }
    1172             : 
    1173             :     /* Allocate memories needed for reverb module */
    1174         271 :     test();
    1175         271 :     IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_32( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
    1176             :     {
    1177           0 :         IF( NE_32( ( error = ivas_binaural_reverb_open_fastconv_fx( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
    1178             :         {
    1179           0 :             return error;
    1180             :         }
    1181             : 
    1182             :         /* initialize the dmx matrix */
    1183           0 :         FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1184             :         {
    1185           0 :             FOR( k = 0; k < hBinRenderer->nInChannels; k++ )
    1186             :             {
    1187           0 :                 hBinRenderer->hReverb->dmxmtx_fx[chIdx][k] = dmxmtx_table_fx[chIdx][k];
    1188           0 :                 move32();
    1189             :             }
    1190             :         }
    1191             :     }
    1192             :     ELSE
    1193             :     {
    1194         271 :         hBinRenderer->hReverb = NULL;
    1195             :     }
    1196             : 
    1197         271 :     hBinRenderer->hEFAPdata = NULL;
    1198             : 
    1199         271 :     IF( hBinRenderer->hReverb != NULL )
    1200             :     {
    1201           0 :         test();
    1202           0 :         test();
    1203           0 :         IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
    1204             :         {
    1205           0 :             FOR( k = 0; k < 11; k++ )
    1206             :             {
    1207           0 :                 ivas_dirac_dec_get_response_fx( extract_l( L_shr_r( ls_azimuth_CICP19_fx[k], 22 ) ), extract_l( L_shr_r( ls_elevation_CICP19_fx[k], 22 ) ), hBinRenderer->hReverb->foa_enc_fx[k], 1, Q29 );
    1208             :                 // Q29: hBinRenderer->hReverb->foa_enc_fx[k]
    1209             :             }
    1210             :         }
    1211           0 :         ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
    1212             :         {
    1213           0 :             IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
    1214             :             {
    1215           0 :                 return error;
    1216             :             }
    1217             : 
    1218             :             /* Copy handles to bin renderer handle*/
    1219           0 :             hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
    1220             :         }
    1221             :     }
    1222             : 
    1223             :     /* Copy the handles to main handle */
    1224         271 :     st_ivas->hBinRenderer = hBinRenderer;
    1225             : 
    1226         271 :     return error;
    1227             : }
    1228             : 
    1229             : /*-------------------------------------------------------------------------
    1230             :  * ivas_binRenderer_convModuleClose()
    1231             :  *
    1232             :  * Close convolution module handle of fastconv binaural renderer
    1233             :  *------------------------------------------------------------------------*/
    1234         271 : static void ivas_binRenderer_convModuleClose_fx(
    1235             :     BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle    */
    1236             : )
    1237             : {
    1238             :     Word16 bandIdx, chIdx;
    1239             : 
    1240             :     BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
    1241             : 
    1242         271 :     hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
    1243             : 
    1244         271 :     IF( hBinRenConvModule == NULL )
    1245             :     {
    1246           0 :         return;
    1247             :     }
    1248             : 
    1249       11671 :     FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
    1250             :     {
    1251       11400 :         free( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] );
    1252       11400 :         hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = NULL;
    1253             : 
    1254       11400 :         free( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] );
    1255       11400 :         hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = NULL;
    1256             : 
    1257       11400 :         free( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] );
    1258       11400 :         hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = NULL;
    1259             : 
    1260       11400 :         free( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] );
    1261       11400 :         hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = NULL;
    1262             :     }
    1263             : 
    1264         271 :     free( hBinRenConvModule->filterTapsLeftReal_fx );
    1265         271 :     hBinRenConvModule->filterTapsLeftReal_fx = NULL;
    1266             : 
    1267         271 :     free( hBinRenConvModule->filterTapsLeftImag_fx );
    1268         271 :     hBinRenConvModule->filterTapsLeftImag_fx = NULL;
    1269             : 
    1270         271 :     free( hBinRenConvModule->filterTapsRightReal_fx );
    1271         271 :     hBinRenConvModule->filterTapsRightReal_fx = NULL;
    1272             : 
    1273         271 :     free( hBinRenConvModule->filterTapsRightImag_fx );
    1274         271 :     hBinRenConvModule->filterTapsRightImag_fx = NULL;
    1275             : 
    1276       11671 :     FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
    1277             :     {
    1278      146130 :         FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
    1279             :         {
    1280      134730 :             free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] );
    1281      134730 :             hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = NULL;
    1282             : 
    1283      134730 :             free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] );
    1284      134730 :             hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL;
    1285             :         }
    1286             : 
    1287       11400 :         free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] );
    1288       11400 :         hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = NULL;
    1289             : 
    1290       11400 :         free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] );
    1291       11400 :         hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL;
    1292             :     }
    1293             : 
    1294         271 :     free( hBinRenConvModule->filterStatesLeftReal_fx );
    1295         271 :     hBinRenConvModule->filterStatesLeftReal_fx = NULL;
    1296             : 
    1297         271 :     free( hBinRenConvModule->filterStatesLeftImag_fx );
    1298         271 :     hBinRenConvModule->filterStatesLeftImag_fx = NULL;
    1299             : 
    1300             : 
    1301         271 :     free( ( *hBinRenderer )->hBinRenConvModule );
    1302         271 :     ( *hBinRenderer )->hBinRenConvModule = NULL;
    1303             : 
    1304         271 :     return;
    1305             : }
    1306             : 
    1307             : /*-------------------------------------------------------------------------
    1308             :  * ivas_binRenderer_close()
    1309             :  *
    1310             :  * Close fastconv binaural renderer memories
    1311             :  *------------------------------------------------------------------------*/
    1312         836 : void ivas_binRenderer_close_fx(
    1313             :     BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle    */
    1314             : )
    1315             : {
    1316         836 :     test();
    1317         836 :     IF( hBinRenderer == NULL || *hBinRenderer == NULL )
    1318             :     {
    1319         565 :         return;
    1320             :     }
    1321             : 
    1322         271 :     IF( ( *hBinRenderer )->hBinRenConvModule != NULL )
    1323             :     {
    1324         271 :         ivas_binRenderer_convModuleClose_fx( hBinRenderer );
    1325             :     }
    1326             : 
    1327         271 :     IF( ( *hBinRenderer )->hReverb != NULL )
    1328             :     {
    1329           0 :         ivas_binaural_reverb_close_fx( &( ( *hBinRenderer )->hReverb ) );
    1330             :     }
    1331             : 
    1332         271 :     free( *hBinRenderer );
    1333         271 :     *hBinRenderer = NULL;
    1334             : 
    1335         271 :     return;
    1336             : }
    1337             : 
    1338             : /*-------------------------------------------------------------------------
    1339             :  * ivas_free_pppHrtfMem()
    1340             :  *
    1341             :  * Free fastconv binaural renderer hrtf memories
    1342             :  *------------------------------------------------------------------------*/
    1343        1220 : static void ivas_free_pppHrtfMem_fx(
    1344             :     Word32 ****ppppHRIR, /*Qx*/
    1345             :     const Word16 dim,
    1346             :     const Word16 alloc_init )
    1347             : {
    1348             :     Word16 i, j;
    1349             : 
    1350        1220 :     IF( *ppppHRIR != NULL )
    1351             :     {
    1352       37128 :         FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
    1353             :         {
    1354       36400 :             IF( alloc_init == 0 )
    1355             :             {
    1356      294400 :                 FOR( j = 0; j < dim; j++ )
    1357             :                 {
    1358      271400 :                     free( ( *ppppHRIR )[i][j] );
    1359      271400 :                     ( *ppppHRIR )[i][j] = NULL;
    1360             :                 }
    1361             :             }
    1362       36400 :             free( ( *ppppHRIR )[i] );
    1363       36400 :             ( *ppppHRIR )[i] = NULL;
    1364             :         }
    1365         728 :         free( *ppppHRIR );
    1366         728 :         *ppppHRIR = NULL;
    1367             :     }
    1368             : 
    1369        1220 :     return;
    1370             : }
    1371             : 
    1372             : /*-------------------------------------------------------------------------
    1373             :  * ivas_binaural_hrtf_close()
    1374             :  *
    1375             :  * Close fastconv binaural renderer hrtf memories
    1376             :  *------------------------------------------------------------------------*/
    1377         604 : void ivas_binaural_hrtf_close(
    1378             :     HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i  : fastconv HRTF handle */
    1379             : )
    1380             : {
    1381             :     Word16 allocate_init_flag;
    1382             : 
    1383         604 :     test();
    1384         604 :     IF( hHrtfFastConv == NULL || *hHrtfFastConv == NULL )
    1385             :     {
    1386         543 :         return;
    1387             :     }
    1388             : 
    1389          61 :     allocate_init_flag = ( *hHrtfFastConv )->allocate_init_flag;
    1390          61 :     move16();
    1391             : 
    1392          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1393          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1394          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1395          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1396             : 
    1397          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1398          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1399          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1400          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
    1401             : 
    1402          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
    1403          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
    1404          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
    1405          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
    1406             : 
    1407          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
    1408          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
    1409          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
    1410          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
    1411             : 
    1412          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
    1413          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
    1414          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
    1415          61 :     ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
    1416             : 
    1417          61 :     return;
    1418             : }
    1419             : 
    1420             : /*-------------------------------------------------------------------------*
    1421             :  * ivas_binaural_add_LFE()
    1422             :  *
    1423             :  * The functions adds the LFE to the left and right channels after binaural rendering
    1424             :  *-------------------------------------------------------------------------*/
    1425       15180 : void ivas_binaural_add_LFE_fx(
    1426             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure                                 */
    1427             :     Word16 output_frame,     /* i  : length of input frame                                  */
    1428             :     Word32 *input_fx[],      /* i  : transport channels                                     Q11*/
    1429             :     Word32 *output_fx[]      /* o  : synthesized core-coder transport channels/DirAC output Q11*/
    1430             : )
    1431             : {
    1432             :     Word16 render_lfe, idx_lfe, gain_fx, idx;
    1433             : 
    1434       15180 :     IF( st_ivas->hBinRenderer != NULL )
    1435             :     {
    1436         160 :         render_lfe = st_ivas->hBinRenderer->render_lfe;
    1437         160 :         move16();
    1438             :     }
    1439             :     ELSE
    1440             :     {
    1441       15020 :         render_lfe = TRUE;
    1442       15020 :         move16();
    1443             :     }
    1444             : 
    1445             : 
    1446       15180 :     IF( render_lfe )
    1447             :     {
    1448       15180 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
    1449             :         {
    1450        3060 :             gain_fx = GAIN_LFE_FX;
    1451        3060 :             move16();
    1452             :         }
    1453             :         ELSE
    1454             :         {
    1455       12120 :             test();
    1456       12120 :             IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) )
    1457             :             {
    1458       11960 :                 gain_fx = st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe_fx;
    1459       11960 :                 move16();
    1460             :             }
    1461             :             ELSE
    1462             :             {
    1463         160 :                 gain_fx = GAIN_LFE_FX;
    1464         160 :                 move16();
    1465             :             }
    1466             :         }
    1467       30210 :         FOR( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
    1468             :         {
    1469       15030 :             v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx  - 1
    1470             :             /* copy LFE to left and right channels */
    1471    13327030 :             FOR( idx = 0; idx < output_frame; idx++ )
    1472             :             {
    1473    13312000 :                 input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q
    1474    13312000 :                 move32();
    1475    13312000 :                 output_fx[0][idx] = L_add_sat( output_fx[0][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] );
    1476    13312000 :                 move32();
    1477    13312000 :                 output_fx[1][idx] = L_add_sat( output_fx[1][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] );
    1478    13312000 :                 move32();
    1479             :             }
    1480             :         }
    1481             :     }
    1482             : 
    1483       15180 :     return;
    1484             : }
    1485             : 
    1486             : /*-------------------------------------------------------------------------
    1487             :  * ivas_binRenderer()
    1488             :  *
    1489             :  * Fastconv binaural renderer main function
    1490             :  *-------------------------------------------------------------------------*/
    1491             : 
    1492      136305 : void ivas_binRenderer_fx(
    1493             :     BINAURAL_RENDERER_HANDLE hBinRenderer,                                                     /* i/o: binaural renderer handle                     */
    1494             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,                                      /* i  : combined head and external orientation handle*/
    1495             :     const Word16 numTimeSlots,                                                                 /* i  : number of time slots to render               */
    1496             :     Word32 Cldfb_RealBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : Binaural signals Q_in*/
    1497             :     Word32 Cldfb_ImagBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o  : Binaural signals Q_in*/
    1498             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                /* i  : LS signals       Q_in*/
    1499             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],                /* i  : LS signals       Q_in*/
    1500             :     Word16 *Q_in                                                                               /* i  : LS signals exp   */
    1501             : )
    1502             : {
    1503             :     Word16 chIdx, i, j, k;
    1504      136305 :     push_wmops( "fastconv_binaural_rendering" );
    1505             : 
    1506             :     /* Compute Convolution */
    1507             :     /* memory reset for the binaural output */
    1508             : #ifndef OPT_SBA_DEC_V2_BE
    1509             :     FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1510             :     {
    1511             :         FOR( k = 0; k < numTimeSlots; k++ )
    1512             :         {
    1513             :             set32_fx( Cldfb_RealBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
    1514             :             set32_fx( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
    1515             :         }
    1516             :     }
    1517             : #endif /* OPT_SBA_DEC_V2_BE */
    1518             : 
    1519             :     /* Head rotation in HOA3 or CICPx */
    1520      136305 :     test();
    1521      136305 :     test();
    1522      136305 :     IF( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb )
    1523             :     {
    1524       62520 :         IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
    1525             :         {
    1526             :             /* Rotation in SHD (HOA3) */
    1527       54520 :             IF( EQ_16( hCombinedOrientationData->shd_rot_max_order, -1 ) )
    1528             :             {
    1529       18520 :                 rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
    1530       18520 :                 *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
    1531       18520 :                 move16();
    1532             :             }
    1533       36000 :             ELSE IF( hCombinedOrientationData->shd_rot_max_order > 0 )
    1534             :             {
    1535           0 :                 rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order );
    1536           0 :                 *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
    1537           0 :                 move16();
    1538             :             }
    1539             :         }
    1540             :         ELSE
    1541             :         {
    1542             :             /* Rotation in SD (CICPx) */
    1543        8000 :             rotateFrame_sd_cldfb_fixed( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], RealBuffer_fx, ImagBuffer_fx,
    1544        8000 :                                         hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
    1545             :         }
    1546             :     }
    1547             : 
    1548             :     /* HOA decoding to CICP19 if needed*/
    1549      136305 :     test();
    1550      136305 :     IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && NE_16( hBinRenderer->nInChannels, 16 ) )
    1551             :     {
    1552       28000 :         ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx,
    1553       28000 :                                  hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx );
    1554             :     }
    1555      136305 :     ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, *Q_in );
    1556             :     /* Obtain the binaural dmx and compute the reverb */
    1557      136305 :     IF( hBinRenderer->hReverb != NULL )
    1558             :     {
    1559             :         Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1560             :         Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1561             :         Word32 inRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1562             :         Word32 inIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
    1563             : 
    1564           0 :         ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx );
    1565             : 
    1566           0 :         FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1567             :         {
    1568           0 :             FOR( k = 0; k < numTimeSlots; k++ )
    1569             :             {
    1570           0 :                 set32_fx( reverbRe_fx[chIdx][k], 0, hBinRenderer->max_band );
    1571           0 :                 set32_fx( reverbIm_fx[chIdx][k], 0, hBinRenderer->max_band );
    1572             :             }
    1573             :         }
    1574             : 
    1575           0 :         ivas_binaural_reverb_processSubframe_fx( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx );
    1576             : 
    1577           0 :         FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
    1578             :         {
    1579           0 :             FOR( j = 0; j < numTimeSlots; j++ )
    1580             :             {
    1581           0 :                 FOR( k = 0; k < hBinRenderer->hReverb->numBins; k++ )
    1582             :                 {
    1583           0 :                     reverbRe_fx[i][j][k] = L_shl( reverbRe_fx[i][j][k], 1 ); //*Q_in
    1584           0 :                     move32();
    1585           0 :                     reverbIm_fx[i][j][k] = L_shl( reverbIm_fx[i][j][k], 1 ); //*Q_in
    1586           0 :                     move32();
    1587             :                 }
    1588             :             }
    1589             :         }
    1590             : 
    1591             :         /* Add the conv module and reverb module output */
    1592           0 :         FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
    1593             :         {
    1594           0 :             FOR( k = 0; k < numTimeSlots; k++ )
    1595             :             {
    1596             :                 /* Combine first and second parts to generate binaural output signal with room effect */
    1597           0 :                 v_add_32( Cldfb_RealBuffer_Binaural_fx[chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in
    1598           0 :                 v_add_32( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in
    1599             :             }
    1600             :         }
    1601             :     }
    1602             : 
    1603             : #ifdef OPT_SBA_DEC_V2_BE
    1604      136305 :     Word16 len = sub( CLDFB_NO_CHANNELS_MAX, hBinRenderer->conv_band );
    1605             : 
    1606      680005 :     FOR( k = 0; k < numTimeSlots; k++ )
    1607             :     {
    1608      543700 :         set32_fx( &Cldfb_RealBuffer_Binaural_fx[0][k][hBinRenderer->conv_band], 0, len );
    1609      543700 :         set32_fx( &Cldfb_RealBuffer_Binaural_fx[1][k][hBinRenderer->conv_band], 0, len );
    1610      543700 :         set32_fx( &Cldfb_ImagBuffer_Binaural_fx[0][k][hBinRenderer->conv_band], 0, len );
    1611      543700 :         set32_fx( &Cldfb_ImagBuffer_Binaural_fx[1][k][hBinRenderer->conv_band], 0, len );
    1612             :     }
    1613             : #endif /* OPT_SBA_DEC_V2_BE */
    1614             : 
    1615      136305 :     pop_wmops();
    1616      136305 :     return;
    1617             : }

Generated by: LCOV version 1.14