LCOV - code coverage report
Current view: top level - lib_dec - ivas_sba_rendering_internal_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 2ac0e6bcc2725ab07bd14076a8fbdebaaf98bf20 Lines: 187 199 94.0 %
Date: 2025-11-08 23:21:44 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "prot_fx.h"
      36             : #include "ivas_prot_rend_fx.h"
      37             : #include "ivas_stat_dec.h"
      38             : #include "ivas_cnst.h"
      39             : #include <math.h>
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : 
      46             : /*-------------------------------------------------------------------------*
      47             :  * ivas_sba2MC_cldfb()
      48             :  *
      49             :  * SBA signals transformed into MC in CLDFB domain
      50             :  *-------------------------------------------------------------------------*/
      51             : 
      52       27996 : void ivas_sba2mc_cldfb_fx(
      53             :     IVAS_OUTPUT_SETUP hInSetup,                                              /* i  : Format of input layout          */
      54             :     Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part (Q_real)        */
      55             :     Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part (Q_imag)        */
      56             :     const Word16 nb_channels_out,                                            /* i  : nb of output channels           Q0*/
      57             :     const Word16 nb_bands,                                                   /* i  : nb of CLDFB bands to process    Q0*/
      58             :     const Word16 nb_timeslots,                                               /* i  : number of time slots to process Q0*/
      59             :     const Word32 *hoa_dec_mtx                                                /* i  : HOA decoding mtx                Q29*/
      60             : )
      61             : {
      62             :     Word16 iBlock, iBand, n, m;
      63             :     Word32 realOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut_fx[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX];
      64             :     Word32 g_fx;
      65             :     Word32 *p_real_fx, *p_imag_fx, *p_realOut_fx, *p_imagOut_fx;
      66             :     Word16 nb_channels_in;
      67             : 
      68       27996 :     push_wmops( "ivas_sba2mc_cldfb_fx" );
      69       27996 :     nb_channels_in = hInSetup.nchan_out_woLFE; /*Q0*/
      70       27996 :     move16();
      71       27996 :     assert( EQ_16( nb_channels_in, 16 ) && EQ_16( nb_channels_out, 11 ) && "ivas_sba2mc_cldfb_fx; only HOA3 to CICP19 is for now supported!" );
      72             : 
      73      335952 :     FOR( n = 0; n < nb_channels_out; n++ )
      74             :     {
      75      307956 :         set32_fx( realOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_real*/
      76      307956 :         set32_fx( imagOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_imag*/
      77             : 
      78     5235252 :         FOR( m = 0; m < nb_channels_in; m++ )
      79             :         {
      80     4927296 :             g_fx = L_shl_sat( hoa_dec_mtx[( ( SBA_NHARM_HOA3 * n ) + m )], Q2 );
      81     4927296 :             p_realOut_fx = realOut_fx[n];
      82     4927296 :             p_imagOut_fx = imagOut_fx[n];
      83             : 
      84    24636480 :             FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
      85             :             {
      86    19709184 :                 p_real_fx = RealBuffer[m][iBlock]; /*Q_real*/
      87    19709184 :                 p_imag_fx = ImagBuffer[m][iBlock]; /*Q_imag*/
      88   836208384 :                 FOR( iBand = 0; iBand < nb_bands; iBand++ )
      89             :                 {
      90   816499200 :                     *p_realOut_fx = Madd_32_32( *p_realOut_fx, g_fx, *( p_real_fx++ ) ); // Q_real
      91   816499200 :                     move32();
      92   816499200 :                     *p_imagOut_fx = Madd_32_32( *p_imagOut_fx, g_fx, *( p_imag_fx++ ) ); // Q_imag
      93   816499200 :                     move32();
      94   816499200 :                     p_realOut_fx++;
      95   816499200 :                     p_imagOut_fx++;
      96             :                 }
      97             :             }
      98             :         }
      99             :     }
     100             : 
     101      335952 :     FOR( n = 0; n < nb_channels_out; n++ )
     102             :     {
     103      307956 :         p_realOut_fx = realOut_fx[n]; /*Q_real*/
     104      307956 :         p_imagOut_fx = imagOut_fx[n]; /*Q_imag*/
     105             : 
     106     1539780 :         FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
     107             :         {
     108     1231824 :             p_real_fx = RealBuffer[n][iBlock]; /*Q_real*/
     109     1231824 :             p_imag_fx = ImagBuffer[n][iBlock]; /*Q_imag*/
     110    52263024 :             FOR( iBand = 0; iBand < nb_bands; iBand++ )
     111             :             {
     112    51031200 :                 *( p_real_fx++ ) = *p_realOut_fx++;
     113    51031200 :                 move32();
     114    51031200 :                 *( p_imag_fx++ ) = *p_imagOut_fx++;
     115    51031200 :                 move32();
     116             :             }
     117             :         }
     118             :     }
     119             : 
     120       27996 :     pop_wmops();
     121       27996 :     return;
     122             : }
     123             : 
     124             : 
     125             : /*-------------------------------------------------------------------------*
     126             :  * ivas_mc2sba()
     127             :  *
     128             :  * MC signals transformed into SBA in TD domain
     129             :  *-------------------------------------------------------------------------*/
     130             : 
     131        8671 : void ivas_mc2sba_fx(
     132             :     IVAS_OUTPUT_SETUP hIntSetup, /* i  : Format of decoder output                         */
     133             :     Word32 *in_buffer_td_fx[],   /* i  : MC signals (on input) and the HOA3 (on output)   Q*/
     134             :     Word32 *buffer_td_fx[],      /* i/o: MC signals (on input) and the HOA3 (on output)   Q*/
     135             :     const Word16 output_frame,   /* i  : output frame length per channel                  Q0*/
     136             :     const Word16 sba_order,      /* i  : Ambisonic (SBA) order                            Q0*/
     137             :     const Word16 gain_lfe_fx     /* i  : gain for LFE, 0 = ignore LFE                     Q14*/
     138             : )
     139             : {
     140             :     Word16 i, j, k;
     141             :     Word16 idx_lfe, idx_in;
     142             :     Word32 buffer_tmp_fx[16][L_FRAME48k];
     143             :     Word32 gains_fx[16];
     144             :     Word16 azimuth, elevation;
     145             :     Word16 sba_num_chans;
     146             : 
     147        8671 :     assert( ( LE_16( sba_order, 3 ) ) && "Only order up to 3 is supported!" );
     148             :     /* Init*/
     149        8671 :     sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) );
     150       62159 :     FOR( j = 0; j < sba_num_chans; j++ )
     151             :     {
     152       53488 :         set32_fx( buffer_tmp_fx[j], 0, output_frame );
     153             :     }
     154             : 
     155             :     /* HOA encoding*/
     156        8671 :     idx_lfe = 0;
     157        8671 :     idx_in = 0;
     158        8671 :     move16();
     159        8671 :     move16();
     160      106723 :     FOR( i = 0; i < ( hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe ); i++ )
     161             :     {
     162       98052 :         test();
     163       98052 :         IF( ( hIntSetup.num_lfe > 0 ) && EQ_16( i, hIntSetup.index_lfe[idx_lfe] ) )
     164             :         {
     165        8671 :             IF( gain_lfe_fx > 0 )
     166             :             {
     167             :                 /* Add LFE to omni W with gain*/
     168      203973 :                 FOR( k = 0; k < output_frame; k++ )
     169             :                 {
     170      203760 :                     buffer_tmp_fx[0][k] = Madd_32_16( buffer_tmp_fx[0][k], L_shl( in_buffer_td_fx[i][k], 1 ), gain_lfe_fx ); /*Q+14-15+1==Q*/
     171      203760 :                     move32();
     172             :                 }
     173             :             }
     174             : 
     175        8671 :             if ( LT_16( idx_lfe, sub( hIntSetup.num_lfe, 1 ) ) )
     176             :             {
     177           0 :                 idx_lfe = add( idx_lfe, 1 ); /*Q0*/
     178             :             }
     179             :         }
     180             :         ELSE
     181             :         {
     182       89381 :             azimuth = extract_l( L_shr( hIntSetup.ls_azimuth_fx[idx_in], Q22 ) ); /*Q0*/
     183       89381 :             move16();
     184       89381 :             elevation = extract_l( L_shr( hIntSetup.ls_elevation_fx[idx_in], Q22 ) ); /*Q0*/
     185       89381 :             move16();
     186       89381 :             idx_in = add( idx_in, 1 ); /*Q0*/
     187       89381 :             ivas_dirac_dec_get_response_fx(
     188             :                 azimuth,
     189             :                 elevation,
     190             :                 gains_fx, /*Q-29*/
     191             :                 sba_order,
     192             :                 Q29 );
     193             :             /* get HOA response for direction (ACN/SN3D)*/
     194             : 
     195      581749 :             FOR( j = 0; j < sba_num_chans; j++ )
     196             :             {
     197   363552848 :                 FOR( k = 0; k < output_frame; k++ )
     198             :                 {
     199   363060480 :                     buffer_tmp_fx[j][k] = Madd_32_32( buffer_tmp_fx[j][k], L_shl_sat( in_buffer_td_fx[i][k], 2 ), gains_fx[j] ); /*Q+29-31+2==Q*/
     200   363060480 :                     move32();
     201             :                 }
     202             :             }
     203             :         }
     204             :     }
     205             : 
     206       62159 :     FOR( j = 0; j < sba_num_chans; j++ )
     207             :     {
     208       53488 :         Copy32( buffer_tmp_fx[j], buffer_td_fx[j], output_frame ); /*Q*/
     209             :     }
     210             : 
     211        8671 :     return;
     212             : }
     213             : 
     214             : 
     215             : /*-------------------------------------------------------------------------*
     216             :  * ivas_param_mc_mc2sba_cldfb()
     217             :  *
     218             :  * MC signals transformed into SBA in CLDFB domain
     219             :  * used for binaural rendering with head rotation
     220             :  *-------------------------------------------------------------------------*/
     221             : 
     222       58723 : void ivas_param_mc_mc2sba_cldfb_fx(
     223             :     IVAS_OUTPUT_SETUP hTransSetup,                                                    /* i  : transported MC Format                                       */
     224             :     Word32 *hoa_encoder_fx,                                                           /* i  : HOA3 encoder for the transported MC format                  Q31*/
     225             :     const Word16 slot_idx,                                                            /* i  : current slot in the subframe                                Q0*/
     226             :     Word32 Cldfb_RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) Q_Cldfb_RealBuffer*/
     227             :     Word32 Cldfb_ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: Contains the MC signals (on input) and the HOA3 (on output) Q_Cldfb_ImagBuffer*/
     228             :     const Word16 nBands,                                                              /* i  : number of synth CLDFB bands                                 Q0*/
     229             :     const Word16 gain_lfe_fx                                                          /* i  : gain applied to LFE                                        Q14*/
     230             : )
     231             : {
     232             :     Word16 idx_ch, idx_band;
     233             :     Word16 idx_lfe, idx_in, idx_out;
     234             :     Word32 Cldfb_RealBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     235             :     Word32 Cldfb_ImagBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     236             :     Word32 *gains_fx;
     237             :     Word16 sba_num_chans;
     238             : 
     239             :     /* Init*/
     240       58723 :     sba_num_chans = MAX_INTERN_CHANNELS;
     241       58723 :     move16();
     242      998291 :     FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
     243             :     {
     244      939568 :         set32_fx( Cldfb_RealBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
     245      939568 :         set32_fx( Cldfb_ImagBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
     246             :     }
     247             : 
     248       58723 :     idx_lfe = 0;
     249       58723 :     idx_in = 0;
     250       58723 :     move16();
     251       58723 :     move16();
     252             : 
     253      461307 :     FOR( idx_ch = 0; idx_ch < ( hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe ); idx_ch++ )
     254             :     {
     255      402584 :         test();
     256      402584 :         IF( ( hTransSetup.num_lfe > 0 ) && EQ_16( idx_ch, hTransSetup.index_lfe[idx_lfe] ) )
     257             :         {
     258       58723 :             IF( gain_lfe_fx > 0 )
     259             :             {
     260             :                 /* Add LFE to Omni Channel i.e. W (Just first Band) */
     261       58723 :                 Cldfb_RealBuffer_tmp_fx[0][0] = L_add_sat( Cldfb_RealBuffer_tmp_fx[0][0], Mult_32_16( L_shl( Cldfb_RealBuffer_fx[idx_ch][slot_idx][0], 1 ), gain_lfe_fx ) ); /*Q_Cldfb_RealBuffer*/
     262       58723 :                 move32();
     263       58723 :                 Cldfb_ImagBuffer_tmp_fx[0][0] = L_add_sat( Cldfb_ImagBuffer_tmp_fx[0][0], Mult_32_16( L_shl( Cldfb_ImagBuffer_fx[idx_ch][slot_idx][0], 1 ), gain_lfe_fx ) ); /*Q_Cldfb_ImagBuffer*/
     264       58723 :                 move32();
     265             :             }
     266             : 
     267       58723 :             if ( LT_16( idx_lfe, sub( hTransSetup.num_lfe, 1 ) ) )
     268             :             {
     269           0 :                 idx_lfe = add( idx_lfe, 1 ); /*Q0*/
     270             :             }
     271             :         }
     272             :         ELSE
     273             :         {
     274      343861 :             gains_fx = hoa_encoder_fx + imult1616( idx_in, sba_num_chans ); /*Pointer addition*/ /*Q31*/
     275     5845637 :             FOR( idx_out = 0; idx_out < sba_num_chans; idx_out++ )
     276             :             {
     277   291672016 :                 FOR( idx_band = 0; idx_band < nBands; idx_band++ )
     278             :                 {
     279   286170240 :                     Cldfb_RealBuffer_tmp_fx[idx_out][idx_band] = L_add( Cldfb_RealBuffer_tmp_fx[idx_out][idx_band], Mult_32_32( ( *gains_fx ), Cldfb_RealBuffer_fx[idx_ch][slot_idx][idx_band] ) ); /*Q_Cldfb_RealBuffer*/
     280   286170240 :                     move32();
     281   286170240 :                     Cldfb_ImagBuffer_tmp_fx[idx_out][idx_band] = L_add( Cldfb_ImagBuffer_tmp_fx[idx_out][idx_band], Mult_32_32( ( *gains_fx ), Cldfb_ImagBuffer_fx[idx_ch][slot_idx][idx_band] ) ); /*Q_Cldfb_ImagBuffer*/
     282   286170240 :                     move32();
     283             :                 }
     284     5501776 :                 gains_fx++;
     285             :             }
     286      343861 :             idx_in = add( idx_in, 1 ); /*Q0*/
     287             :         }
     288             :     }
     289      998291 :     FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
     290             :     {
     291      939568 :         Copy32( Cldfb_RealBuffer_tmp_fx[idx_ch], Cldfb_RealBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_RealBuffer*/
     292      939568 :         Copy32( Cldfb_ImagBuffer_tmp_fx[idx_ch], Cldfb_ImagBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_ImagBuffer*/
     293             :     }
     294             : 
     295       58723 :     return;
     296             : }
     297             : 
     298             : 
     299             : /*-------------------------------------------------------------------*
     300             :  * ivas_sba_remapTCs()
     301             :  *
     302             :  * Get TCs from Ambisonics signal in ACN
     303             :  *-------------------------------------------------------------------*/
     304             : 
     305             : /*! r: SBA DirAC stereo flag */
     306      158813 : Word16 ivas_sba_remapTCs_fx(
     307             :     Word32 *sba_data_fx[],    /* i/o: SBA signals                  Q11*/
     308             :     Decoder_Struct *st_ivas,  /* i/o: decoder struct               */
     309             :     const Word16 output_frame /* i  : frame length                 Q0*/
     310             : )
     311             : {
     312             :     Word16 nchan_remapped;
     313      158813 :     nchan_remapped = st_ivas->nchan_transport; /*Q0*/
     314      158813 :     move16();
     315      158813 :     IF( EQ_16( nchan_remapped, 3 ) )
     316             :     {
     317       33766 :         nchan_remapped = add( nchan_remapped, 1 ); /*Q0*/
     318       33766 :         IF( EQ_16( nchan_remapped, 4 ) )
     319             :         {
     320       33766 :             Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/
     321             :         }
     322             :     }
     323      158813 :     IF( GE_16( st_ivas->nchan_transport, 3 ) )
     324             :     {
     325       74935 :         Word16 i = 0;
     326       74935 :         move16();
     327             :         Word32 temp_fx;
     328             : 
     329             :         /*convert WYXZ downmix to WYZX*/
     330    61700535 :         FOR( i = 0; i < output_frame; i++ )
     331             :         {
     332    61625600 :             temp_fx = sba_data_fx[2][i]; /*Q11*/
     333    61625600 :             move32();
     334    61625600 :             sba_data_fx[2][i] = sba_data_fx[3][i]; /*Q11*/
     335    61625600 :             move32();
     336    61625600 :             sba_data_fx[3][i] = temp_fx; /*Q11*/
     337    61625600 :             move32();
     338             : 
     339    61625600 :             if ( EQ_16( st_ivas->nchan_transport, 3 ) )
     340             :             {
     341    26986560 :                 sba_data_fx[2][i] = 0;
     342    26986560 :                 move32();
     343             :             }
     344             :         }
     345             :     }
     346             : 
     347      158813 :     return ( nchan_remapped );
     348             : }
     349             : 
     350             : 
     351             : /*-------------------------------------------------------------------------*
     352             :  * ivas_ism2sba_sf()
     353             :  *
     354             :  * ISM transformed into SBA in TD domain.
     355             :  *-------------------------------------------------------------------------*/
     356             : 
     357        7843 : void ivas_ism2sba_sf_fx(
     358             :     Word32 *buffer_in_fx[],               /* i  : TC buffer                       Q_buffer_in*/
     359             :     Word32 *buffer_out_fx[],              /* o  : TD signal buffers               Q_buffer_in + 29 - 31*/
     360             :     ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data                   */
     361             :     const Word16 num_objects,             /* i  : number of objects               Q0*/
     362             :     const Word16 n_samples_to_render,     /* i  : output frame length per channel Q0*/
     363             :     const Word16 offset,                  /* i  : offset for the interpolatr      Q0*/
     364             :     const Word16 sba_order                /* i  : Ambisonic (SBA) order           Q0*/
     365             : )
     366             : {
     367             :     Word16 i, j, k;
     368             :     Word32 buffer_tmp_fx[HOA3_CHANNELS][L_FRAME48k];
     369             :     Word16 *g2_fx, g1_fx;
     370             :     Word32 *tc_fx, *out_fx, gain_fx, prev_gain_fx;
     371             :     Word16 sba_num_chans;
     372             : 
     373        7843 :     assert( LE_16( sba_order, 3 ) && "Only order up to 3 is supported!" );
     374        7843 :     assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" );
     375             :     /* Init*/
     376        7843 :     sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) ); /*Q0*/
     377       79755 :     FOR( j = 0; j < sba_num_chans; j++ )
     378             :     {
     379       71912 :         set32_fx( buffer_tmp_fx[j], 0, n_samples_to_render );
     380             :     }
     381       32568 :     FOR( i = 0; i < num_objects; i++ )
     382             :     {
     383      256797 :         FOR( j = 0; j < sba_num_chans; j++ )
     384             :         {
     385      232072 :             g2_fx = hIsmRendererData->interpolator_fx + offset; /*Pointer addition*/ /*Q15*/
     386      232072 :             tc_fx = buffer_in_fx[i];                                                 /*Q_buffer_in*/
     387      232072 :             out_fx = buffer_tmp_fx[j];                                               /*Q_buffer_in + 29 - 31*/
     388      232072 :             gain_fx = hIsmRendererData->gains_fx[i][j];                              /*Q29*/
     389      232072 :             move32();
     390      232072 :             prev_gain_fx = hIsmRendererData->prev_gains_fx[i][j]; /*Q29*/
     391      232072 :             move32();
     392   183374632 :             FOR( k = 0; k < n_samples_to_render; k++ )
     393             :             {
     394   183142560 :                 g1_fx = sub( 32767, *g2_fx );                                                                                                      /*Q15*/
     395   183142560 :                 *( out_fx ) = Madd_32_32( *( out_fx ), Madd_32_16( Mult_32_16( gain_fx, ( *( g2_fx ) ) ), prev_gain_fx, g1_fx ), ( *( tc_fx ) ) ); /*Q_buffer_in + 29 - 31*/
     396   183142560 :                 move32();
     397   183142560 :                 g2_fx++;
     398   183142560 :                 tc_fx++;
     399   183142560 :                 out_fx++;
     400             :             }
     401             :         }
     402             :     }
     403             : 
     404       79755 :     FOR( j = 0; j < sba_num_chans; j++ )
     405             :     {
     406       71912 :         Copy32( buffer_tmp_fx[j], buffer_out_fx[j], n_samples_to_render ); /*Q_buffer_in + 29 - 31*/
     407             :     }
     408             : 
     409        7843 :     return;
     410             : }
     411             : 
     412             : 
     413             : /*-------------------------------------------------------------------*
     414             :  * ivas_sba_linear_renderer()
     415             :  *
     416             :  * Linear rendering for SBA format
     417             :  *-------------------------------------------------------------------*/
     418             : 
     419       63200 : ivas_error ivas_sba_linear_renderer_fx(
     420             :     Word32 *output_fx[],                 /* i/o: synthesized core-coder transport channels/DirAC output  Q11*/
     421             :     const Word16 output_frame,           /* i  : output frame length per channel                         Q0*/
     422             :     const Word16 nchan_in,               /* i  : number of input ambisonics channels                     Q0*/
     423             :     const Word16 nchan_ism,              /* i  : number of objects                                      Q0*/
     424             :     const AUDIO_CONFIG output_config,    /* i  : output audio configuration                              */
     425             :     const IVAS_OUTPUT_SETUP output_setup /* i  : output format setup                                     */
     426             : )
     427             : {
     428             :     Word16 i;
     429             :     Word16 nchan_hoa;
     430             :     ivas_error error;
     431             : 
     432       63200 :     error = IVAS_ERR_OK;
     433       63200 :     move32();
     434             : 
     435             :     /* Number of channels of HOA depends of transport format which is mixed order xH1V*/
     436       63200 :     nchan_hoa = nchan_in; /*Q0*/
     437       63200 :     move16();
     438             : 
     439       63200 :     IF( EQ_16( nchan_in, 6 ) ) /*2H1V*/
     440             :     {
     441           0 :         nchan_hoa = 9;
     442           0 :         move16();
     443             :     }
     444       63200 :     ELSE IF( EQ_16( nchan_in, 8 ) ) /*3H1V*/
     445             :     {
     446           0 :         nchan_hoa = 16;
     447           0 :         move16();
     448             :     }
     449             : 
     450       63200 :     SWITCH( output_config )
     451             :     {
     452       56302 :         case IVAS_AUDIO_CONFIG_FOA:  /* Ambisonics output, order: 1 */
     453             :         case IVAS_AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */
     454             :         case IVAS_AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */
     455       56302 :             FOR( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ )
     456             :             {
     457           0 :                 set_zero_fx( output_fx[i], output_frame );
     458             :             }
     459       56302 :             BREAK;
     460        6898 :         case IVAS_AUDIO_CONFIG_EXTERNAL:
     461       80566 :             FOR( i = output_setup.nchan_out_woLFE - 1; i >= nchan_ism; i-- )
     462             :             {
     463       73668 :                 Copy32( output_fx[i - nchan_ism], output_fx[i], output_frame ); /*Q11*/
     464             :             }
     465        6898 :             FOR( ; i >= 0; i-- )
     466             :             {
     467           0 :                 set_zero_fx( output_fx[i], output_frame );
     468             :             }
     469        6898 :             BREAK;
     470           0 :         default:
     471           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" );
     472             :     }
     473             : 
     474       63200 :     return error;
     475             : }
     476             : 
     477             : 
     478             : /*-------------------------------------------------------------------*
     479             :  * ivas_sba_mix_matrix_determiner()
     480             :  *
     481             :  * Determine SBA mixing matrices
     482             :  *-------------------------------------------------------------------*/
     483             : 
     484       38555 : void ivas_sba_mix_matrix_determiner_fx(
     485             :     SPAR_DEC_HANDLE hSpar,          /* i/o: SPAR decoder handle                 */
     486             :     Word32 *output_fx[],            /* i/o: transport/output audio channels     Q_output*/
     487             :     const Word16 bfi,               /* i  : BFI flag                            Q0*/
     488             :     const Word16 nchan_remapped,    /* i  : num channels after remapping of TCs Q0*/
     489             :     const Word16 output_frame,      /* i  : output frame length                 Q0*/
     490             :     const Word16 num_md_sub_frames, /* i  : number of subframes in mixing matrix Q0*/
     491             :     const Word16 Q_output           /* i  : Q of transport/output audio channels */
     492             : )
     493             : {
     494             :     Word16 i, ch;
     495             :     Word16 num_bands_out, nchan_transport, nchan_out;
     496       38555 :     Word16 Q_p_output = add( 11, Q_output );
     497             :     Word32 temp_fx;
     498             : 
     499             :     /* Convert numeric range */
     500       98948 :     FOR( ch = 0; ch < nchan_remapped; ch++ )
     501             :     {
     502    41927273 :         FOR( i = 0; i < output_frame; i++ )
     503             :         {
     504    41866880 :             temp_fx = output_fx[ch][i]; /*Q_output*/
     505    41866880 :             move32();
     506    41866880 :             temp_fx = L_shr( temp_fx + L_shl( 1, Q_p_output - 1 ), Q_p_output ); /*Q0*/
     507             : 
     508    41866880 :             IF( GT_32( temp_fx, MAX16B ) )
     509             :             {
     510           1 :                 temp_fx = MAX16B; /*Q0*/
     511           1 :                 move32();
     512             :             }
     513    41866879 :             ELSE IF( LT_32( temp_fx, -( PCM16_TO_FLT_FAC_FX ) ) )
     514             :             {
     515           0 :                 temp_fx = -( PCM16_TO_FLT_FAC_FX ); /*Q0*/
     516           0 :                 move32();
     517             :             }
     518    41866880 :             temp_fx = Mult_32_32( MAX_32 / PCM16_TO_FLT_FAC_FX, L_shl( temp_fx, Q_p_output ) ); /*Q_p_output*/
     519    41866880 :             output_fx[ch][i] = temp_fx;                                                         /*Q_p_output*/
     520    41866880 :             move32();
     521             :         }
     522             :     }
     523             :     /* AGC */
     524       38555 :     nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
     525       38555 :     move16();
     526       38555 :     nchan_out = nchan_transport; /*Q0*/
     527       38555 :     move16();
     528             : 
     529       38555 :     ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output_fx ), ( output_fx ), nchan_transport, output_frame );
     530       38555 :     Q_p_output = sub( Q_p_output, 3 );
     531             : #ifdef DEBUGGING
     532             :     dbgwrite_txt( (const float *) ( output_fx[0] ), output_frame, "fix_ivas_agc_dec_process_output.txt", NULL );
     533             : #endif
     534             : 
     535             :     /* Convert numeric range back */
     536       98948 :     FOR( ch = 0; ch < nchan_out; ch++ )
     537             :     {
     538    41927273 :         FOR( i = 0; i < output_frame; i++ )
     539             :         {
     540    41866880 :             output_fx[ch][i] = Mult_32_32( L_shl_sat( output_fx[ch][i], sub( 15, Q_p_output ) ), 2147483647 /* PCM16_TO_FLT_FAC_FX << 16 */ ); /* Q0 */
     541             :         }
     542             :     }
     543             : 
     544             :     /* Mixing matrix determiner */
     545       38555 :     num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
     546       38555 :     move16();
     547             : 
     548       38555 :     ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, bfi, num_md_sub_frames );
     549             : 
     550       38555 :     return;
     551             : }

Generated by: LCOV version 1.14