LCOV - code coverage report
Current view: top level - lib_enc - ivas_osba_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 183 194 94.3 %
Date: 2025-09-14 03:13:15 Functions: 6 6 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 "options.h"
      34             : #include <stdlib.h>
      35             : #include <assert.h>
      36             : #include <math.h>
      37             : #include "ivas_cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "ivas_rom_enc.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : 
      45             : /*-------------------------------------------------------------------------
      46             :  * Local function prototypes
      47             :  *------------------------------------------------------------------------*/
      48             : static void ivas_osba_render_ism_to_sba_fx(
      49             :     Word32 *data_in_fx[],
      50             :     Word32 data_out_fx[][L_FRAME48k],
      51             :     const Word16 input_frame,
      52             :     const Word16 sba_analysis_order,
      53             :     const Word16 nchan_ism,
      54             :     ISM_METADATA_HANDLE hIsmMeta[],
      55             :     Word32 prev_gains_fx[][MAX_INPUT_CHANNELS],
      56             :     const Word32 interpolator_fx[L_FRAME48k],
      57             :     Word16 *Q_data );
      58             : /*-------------------------------------------------------------------*
      59             :  * ivas_merge_sba_transports()
      60             :  *
      61             :  * Merge SBA transport channels
      62             :  *-------------------------------------------------------------------*/
      63       14920 : static void ivas_merge_sba_transports_fx(
      64             :     Word32 data_in_f1[][L_FRAME48k], // Q_f1
      65             :     Word32 *data_in_f2[],            // Q_f2
      66             :     Word32 *data_out_f[],            // Q_out
      67             :     const Word16 input_frame,
      68             :     const Word16 sba_analysis_order,
      69             :     Word16 Q_f1,
      70             :     Word16 Q_f2,
      71             :     Word16 *Q_out )
      72             : {
      73             :     Word16 i, j, nchan_sba;
      74       14920 :     nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) );
      75             : 
      76       74600 :     FOR( i = 0; i < nchan_sba; i++ )
      77             :     {
      78    51950880 :         FOR( j = 0; j < input_frame; j++ )
      79             :         {
      80    51891200 :             data_out_f[i][j] = L_shr( L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ), Q1 );
      81    51891200 :             move32();
      82             :         }
      83             :     }
      84       14920 :     *Q_out = sub( Q_f1, 1 );
      85       14920 :     return;
      86             : }
      87             : /*--------------------------------------------------------------------------*
      88             :  * ivas_osba_enc_open()
      89             :  *
      90             :  * Allocate and initialize OMASA handle
      91             :  *--------------------------------------------------------------------------*/
      92          37 : ivas_error ivas_osba_enc_open_fx(
      93             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
      94             : )
      95             : {
      96             :     Word16 i;
      97             :     OSBA_ENC_HANDLE hOSba;
      98             :     Word16 input_frame;
      99             :     ivas_error error;
     100             :     Word16 len;
     101          37 :     error = IVAS_ERR_OK;
     102             : 
     103          37 :     IF( ( hOSba = (OSBA_ENC_HANDLE) malloc( sizeof( OSBA_ENC_DATA ) ) ) == NULL )
     104             :     {
     105           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
     106             :     }
     107         185 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
     108             :     {
     109         148 :         set_val_Word32( hOSba->prev_object_dm_gains_fx[i], INV_SQRT_2_Q30, MAX_INPUT_CHANNELS );
     110             :     }
     111          37 :     len = NS2SA_FX2( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS );
     112          37 :     move16();
     113         147 :     FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
     114             :     {
     115         110 :         IF( ( hOSba->input_data_mem_fx[i] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL )
     116             :         {
     117           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OSBA input buffers" );
     118             :         }
     119         110 :         set_val_Word32( hOSba->input_data_mem_fx[i], 0, len );
     120             :     }
     121          75 :     FOR( ; i < MAX_NUM_OBJECTS; i++ )
     122             :     {
     123          38 :         hOSba->input_data_mem_fx[i] = NULL;
     124             :     }
     125             :     Word16 tmp_e;
     126          37 :     Word32 tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hEncoderConfig->input_Fs, FRAMES_PER_SEC, &tmp_e ) );
     127          37 :     tmp32 = L_shr( tmp32, sub( 15, tmp_e ) );
     128          37 :     input_frame = extract_l( tmp32 );
     129             : 
     130       31717 :     FOR( i = 0; i < input_frame; i++ )
     131             :     {
     132       31680 :         tmp32 = L_deposit_h( BASOP_Util_Divide1616_Scale( i, input_frame, &tmp_e ) );
     133       31680 :         hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); // Q31
     134       31680 :         move32();
     135             :     }
     136          37 :     st_ivas->hOSba = hOSba;
     137             : 
     138          37 :     return error;
     139             : }
     140             : 
     141             : /*--------------------------------------------------------------------------*
     142             :  * ivas_omasa_enc_close()
     143             :  *
     144             :  * Close OMASA handle
     145             :  *--------------------------------------------------------------------------*/
     146         627 : void ivas_osba_enc_close_fx(
     147             :     OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */
     148             : )
     149             : {
     150             :     Word16 n;
     151         627 :     test();
     152         627 :     IF( hOSba == NULL || *hOSba == NULL )
     153             :     {
     154         590 :         return;
     155             :     }
     156         185 :     FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
     157             :     {
     158         148 :         IF( ( *hOSba )->input_data_mem_fx[n] != NULL )
     159             :         {
     160         110 :             free( ( *hOSba )->input_data_mem_fx[n] );
     161         110 :             ( *hOSba )->input_data_mem_fx[n] = NULL;
     162             :         }
     163             :     }
     164          37 :     free( *hOSba );
     165          37 :     ( *hOSba ) = NULL;
     166             : 
     167          37 :     return;
     168             : }
     169             : 
     170             : /*--------------------------------------------------------------------------*
     171             :  * ivas_osba_enc_reconfig()
     172             :  *
     173             :  * oSBA encoder reconfiguration
     174             :  *--------------------------------------------------------------------------*/
     175       37000 : ivas_error ivas_osba_enc_reconfig(
     176             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure           */
     177             : )
     178             : {
     179             : 
     180             :     Word16 n, nSCE_old, nCPE_old, nchan_transport_old;
     181             :     ISM_MODE old_ism_mode;
     182             :     Word32 ivas_total_brate;
     183             :     ivas_error error;
     184             :     ENCODER_CONFIG_HANDLE hEncoderConfig;
     185             : 
     186       37000 :     error = IVAS_ERR_OK;
     187       37000 :     move32();
     188       37000 :     hEncoderConfig = st_ivas->hEncoderConfig;
     189       37000 :     ivas_total_brate = hEncoderConfig->ivas_total_brate;
     190       37000 :     move32();
     191             :     Word16 nchan_transport;
     192             : 
     193       37000 :     IF( NE_32( ivas_total_brate, hEncoderConfig->last_ivas_total_brate ) )
     194             :     {
     195         653 :         DIRAC_ENC_HANDLE hDirAC = st_ivas->hDirAC;
     196             :         SPAR_ENC_HANDLE hSpar;
     197             :         Word16 analysis_order_old;
     198             :         Word16 spar_reconfig_flag;
     199             :         Word16 nbands_old;
     200             :         Word16 ndir_old;
     201             : 
     202         653 :         spar_reconfig_flag = 0;
     203         653 :         move16();
     204         653 :         old_ism_mode = st_ivas->ism_mode;
     205         653 :         move32();
     206         653 :         st_ivas->ism_mode = ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism );
     207         653 :         nchan_transport_old = st_ivas->nchan_transport;
     208         653 :         nCPE_old = st_ivas->nCPE;
     209         653 :         nSCE_old = st_ivas->nSCE;
     210         653 :         move16();
     211         653 :         move16();
     212         653 :         move16();
     213             : 
     214         653 :         st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, hEncoderConfig->sba_order );
     215         653 :         move16();
     216         653 :         analysis_order_old = ivas_sba_get_analysis_order_fx( hEncoderConfig->last_ivas_total_brate, hEncoderConfig->sba_order );
     217             : 
     218         653 :         nbands_old = st_ivas->hQMetaData->q_direction->cfg.nbands;
     219         653 :         move16();
     220         653 :         ndir_old = st_ivas->hQMetaData->no_directions;
     221         653 :         move16();
     222             : 
     223         653 :         test();
     224         653 :         IF( NE_16( analysis_order_old, st_ivas->sba_analysis_order ) || NE_32( old_ism_mode, st_ivas->ism_mode ) )
     225             :         {
     226             :             Word16 i, n_old;
     227             :             Word32 **old_mem_hp20_in_fx;
     228             : 
     229         396 :             n_old = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( analysis_order_old, 1 ), add( analysis_order_old, 1 ) ) );
     230         396 :             n = add( st_ivas->hEncoderConfig->nchan_ism, imult1616( add( st_ivas->sba_analysis_order, 1 ), add( st_ivas->sba_analysis_order, 1 ) ) );
     231             : 
     232         396 :             IF( GT_16( n, n_old ) )
     233             :             {
     234             :                 /* save old mem_hp_20 pointer */
     235          92 :                 old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
     236          92 :                 st_ivas->mem_hp20_in_fx = NULL;
     237             : 
     238          92 :                 IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
     239             :                 {
     240           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
     241             :                 }
     242             : 
     243         762 :                 FOR( i = 0; i < n_old; i++ )
     244             :                 {
     245         670 :                     st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
     246         670 :                     old_mem_hp20_in_fx[i] = NULL;
     247             :                 }
     248             :                 /* create additional hp20 memories */
     249         909 :                 FOR( ; i < n; i++ )
     250             :                 {
     251         817 :                     IF( ( st_ivas->mem_hp20_in_fx[i] = (Word32 *) malloc( ( L_HP20_MEM + 2 ) * sizeof( Word32 ) ) ) == NULL )
     252             :                     {
     253           0 :                         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
     254             :                     }
     255             : 
     256         817 :                     set32_fx( st_ivas->mem_hp20_in_fx[i], 0, L_HP20_MEM + 2 );
     257             :                 }
     258             : 
     259          92 :                 free( old_mem_hp20_in_fx );
     260          92 :                 old_mem_hp20_in_fx = NULL;
     261             :             }
     262         304 :             ELSE IF( LT_16( n, n_old ) )
     263             :             {
     264             :                 /* save old mem_hp_20 pointer */
     265          87 :                 old_mem_hp20_in_fx = st_ivas->mem_hp20_in_fx;
     266          87 :                 st_ivas->mem_hp20_in_fx = NULL;
     267             : 
     268          87 :                 IF( ( st_ivas->mem_hp20_in_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
     269             :                 {
     270           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
     271             :                 }
     272             : 
     273         720 :                 FOR( i = 0; i < n; i++ )
     274             :                 {
     275         633 :                     st_ivas->mem_hp20_in_fx[i] = old_mem_hp20_in_fx[i];
     276         633 :                     old_mem_hp20_in_fx[i] = NULL;
     277             :                 }
     278             :                 /* remove superfluous hp20 memories */
     279         858 :                 FOR( ; i < n_old; i++ )
     280             :                 {
     281         771 :                     free( old_mem_hp20_in_fx[i] );
     282         771 :                     old_mem_hp20_in_fx[i] = NULL;
     283             :                 }
     284             : 
     285          87 :                 free( old_mem_hp20_in_fx );
     286          87 :                 old_mem_hp20_in_fx = NULL;
     287             :             }
     288             :         }
     289             : 
     290         653 :         ivas_spar_config_fx( ivas_total_brate, s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, -1 );
     291             : 
     292         653 :         hSpar = st_ivas->hSpar;
     293             : 
     294         653 :         IF( EQ_16( st_ivas->nchan_transport, 1 ) )
     295             :         {
     296         228 :             hEncoderConfig->element_mode_init = IVAS_SCE;
     297         228 :             move16();
     298             :         }
     299             :         ELSE
     300             :         {
     301         425 :             hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     302         425 :             move16();
     303             :         }
     304         653 :         test();
     305         653 :         test();
     306         653 :         test();
     307         653 :         test();
     308         653 :         IF( NE_16( nchan_transport_old, st_ivas->nchan_transport ) || ( LT_32( ivas_total_brate, IVAS_512k ) && GE_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) || ( GE_32( ivas_total_brate, IVAS_512k ) && LT_32( hEncoderConfig->last_ivas_total_brate, IVAS_512k ) ) )
     309             :         {
     310             :             /* FB mixer handle */
     311         540 :             IF( hDirAC->hFbMixer != NULL )
     312             :             {
     313           0 :                 ivas_FB_mixer_close_fx( &( hDirAC->hFbMixer ), hEncoderConfig->input_Fs, 0 );
     314           0 :                 hDirAC->hFbMixer = NULL;
     315             :             }
     316         540 :             spar_reconfig_flag = 1;
     317         540 :             move16();
     318         540 :             ivas_spar_enc_close_fx( &( st_ivas->hSpar ), hEncoderConfig->input_Fs, hEncoderConfig->nchan_inp, spar_reconfig_flag );
     319             : 
     320         540 :             IF( NE_32( ( error = ivas_spar_enc_open_fx( st_ivas, spar_reconfig_flag ) ), IVAS_ERR_OK ) )
     321             :             {
     322           0 :                 return error;
     323             :             }
     324             :         }
     325         653 :         st_ivas->hSpar->spar_reconfig_flag = spar_reconfig_flag;
     326         653 :         move16();
     327         653 :         IF( NE_32( ( error = ivas_dirac_enc_reconfigure( st_ivas ) ), IVAS_ERR_OK ) )
     328             :         {
     329           0 :             return error;
     330             :         }
     331         653 :         test();
     332         653 :         IF( NE_16( st_ivas->hQMetaData->q_direction->cfg.nbands, nbands_old ) || NE_16( st_ivas->hQMetaData->no_directions, ndir_old ) )
     333             :         {
     334             :             Word16 dir, j, i;
     335         334 :             IVAS_QDIRECTION *q_direction = st_ivas->hQMetaData->q_direction;
     336         730 :             FOR( dir = 0; dir < st_ivas->hQMetaData->no_directions; dir++ )
     337             :             {
     338        2447 :                 FOR( j = 0; j < q_direction[dir].cfg.nbands; j++ )
     339             :                 {
     340       10255 :                     FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     341             :                     {
     342        8204 :                         q_direction[dir].band_data[j].energy_ratio_index[i] = 0;
     343        8204 :                         move32();
     344        8204 :                         q_direction[dir].band_data[j].energy_ratio_index_mod[i] = 0;
     345        8204 :                         move32();
     346             :                     }
     347             :                 }
     348             :             }
     349             :         }
     350         653 :         hSpar->enc_param_start_band = hDirAC->hConfig->enc_param_start_band;
     351         653 :         move16();
     352             : 
     353             :         /*-----------------------------------------------------------------*
     354             :          * Allocate, initialize, and configure SCE/CPE/MCT handles
     355             :          *-----------------------------------------------------------------*/
     356         653 :         nchan_transport = st_ivas->nchan_transport;
     357             : 
     358         653 :         test();
     359         653 :         test();
     360         653 :         IF( old_ism_mode == ISM_MODE_NONE && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
     361             :         {
     362             :             {
     363         186 :                 nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
     364         186 :                 st_ivas->nCPE = shr_r( nchan_transport, 1 );
     365             :             }
     366             :         }
     367         467 :         ELSE IF( EQ_32( old_ism_mode, ISM_SBA_MODE_DISC ) && st_ivas->ism_mode == ISM_MODE_NONE )
     368             :         {
     369         180 :             nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism );
     370             : 
     371         180 :             nchan_transport = st_ivas->nchan_transport;
     372             :         }
     373         287 :         ELSE IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
     374             :         {
     375          69 :             nchan_transport_old = add( nchan_transport_old, st_ivas->hEncoderConfig->nchan_ism );
     376          69 :             nchan_transport = add( st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_ism );
     377          69 :             st_ivas->nCPE = shr_r( nchan_transport, 1 );
     378             :         }
     379             :         Word16 tmp_e;
     380         653 :         Word32 bitrate_per_chan = L_deposit_h( BASOP_Util_Divide3216_Scale( ivas_total_brate, st_ivas->nchan_transport, &tmp_e ) );
     381         653 :         bitrate_per_chan = L_shr( bitrate_per_chan, sub( 15, tmp_e ) );
     382         653 :         IF( NE_32( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, bitrate_per_chan, imult3216( bitrate_per_chan, CPE_CHANNELS ), MC_MODE_NONE ) ), IVAS_ERR_OK ) )
     383             :         {
     384           0 :             return error;
     385             :         }
     386             :     }
     387             : 
     388       37000 :     return error;
     389             : }
     390             : /*--------------------------------------------------------------------------*
     391             :  * ivas_osba_enc()
     392             :  *
     393             :  * Main OSBA encoding function
     394             :  *--------------------------------------------------------------------------*/
     395             : 
     396       37000 : void ivas_osba_enc_fx(
     397             :     OSBA_ENC_HANDLE hOSba,           /* i/o: OSBA encoder handle                         */
     398             :     ISM_METADATA_HANDLE hIsmMeta[],  /* i/o: ISM metadata handle                         */
     399             :     Word32 *data_in_fx[],            /* i/o: Input / transport audio signals             q_data*/
     400             :     const Word16 input_frame,        /* i  : Input frame size                            */
     401             :     const Word16 nchan_ism,          /* i  : Number of objects for parameter analysis    */
     402             :     const ISM_MODE ism_mode,         /* i  : ISM mode                                    */
     403             :     const Word16 sba_analysis_order, /* i  : SBA order evaluated in DirAC/SPAR encoder   */
     404             :     const Word32 input_Fs,           /* i  : input sampling rate                         */
     405             :     const Word16 sba_planar,         /* i  : planar SBA flag                             */
     406             :     Word16 *q_data )
     407             : {
     408             :     Word32 data_out_fx[MAX_INPUT_CHANNELS][L_FRAME48k];
     409       37000 :     Word16 Q_out = *q_data;
     410       37000 :     move16();
     411             :     Word16 n, delay_s;
     412       37000 :     delay_s = NS2SA_FX2( input_Fs, IVAS_FB_ENC_DELAY_NS );
     413       37000 :     IF( ism_mode == ISM_MODE_NONE )
     414             :     {
     415             :         /*keep the delay buffer up to date*/
     416       55560 :         FOR( n = 0; n < nchan_ism; n++ )
     417             :         {
     418       40640 :             MVR2R_WORD32( &data_in_fx[n][input_frame - delay_s], hOSba->input_data_mem_fx[n], delay_s ); // Q_data
     419             :         }
     420             :         /* Convert ISM to SBA */
     421             : 
     422       14920 :         ivas_osba_render_ism_to_sba_fx( data_in_fx, data_out_fx, input_frame, sba_analysis_order, nchan_ism, hIsmMeta, hOSba->prev_object_dm_gains_fx, hOSba->interpolator_fx, &Q_out );
     423             : 
     424       14920 :         IF( sba_planar )
     425             :         {
     426           0 :             ivas_sba_zero_vert_comp_fx( &( data_in_fx[nchan_ism] ), sba_analysis_order, sba_planar, input_frame );
     427             :         }
     428             : 
     429             : 
     430             :         /* Merge SBA signals */
     431       14920 :         ivas_merge_sba_transports_fx( data_out_fx, &( data_in_fx[nchan_ism] ), data_in_fx, input_frame, sba_analysis_order, Q_out, *q_data, q_data );
     432             :     }
     433             :     ELSE
     434             :     {
     435             :         Word16 azimuth_fx, elevation_fx;
     436             :         /* delay ISM input channels to match the SBA encoder delay */
     437       91440 :         FOR( n = 0; n < nchan_ism; n++ )
     438             :         {
     439       69360 :             delay_signal32_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s );
     440             : 
     441       69360 :             azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) );     // Q0
     442       69360 :             elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
     443       69360 :             ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, hOSba->prev_object_dm_gains_fx[n], sba_analysis_order, Q30 );
     444             :         }
     445             :     }
     446             : 
     447             :     /* Set the number of objects */
     448       37000 :     hOSba->nchan_ism = nchan_ism;
     449       37000 :     move16();
     450       37000 :     return;
     451             : }
     452             : 
     453             : /*--------------------------------------------------------------------------*
     454             :  * Local functions
     455             :  *--------------------------------------------------------------------------*/
     456             : /* Render ISMs to SBA */
     457       14920 : static void ivas_osba_render_ism_to_sba_fx(
     458             :     Word32 *data_in_fx[],             // Q_data
     459             :     Word32 data_out_fx[][L_FRAME48k], // Q_data
     460             :     const Word16 input_frame,
     461             :     const Word16 sba_analysis_order,
     462             :     const Word16 nchan_ism,
     463             :     ISM_METADATA_HANDLE hIsmMeta[],
     464             :     Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], // Q30
     465             :     const Word32 interpolator_fx[L_FRAME48k],   // Q31
     466             :     Word16 *Q_data )
     467             : {
     468             :     Word16 i, j, k;
     469             :     Word16 azimuth_fx, elevation_fx;
     470             :     Word32 gains_fx[MAX_INPUT_CHANNELS];
     471             :     Word32 g1_fx, g2_fx;
     472             :     Word16 nchan_sba;
     473       14920 :     nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) );
     474             : 
     475       74600 :     FOR( i = 0; i < nchan_sba; i++ )
     476             :     {
     477       59680 :         set_val_Word32( data_out_fx[i], 0, input_frame );
     478             :     }
     479             : 
     480       55560 :     FOR( i = 0; i < nchan_ism; i++ )
     481             :     {
     482             :         // azimuth = (int16_t) floorf( hIsmMeta[i]->azimuth + 0.5f );
     483       40640 :         azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
     484             :         //   elevation = (int16_t) floorf( hIsmMeta[i]->elevation + 0.5f );
     485       40640 :         elevation_fx = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, 2097152 /*0.5.Q22*/ ), Q22 ) ); // Q0
     486             : 
     487       40640 :         ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, gains_fx, sba_analysis_order, Q30 );
     488             : 
     489             :         /* Render using the sh gains */
     490      203200 :         FOR( j = 0; j < nchan_sba; j++ )
     491             :         {
     492      162560 :             test();
     493      162560 :             IF( L_abs( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 )
     494             :             {
     495   145480862 :                 FOR( k = 0; k < input_frame; k++ )
     496             :                 {
     497             :                     //     g1 = interpolator[k];
     498   145319360 :                     g1_fx = interpolator_fx[k]; // Q31
     499   145319360 :                     move32();
     500             :                     //     g2 = 1.0f - g1;
     501   145319360 :                     g2_fx = L_sub( ONE_IN_Q31, g1_fx ); // Q31
     502   145319360 :                     move32();
     503             :                     //  data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
     504   145319360 :                     data_out_fx[j][k] = L_add( data_out_fx[j][k], L_shr( Mpy_32_32( L_add( Mpy_32_32( g1_fx, gains_fx[j] ), Mpy_32_32( g2_fx, prev_gains_fx[i][j] ) ), data_in_fx[i][k] ), 1 ) ); // Q_data-2
     505   145319360 :                     move32();
     506             :                 }
     507             :             }
     508      162560 :             prev_gains_fx[i][j] = gains_fx[j]; // Q30
     509      162560 :             move32();
     510             :         }
     511             :     }
     512       14920 :     *Q_data = sub( *Q_data, 2 );
     513             : 
     514             : 
     515       14920 :     return;
     516             : }

Generated by: LCOV version 1.14