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 enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 189 199 95.0 %
Date: 2025-05-03 01:55:50 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       28000 : void ivas_sba2mc_cldfb_fixed(
      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       28000 :     push_wmops( "ivas_sba2mc_cldfb_fixed" );
      69       28000 :     nb_channels_in = hInSetup.nchan_out_woLFE; /*Q0*/
      70       28000 :     move16();
      71       28000 :     assert( EQ_16( nb_channels_in, 16 ) && EQ_16( nb_channels_out, 11 ) && "ivas_sba2mc_cldfb_fixed; only HOA3 to CICP19 is for now supported!" );
      72             : 
      73      336000 :     FOR( n = 0; n < nb_channels_out; n++ )
      74             :     {
      75      308000 :         set32_fx( realOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_real*/
      76      308000 :         set32_fx( imagOut_fx[n], 0, i_mult( MAX_PARAM_SPATIAL_SUBFRAMES, nb_bands ) ); /*Q_imag*/
      77             : 
      78     5236000 :         FOR( m = 0; m < nb_channels_in; m++ )
      79             :         {
      80     4928000 :             g_fx = hoa_dec_mtx[( ( SBA_NHARM_HOA3 * n ) + m )]; // Q29
      81     4928000 :             p_realOut_fx = realOut_fx[n];
      82     4928000 :             p_imagOut_fx = imagOut_fx[n];
      83             : 
      84    24640000 :             FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
      85             :             {
      86    19712000 :                 p_real_fx = RealBuffer[m][iBlock]; /*Q_real*/
      87    19712000 :                 p_imag_fx = ImagBuffer[m][iBlock]; /*Q_imag*/
      88   836352000 :                 FOR( iBand = 0; iBand < nb_bands; iBand++ )
      89             :                 {
      90   816640000 :                     *p_realOut_fx = L_add( *p_realOut_fx, Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_real_fx++ ) ) ); // Q_real
      91   816640000 :                     move32();
      92   816640000 :                     *p_imagOut_fx = L_add( *p_imagOut_fx, Mpy_32_32( L_shl_sat( g_fx, Q2 ), *( p_imag_fx++ ) ) ); // Q_imag
      93   816640000 :                     move32();
      94   816640000 :                     p_realOut_fx++;
      95   816640000 :                     p_imagOut_fx++;
      96             :                 }
      97             :             }
      98             :         }
      99             :     }
     100             : 
     101      336000 :     FOR( n = 0; n < nb_channels_out; n++ )
     102             :     {
     103      308000 :         p_realOut_fx = realOut_fx[n]; /*Q_real*/
     104      308000 :         p_imagOut_fx = imagOut_fx[n]; /*Q_imag*/
     105             : 
     106     1540000 :         FOR( iBlock = 0; iBlock < nb_timeslots; iBlock++ )
     107             :         {
     108     1232000 :             p_real_fx = RealBuffer[n][iBlock]; /*Q_real*/
     109     1232000 :             p_imag_fx = ImagBuffer[n][iBlock]; /*Q_imag*/
     110    52272000 :             FOR( iBand = 0; iBand < nb_bands; iBand++ )
     111             :             {
     112    51040000 :                 *( p_real_fx++ ) = *p_realOut_fx++;
     113    51040000 :                 move32();
     114    51040000 :                 *( p_imag_fx++ ) = *p_imagOut_fx++;
     115    51040000 :                 move32();
     116             :             }
     117             :         }
     118             :     }
     119             : 
     120       28000 :     pop_wmops();
     121       28000 :     return;
     122             : }
     123             : 
     124             : /*-------------------------------------------------------------------------*
     125             :  * ivas_mc2sba()
     126             :  *
     127             :  * MC signals transformed into SBA in TD domain
     128             :  *-------------------------------------------------------------------------*/
     129             : 
     130        5816 : void ivas_mc2sba_fx(
     131             :     IVAS_OUTPUT_SETUP hIntSetup, /* i  : Format of decoder output                         */
     132             :     Word32 *in_buffer_td_fx[],
     133             :     /* 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        5816 :     assert( ( LE_16( sba_order, 3 ) ) && "Only order up to 3 is supported!" );
     148             :     /* Init*/
     149        5816 :     sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) );
     150       47128 :     FOR( j = 0; j < sba_num_chans; j++ )
     151             :     {
     152       41312 :         set32_fx( buffer_tmp_fx[j], 0, output_frame );
     153             :     }
     154             : 
     155             :     /* HOA encoding*/
     156        5816 :     idx_lfe = 0;
     157        5816 :     idx_in = 0;
     158        5816 :     move16();
     159        5816 :     move16();
     160       69608 :     FOR( i = 0; i < ( hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe ); i++ )
     161             :     {
     162       63792 :         test();
     163       63792 :         IF( ( hIntSetup.num_lfe > 0 ) && EQ_16( i, hIntSetup.index_lfe[idx_lfe] ) )
     164             :         {
     165        5816 :             IF( gain_lfe_fx > 0 )
     166             :             {
     167             :                 /* Add LFE to omni W with gain*/
     168      144150 :                 FOR( k = 0; k < output_frame; k++ )
     169             :                 {
     170      144000 :                     buffer_tmp_fx[0][k] = L_add( buffer_tmp_fx[0][k], L_shl( Mult_32_16( in_buffer_td_fx[i][k], gain_lfe_fx ), 1 ) ); /*Q+14-15+1==Q*/
     171      144000 :                     move32();
     172             :                 }
     173             :             }
     174             : 
     175        5816 :             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       57976 :             azimuth = extract_l( L_shr( hIntSetup.ls_azimuth_fx[idx_in], Q22 ) ); /*Q0*/
     183       57976 :             move16();
     184       57976 :             elevation = extract_l( L_shr( hIntSetup.ls_elevation_fx[idx_in], Q22 ) ); /*Q0*/
     185       57976 :             move16();
     186       57976 :             idx_in = add( idx_in, 1 ); /*Q0*/
     187       57976 :             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      416408 :             FOR( j = 0; j < sba_num_chans; j++ )
     196             :             {
     197   289287712 :                 FOR( k = 0; k < output_frame; k++ )
     198             :                 {
     199   288929280 :                     buffer_tmp_fx[j][k] = L_add( buffer_tmp_fx[j][k], L_shl( Mult_32_32( in_buffer_td_fx[i][k], gains_fx[j] ), 2 ) ); /*Q+29-31+2==Q*/
     200   288929280 :                     move32();
     201             :                 }
     202             :             }
     203             :         }
     204             :     }
     205             : 
     206       47128 :     FOR( j = 0; j < sba_num_chans; j++ )
     207             :     {
     208       41312 :         Copy32( buffer_tmp_fx[j], buffer_td_fx[j], output_frame ); /*Q*/
     209             :     }
     210             : 
     211        5816 :     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       58080 : void ivas_param_mc_mc2sba_cldfb_fx(
     222             :     IVAS_OUTPUT_SETUP hTransSetup,                                                    /* i  : transported MC Format                                       */
     223             :     Word32 *hoa_encoder_fx,                                                           /* i  : HOA3 encoder for the transported MC format                  Q31*/
     224             :     const Word16 slot_idx,                                                            /* i  : current slot in the subframe                                Q0*/
     225             :     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*/
     226             :     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*/
     227             :     const Word16 nBands,                                                              /* i  : number of synth CLDFB bands                                 Q0*/
     228             :     const Word16 gain_lfe_fx                                                          /* i  : gain applied to LFE                                        Q14*/
     229             : )
     230             : {
     231             :     Word16 idx_ch, idx_band;
     232             :     Word16 idx_lfe, idx_in, idx_out;
     233             :     Word32 Cldfb_RealBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     234             :     Word32 Cldfb_ImagBuffer_tmp_fx[MAX_INTERN_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     235             :     Word32 *gains_fx;
     236             :     Word16 sba_num_chans;
     237             : 
     238             :     /* Init*/
     239       58080 :     sba_num_chans = MAX_INTERN_CHANNELS;
     240       58080 :     move16();
     241      987360 :     FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
     242             :     {
     243      929280 :         set32_fx( Cldfb_RealBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
     244      929280 :         set32_fx( Cldfb_ImagBuffer_tmp_fx[idx_ch], 0, CLDFB_NO_CHANNELS_MAX );
     245             :     }
     246             : 
     247       58080 :     idx_lfe = 0;
     248       58080 :     idx_in = 0;
     249       58080 :     move16();
     250       58080 :     move16();
     251             : 
     252      455520 :     FOR( idx_ch = 0; idx_ch < ( hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe ); idx_ch++ )
     253             :     {
     254      397440 :         test();
     255      397440 :         IF( ( hTransSetup.num_lfe > 0 ) && EQ_16( idx_ch, hTransSetup.index_lfe[idx_lfe] ) )
     256             :         {
     257       58080 :             IF( gain_lfe_fx > 0 )
     258             :             {
     259             :                 /* Add LFE to Omni Channel i.e. W (Just first Band) */
     260       58080 :                 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*/
     261       58080 :                 move32();
     262       58080 :                 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*/
     263       58080 :                 move32();
     264             :             }
     265             : 
     266       58080 :             if ( LT_16( idx_lfe, sub( hTransSetup.num_lfe, 1 ) ) )
     267             :             {
     268           0 :                 idx_lfe = add( idx_lfe, 1 ); /*Q0*/
     269             :             }
     270             :         }
     271             :         ELSE
     272             :         {
     273      339360 :             gains_fx = hoa_encoder_fx + imult1616( idx_in, sba_num_chans ); /*Pointer addition*/ /*Q31*/
     274     5769120 :             FOR( idx_out = 0; idx_out < sba_num_chans; idx_out++ )
     275             :             {
     276   288719360 :                 FOR( idx_band = 0; idx_band < nBands; idx_band++ )
     277             :                 {
     278   283289600 :                     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*/
     279   283289600 :                     move32();
     280   283289600 :                     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*/
     281   283289600 :                     move32();
     282             :                 }
     283     5429760 :                 gains_fx++;
     284             :             }
     285      339360 :             idx_in = add( idx_in, 1 ); /*Q0*/
     286             :         }
     287             :     }
     288      987360 :     FOR( idx_ch = 0; idx_ch < sba_num_chans; idx_ch++ )
     289             :     {
     290      929280 :         Copy32( Cldfb_RealBuffer_tmp_fx[idx_ch], Cldfb_RealBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_RealBuffer*/
     291      929280 :         Copy32( Cldfb_ImagBuffer_tmp_fx[idx_ch], Cldfb_ImagBuffer_fx[idx_ch][slot_idx], nBands ); /*Q_Cldfb_ImagBuffer*/
     292             :     }
     293             : 
     294       58080 :     return;
     295             : }
     296             : 
     297             : 
     298             : /*-------------------------------------------------------------------*
     299             :  * ivas_sba_remapTCs()
     300             :  *
     301             :  * Get TCs from Ambisonics signal in ACN
     302             :  *-------------------------------------------------------------------*/
     303             : 
     304             : /*! r: SBA DirAC stereo flag */
     305      149027 : Word16 ivas_sba_remapTCs_fx(
     306             :     Word32 *sba_data_fx[],    /* i/o: SBA signals                  Q11*/
     307             :     Decoder_Struct *st_ivas,  /* i/o: decoder struct               */
     308             :     const Word16 output_frame /* i  : frame length                 Q0*/
     309             : )
     310             : {
     311             :     Word16 nchan_remapped;
     312      149027 :     nchan_remapped = st_ivas->nchan_transport; /*Q0*/
     313      149027 :     move16();
     314      149027 :     IF( EQ_16( nchan_remapped, 3 ) )
     315             :     {
     316       30220 :         nchan_remapped = add( nchan_remapped, 1 ); /*Q0*/
     317       30220 :         IF( EQ_16( nchan_remapped, 4 ) )
     318             :         {
     319       30220 :             Copy32( sba_data_fx[2], sba_data_fx[3], output_frame ); /*Q11*/
     320             :         }
     321             :     }
     322      149027 :     IF( GE_16( st_ivas->nchan_transport, 3 ) )
     323             :     {
     324       67969 :         Word16 i = 0;
     325       67969 :         move16();
     326             :         Word32 temp_fx;
     327             : 
     328             :         /*convert WYXZ downmix to WYZX*/
     329    55311489 :         FOR( i = 0; i < output_frame; i++ )
     330             :         {
     331    55243520 :             temp_fx = sba_data_fx[2][i]; /*Q11*/
     332    55243520 :             move32();
     333    55243520 :             sba_data_fx[2][i] = sba_data_fx[3][i]; /*Q11*/
     334    55243520 :             move32();
     335    55243520 :             sba_data_fx[3][i] = temp_fx; /*Q11*/
     336    55243520 :             move32();
     337             : 
     338    55243520 :             if ( EQ_16( st_ivas->nchan_transport, 3 ) )
     339             :             {
     340    23753280 :                 sba_data_fx[2][i] = 0;
     341    23753280 :                 move32();
     342             :             }
     343             :         }
     344             :     }
     345      149027 :     return ( nchan_remapped );
     346             : }
     347             : 
     348             : /*-------------------------------------------------------------------------*
     349             :  * ivas_ism2sba_sf()
     350             :  *
     351             :  * ISM transformed into SBA in TD domain.
     352             :  *-------------------------------------------------------------------------*/
     353        4896 : void ivas_ism2sba_sf_fx(
     354             :     Word32 *buffer_in_fx[],
     355             :     /* i  : TC buffer                       */ /*Q_buffer_in*/
     356             :     Word32 *buffer_out_fx[],                   /* o  : TD signal buffers               Q_buffer_in + 29 - 31*/
     357             :     ISM_RENDERER_HANDLE hIsmRendererData,      /* i/o: renderer data                   */
     358             :     const Word16 num_objects,                  /* i  : number of objects               Q0*/
     359             :     const Word16 n_samples_to_render,          /* i  : output frame length per channel Q0*/
     360             :     const Word16 offset,                       /* i  : offset for the interpolatr      Q0*/
     361             :     const Word16 sba_order                     /* i  : Ambisonic (SBA) order           Q0*/
     362             : )
     363             : {
     364             :     Word16 i, j, k;
     365             :     Word32 buffer_tmp_fx[HOA3_CHANNELS][L_FRAME48k];
     366             :     Word16 *g2_fx, g1_fx;
     367             :     Word32 *tc_fx, *out_fx, gain_fx, prev_gain_fx;
     368             :     Word16 sba_num_chans;
     369             : 
     370        4896 :     assert( LE_16( sba_order, 3 ) && "Only order up to 3 is supported!" );
     371        4896 :     assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" );
     372             :     /* Init*/
     373        4896 :     sba_num_chans = imult1616( add( sba_order, 1 ), add( sba_order, 1 ) ); /*Q0*/
     374       65032 :     FOR( j = 0; j < sba_num_chans; j++ )
     375             :     {
     376       60136 :         set32_fx( buffer_tmp_fx[j], 0, n_samples_to_render );
     377             :     }
     378       20780 :     FOR( i = 0; i < num_objects; i++ )
     379             :     {
     380      212628 :         FOR( j = 0; j < sba_num_chans; j++ )
     381             :         {
     382      196744 :             g2_fx = hIsmRendererData->interpolator_fx + offset; /*Pointer addition*/ /*Q15*/
     383      196744 :             tc_fx = buffer_in_fx[i] + offset; /*Pointer addition*/                   /*Q_buffer_in*/
     384      196744 :             out_fx = buffer_tmp_fx[j];                                               /*Q_buffer_in + 29 - 31*/
     385      196744 :             gain_fx = hIsmRendererData->gains_fx[i][j];                              /*Q29*/
     386      196744 :             move32();
     387      196744 :             prev_gain_fx = hIsmRendererData->prev_gains_fx[i][j]; /*Q29*/
     388      196744 :             move32();
     389   166030984 :             FOR( k = 0; k < n_samples_to_render; k++ )
     390             :             {
     391   165834240 :                 g1_fx = sub( 32767, *g2_fx );                                                                                                      /*Q15*/
     392   165834240 :                 *( 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*/
     393   165834240 :                 move32();
     394   165834240 :                 g2_fx++;
     395   165834240 :                 tc_fx++;
     396   165834240 :                 out_fx++;
     397             :             }
     398             :         }
     399             :     }
     400       65032 :     FOR( j = 0; j < sba_num_chans; j++ )
     401             :     {
     402       60136 :         Copy32( buffer_tmp_fx[j], buffer_out_fx[j], n_samples_to_render ); /*Q_buffer_in + 29 - 31*/
     403             :     }
     404        4896 :     return;
     405             : }
     406             : 
     407             : /*-------------------------------------------------------------------*
     408             :  * ivas_sba_linear_renderer()
     409             :  *
     410             :  * Linear rendering for SBA format
     411             :  *-------------------------------------------------------------------*/
     412             : /*TODO: To be tested*/
     413             : /************************
     414             : Float to fixed conversion required for:output_f
     415             : *************************/
     416       60953 : ivas_error ivas_sba_linear_renderer_fx(
     417             :     Word32 *output_f[],                  /* i/o: synthesized core-coder transport channels/DirAC output  Q11*/
     418             :     const Word16 output_frame,           /* i  : output frame length per channel                         Q0*/
     419             :     const Word16 nchan_in,               /* i  : number of input ambisonics channels                     Q0*/
     420             :     const Word16 nchan_ism,              /* i  : number of objects                                      Q0*/
     421             :     const AUDIO_CONFIG output_config,    /* i  : output audio configuration                              */
     422             :     const IVAS_OUTPUT_SETUP output_setup /* i  : output format setup                                     */
     423             : )
     424             : {
     425             :     Word16 i;
     426             :     Word16 nchan_hoa;
     427             :     ivas_error error;
     428             : 
     429       60953 :     error = IVAS_ERR_OK;
     430       60953 :     move32();
     431             : 
     432             :     /* Number of channels of HOA depends of transport format which is mixed order xH1V*/
     433       60953 :     nchan_hoa = nchan_in; /*Q0*/
     434       60953 :     move16();
     435             : 
     436       60953 :     IF( EQ_16( nchan_in, 6 ) ) /*2H1V*/
     437             :     {
     438           0 :         nchan_hoa = 9;
     439           0 :         move16();
     440             :     }
     441       60953 :     ELSE IF( EQ_16( nchan_in, 8 ) ) /*3H1V*/
     442             :     {
     443           0 :         nchan_hoa = 16;
     444           0 :         move16();
     445             :     }
     446             : 
     447       60953 :     SWITCH( output_config )
     448             :     {
     449       54203 :         case IVAS_AUDIO_CONFIG_FOA:  /* Ambisonics output, order: 1 */
     450             :         case IVAS_AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */
     451             :         case IVAS_AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */
     452       54203 :             FOR( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ )
     453             :             {
     454           0 :                 set_zero_fx( output_f[i], output_frame );
     455             :             }
     456       54203 :             BREAK;
     457        6750 :         case IVAS_AUDIO_CONFIG_EXTERNAL:
     458       58500 :             FOR( i = output_setup.nchan_out_woLFE - 1; i >= nchan_ism; i-- )
     459             :             {
     460       51750 :                 Copy32( output_f[i - nchan_ism], output_f[i], output_frame ); /*Q11*/
     461             :             }
     462        6750 :             FOR( ; i >= 0; i-- )
     463             :             {
     464           0 :                 set_zero_fx( output_f[i], output_frame );
     465             :             }
     466        6750 :             BREAK;
     467           0 :         default:
     468           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" );
     469             :     }
     470             : 
     471       60953 :     return error;
     472             : }
     473             : 
     474             : 
     475             : /*-------------------------------------------------------------------*
     476             :  * ivas_sba_mix_matrix_determiner()
     477             :  *
     478             :  * Determine SBA mixing matrices
     479             :  *-------------------------------------------------------------------*/
     480       37054 : void ivas_sba_mix_matrix_determiner_fx(
     481             :     SPAR_DEC_HANDLE hSpar,          /* i/o: SPAR decoder handle                 */
     482             :     Word32 *output_fx[],            /* i/o: transport/output audio channels     Q_output*/
     483             :     const Word16 bfi,               /* i  : BFI flag                            Q0*/
     484             :     const Word16 nchan_remapped,    /* i  : num channels after remapping of TCs Q0*/
     485             :     const Word16 output_frame,      /* i  : output frame length                 Q0*/
     486             :     const Word16 num_md_sub_frames, /* i  : number of subframes in mixing matrix Q0*/
     487             :     const Word16 Q_output           /* i  : Q of transport/output audio channels */
     488             : )
     489             : {
     490             :     Word16 i, ch;
     491             :     Word16 num_bands_out, nchan_transport, nchan_out;
     492       37054 :     Word16 Q_p_output = add( 11, Q_output );
     493             :     Word32 temp_fx;
     494             :     /* Convert numeric range */
     495       95357 :     FOR( ch = 0; ch < nchan_remapped; ch++ )
     496             :     {
     497    40525183 :         FOR( i = 0; i < output_frame; i++ )
     498             :         {
     499    40466880 :             temp_fx = output_fx[ch][i]; /*Q_output*/
     500    40466880 :             move32();
     501    40466880 :             temp_fx = L_shr( temp_fx + L_shl( 1, Q_p_output - 1 ), Q_p_output ); /*Q0*/
     502             : 
     503    40466880 :             IF( GT_32( temp_fx, MAX16B ) )
     504             :             {
     505           7 :                 temp_fx = MAX16B; /*Q0*/
     506           7 :                 move32();
     507             :             }
     508    40466873 :             ELSE IF( LT_32( temp_fx, L_negate( PCM16_TO_FLT_FAC_FX ) ) )
     509             :             {
     510           2 :                 temp_fx = -( PCM16_TO_FLT_FAC_FX ); /*Q0*/
     511           2 :                 move32();
     512             :             }
     513    40466880 :             temp_fx = Mult_32_32( MAX_32 / PCM16_TO_FLT_FAC_FX, L_shl( temp_fx, Q_p_output ) ); /*Q_p_output*/
     514    40466880 :             output_fx[ch][i] = temp_fx;                                                         /*Q_p_output*/
     515    40466880 :             move32();
     516             :         }
     517             :     }
     518             :     /* AGC */
     519       37054 :     nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
     520       37054 :     move16();
     521       37054 :     nchan_out = nchan_transport; /*Q0*/
     522       37054 :     move16();
     523       37054 :     ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output_fx ), ( output_fx ), nchan_transport, output_frame );
     524       37054 :     Q_p_output = sub( Q_p_output, 3 );
     525             : #ifdef DEBUGGING
     526             :     dbgwrite_txt( (const float *) ( output_fx[0] ), output_frame, "fix_ivas_agc_dec_process_output.txt", NULL );
     527             : #endif
     528             : 
     529             :     /* Convert numeric range back */
     530       95357 :     FOR( ch = 0; ch < nchan_out; ch++ )
     531             :     {
     532    40525183 :         FOR( i = 0; i < output_frame; i++ )
     533             :         {
     534    40466880 :             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 */
     535             :         }
     536             :     }
     537             : 
     538             :     /* Mixing matrix determiner */
     539       37054 :     num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
     540       37054 :     move16();
     541       37054 :     ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, bfi, num_md_sub_frames );
     542       37054 :     return;
     543             : }

Generated by: LCOV version 1.14