LCOV - code coverage report
Current view: top level - lib_dec - ivas_omasa_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 291 316 92.1 %
Date: 2025-05-03 01:55:50 Functions: 8 8 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 "ivas_cnst.h"
      36             : #include "ivas_prot_fx.h"
      37             : #include "prot_fx.h"
      38             : #include "ivas_prot_rend_fx.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : 
      43             : 
      44             : /*-------------------------------------------------------------------------
      45             :  * Local constants
      46             :  *------------------------------------------------------------------------*/
      47             : 
      48             : #define OMASA_TDREND_MATCHING_GAIN_FX 26026
      49             : 
      50             : /*-------------------------------------------------------------------*
      51             :  * ivas_omasa_data_open()
      52             :  *
      53             :  * Allocate and initialize MASA_ISM rendering handle
      54             :  *-------------------------------------------------------------------*/
      55             : 
      56          34 : ivas_error ivas_omasa_data_open_fx(
      57             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle  */
      58             : )
      59             : {
      60             :     MASA_ISM_DATA_HANDLE hMasaIsmData;
      61             :     Word16 ch, bin;
      62             :     Word16 sf, obj_idx;
      63             : 
      64          34 :     IF( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
      65             :     {
      66           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
      67             :     }
      68             : 
      69        2074 :     FOR( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
      70             :     {
      71        6120 :         FOR( ch = 0; ch < 2; ch++ )
      72             :         {
      73        4080 :             hMasaIsmData->ismPreprocMatrix_fx[ch][ch][bin] = 32767; /* 1.0f in Q15 */
      74        4080 :             move16();
      75        4080 :             hMasaIsmData->ismPreprocMatrix_fx[1 - ch][ch][bin] = 0; // Q15
      76        4080 :             move16();
      77        4080 :             hMasaIsmData->eneMoveIIR_fx[ch][bin] = 0; // Q22
      78        4080 :             move32();
      79        4080 :             hMasaIsmData->enePreserveIIR_fx[ch][bin] = 0; // Q22
      80        4080 :             move32();
      81             :         }
      82        2040 :         hMasaIsmData->preprocEneTarget_fx[bin] = 0; // Q19
      83        2040 :         move32();
      84        2040 :         hMasaIsmData->preprocEneRealized_fx[bin] = 0; // Q19
      85        2040 :         move32();
      86             :     }
      87             : 
      88          34 :     hMasaIsmData->objectsMoved = 0;
      89          34 :     move16();
      90          34 :     hMasaIsmData->delayBuffer_fx = NULL;
      91             : 
      92         170 :     FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
      93             :     {
      94         136 :         hMasaIsmData->ism_is_edited[ch] = 0;
      95         136 :         move16();
      96         136 :         hMasaIsmData->q_elevation_old_fx[ch] = 0; // Q22
      97         136 :         move32();
      98         136 :         hMasaIsmData->q_azimuth_old_fx[ch] = 0; // Q22
      99         136 :         move32();
     100             :     }
     101             : 
     102         170 :     FOR( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
     103             :     {
     104         136 :         set16_fx( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     105         136 :         set16_fx( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     106         952 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
     107             :         {
     108         816 :             set32_fx( hMasaIsmData->energy_ratio_ism_fx[obj_idx][sf], 0, CLDFB_NO_CHANNELS_MAX );
     109             :         }
     110             :     }
     111          34 :     set16_fx( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     112          34 :     set16_fx( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     113             : 
     114          34 :     st_ivas->hMasaIsmData = hMasaIsmData;
     115             : 
     116          34 :     return IVAS_ERR_OK;
     117             : }
     118             : 
     119             : 
     120             : /*-------------------------------------------------------------------*
     121             :  * ivas_omasa_data_close()
     122             :  *
     123             :  * Deallocate MASA_ISM rendering handle
     124             :  *-------------------------------------------------------------------*/
     125             : 
     126         604 : void ivas_omasa_data_close_fx(
     127             :     MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle    */
     128             : )
     129             : {
     130             :     Word16 i;
     131             : 
     132         604 :     test();
     133         604 :     IF( hMasaIsmData == NULL || *hMasaIsmData == NULL )
     134             :     {
     135         570 :         return;
     136             :     }
     137             : 
     138          34 :     IF( ( *hMasaIsmData )->delayBuffer_fx != NULL )
     139             :     {
     140          39 :         FOR( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
     141             :         {
     142          27 :             free( ( *hMasaIsmData )->delayBuffer_fx[i] ); // Q11
     143             :         }
     144          12 :         free( ( *hMasaIsmData )->delayBuffer_fx );
     145          12 :         ( *hMasaIsmData )->delayBuffer_fx = NULL;
     146             :     }
     147             : 
     148          34 :     free( *hMasaIsmData );
     149          34 :     *hMasaIsmData = NULL;
     150             : 
     151          34 :     return;
     152             : }
     153             : 
     154             : 
     155             : /*--------------------------------------------------------------------------*
     156             :  * ivas_omasa_dec_config()
     157             :  *
     158             :  * oMASA decoder configuration
     159             :  *--------------------------------------------------------------------------*/
     160             : 
     161        1460 : ivas_error ivas_omasa_dec_config_fx(
     162             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure                                  */
     163             :     UWord16 *nSamplesRendered, /* o  : number of samples flushed from the previous frame (JBM) */
     164             :     Word16 *num_src,
     165             :     Word16 SrcInd[MAX_NUM_TDREND_CHANNELS],
     166             :     Word16 *data /* o  : output synthesis signal                                 Qx*/
     167             : )
     168             : {
     169             :     Word16 k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD;
     170             :     Word32 ivas_total_brate, ism_total_brate, cpe_brate;
     171             :     Word32 brate_SCE, brate_CPE;
     172             :     ISM_MODE ism_mode_old;
     173             :     IVAS_FORMAT ivas_format_orig;
     174             :     Word16 nchan_out_buff, nchan_out_buff_old;
     175             :     ivas_error error;
     176             :     RENDERER_TYPE old_renderer_type;
     177             : 
     178             :     /* initializations */
     179        1460 :     ism_total_brate = 0;
     180        1460 :     move32();
     181        1460 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
     182        1460 :     move32();
     183             : 
     184             :     /* save previous frame parameters */
     185        1460 :     ism_mode_old = ivas_omasa_ism_mode_select_fx( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
     186        1460 :     move16();
     187        1460 :     st_ivas->ism_mode = ism_mode_old;
     188        1460 :     move16();
     189             : 
     190        1460 :     ivas_format_orig = st_ivas->ivas_format;
     191        1460 :     move16();
     192        1460 :     st_ivas->ivas_format = st_ivas->last_ivas_format;
     193        1460 :     move16();
     194        1460 :     ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
     195        1460 :     nchan_out_buff_old = ivas_get_nchan_buffers_dec_ivas_fx( st_ivas, -1, -1 );
     196        1460 :     move16();
     197             : 
     198        1460 :     st_ivas->ivas_format = ivas_format_orig;
     199        1460 :     move16();
     200             : 
     201        1460 :     nSCE_old = st_ivas->nSCE;
     202        1460 :     move16();
     203        1460 :     nchan_hp20_old = getNumChanSynthesis( st_ivas );
     204        1460 :     move16();
     205             : 
     206             :     /* set ism_mode of current frame */
     207        1460 :     st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
     208        1460 :     move16();
     209             : 
     210             :     /*-----------------------------------------------------------------*
     211             :      * Renderer selection
     212             :      *-----------------------------------------------------------------*/
     213             : 
     214        1460 :     old_renderer_type = st_ivas->renderer_type;
     215        1460 :     move32();
     216             : 
     217             :     /* MASA reconfig. */
     218        1460 :     cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
     219        1460 :     move32();
     220        1460 :     test();
     221        1460 :     test();
     222        1460 :     test();
     223        1460 :     IF( ( st_ivas->ini_active_frame == 0 ) && ( ivas_total_brate != FRAME_NO_DATA ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
     224             :     {
     225           0 :         st_ivas->hCPE[0]->nchan_out = 1;
     226           0 :         move16();
     227             :     }
     228             :     ELSE
     229             :     {
     230        1460 :         IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
     231             :         {
     232           0 :             return error;
     233             :         }
     234             :     }
     235             : 
     236        1460 :     IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
     237             :     {
     238         479 :         st_ivas->hCPE[0]->nchan_out = 1;
     239         479 :         move16();
     240             :     }
     241             :     ELSE
     242             :     {
     243         981 :         st_ivas->hCPE[0]->nchan_out = 2;
     244         981 :         move16();
     245             :     }
     246             : 
     247             :     /* OMASA reconfig. */
     248        1460 :     test();
     249        1460 :     IF( st_ivas->hMasaIsmData == NULL && EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     250             :     {
     251           2 :         IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     252             :         {
     253           0 :             return error;
     254             :         }
     255             :     }
     256             : 
     257        1460 :     ivas_set_omasa_TC_fx( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
     258             : 
     259             :     /* re-configure hp20 memories */
     260        1460 :     IF( NE_32( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ), IVAS_ERR_OK ) )
     261             :     {
     262           0 :         return error;
     263             :     }
     264             : 
     265             :     /* reconfigure core-coders for ISMs */
     266        1460 :     k = 0;
     267        1460 :     move16();
     268       11574 :     WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
     269             :     {
     270       10114 :         k = add( k, 1 );
     271             :     }
     272             : 
     273        3355 :     FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
     274             :     {
     275        1895 :         ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
     276             :     }
     277             : 
     278        1460 :     brate_SCE = 0;
     279        1460 :     move32();
     280        1460 :     IF( st_ivas->nSCE > 0 )
     281             :     {
     282        1066 :         brate_SCE = sep_object_brate[k - 2][st_ivas->nSCE - 1];
     283        1066 :         move32();
     284             :     }
     285        1460 :     brate_CPE = L_sub( ivas_total_brate, ism_total_brate );
     286             : 
     287        1460 :     IF( NE_32( ( error = ivas_corecoder_dec_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, brate_SCE, brate_CPE ) ), IVAS_ERR_OK ) )
     288             :     {
     289           0 :         return error;
     290             :     }
     291             : 
     292        1460 :     IF( NE_16( ism_mode_old, st_ivas->ism_mode ) )
     293             :     {
     294             :         /* ISM MD reconfig. */
     295        1459 :         n_MD = 0;
     296        1459 :         move16();
     297             : 
     298        1459 :         test();
     299        1459 :         IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     300             :         {
     301         675 :             n_MD = 1;
     302         675 :             move16();
     303             : 
     304         675 :             IF( st_ivas->hIsmMetaData[0] == NULL )
     305             :             {
     306         233 :                 IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL ) ), IVAS_ERR_OK ) )
     307             :                 {
     308           0 :                     return error;
     309             :                 }
     310             :             }
     311             :         }
     312         784 :         ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     313             :         {
     314         390 :             n_MD = st_ivas->nchan_ism;
     315         390 :             move16();
     316             : 
     317         390 :             ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
     318             : 
     319         390 :             IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL ) ), IVAS_ERR_OK ) )
     320             :             {
     321           0 :                 return error;
     322             :             }
     323             :         }
     324             : 
     325        1459 :         ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD );
     326             : 
     327        1459 :         st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
     328             : 
     329             :         /*-----------------------------------------------------------------*
     330             :          * Renderer selection
     331             :          *-----------------------------------------------------------------*/
     332             : 
     333        1459 :         ivas_renderer_select( st_ivas );
     334             : 
     335             :         /*-------------------------------------------------------------------*
     336             :          * Reallocate rendering handles
     337             :          *--------------------------------------------------------------------*/
     338             : 
     339        1459 :         IF( NE_16( old_renderer_type, st_ivas->renderer_type ) )
     340             :         {
     341          76 :             IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
     342             :             {
     343          38 :                 IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
     344             :                 {
     345           0 :                     return error;
     346             :                 }
     347             :             }
     348             :             ELSE
     349             :             {
     350          38 :                 ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
     351             :             }
     352             :         }
     353             : 
     354             :         /* objects renderer reconfig. */
     355        1459 :         IF( st_ivas->hMasaIsmData != NULL )
     356             :         {
     357        1459 :             ivas_omasa_separate_object_renderer_close( st_ivas );
     358             :         }
     359             : 
     360        1459 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
     361             :         {
     362         221 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     363             :             {
     364             :                 /* Allocate TD renderer for the objects in DISC mode */
     365          54 :                 IF( st_ivas->hBinRendererTd == NULL )
     366             :                 {
     367          35 :                     IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ), IVAS_ERR_OK ) )
     368             :                     {
     369           0 :                         return error;
     370             :                     }
     371             :                 }
     372             : 
     373             :                 /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
     374          54 :                 IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
     375             :                 {
     376           0 :                     return error;
     377             :                 }
     378             :             }
     379             :             ELSE
     380             :             {
     381             :                 /* TD renderer handle */
     382         167 :                 test();
     383         167 :                 IF( st_ivas->hBinRendererTd != NULL && EQ_16( st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM, TRUE ) )
     384             :                 {
     385          35 :                     ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
     386             : 
     387          35 :                     st_ivas->hHrtfTD = NULL;
     388             :                 }
     389             : 
     390             :                 /* ISM renderer handle + ISM data handle */
     391         167 :                 ivas_omasa_separate_object_renderer_close( st_ivas );
     392             :             }
     393             :         }
     394             : 
     395        1459 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
     396             :         {
     397         667 :             IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
     398             :             {
     399           0 :                 return error;
     400             :             }
     401             : 
     402         667 :             test();
     403         667 :             test();
     404         667 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     405             :             {
     406             :                 /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
     407         485 :                 IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
     408             :                 {
     409           0 :                     return error;
     410             :                 }
     411             :             }
     412             :             ELSE
     413             :             {
     414             :                 /* ISM renderer handle + ISM data handle */
     415         182 :                 ivas_omasa_separate_object_renderer_close( st_ivas );
     416             :             }
     417             :         }
     418             : 
     419             :         /*-----------------------------------------------------------------*
     420             :          * TD Decorrelator
     421             :          *-----------------------------------------------------------------*/
     422             : 
     423        1459 :         IF( st_ivas->hDiracDecBin != NULL )
     424             :         {
     425         657 :             IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
     426             : 
     427             :             {
     428           0 :                 return error;
     429             :             }
     430             :         }
     431             : 
     432             :         /*-----------------------------------------------------------------*
     433             :          * CLDFB instances
     434             :          *-----------------------------------------------------------------*/
     435             : 
     436        1459 :         IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
     437             :         {
     438           0 :             return error;
     439             :         }
     440             : 
     441             :         /*-----------------------------------------------------------------*
     442             :          * floating-point output audio buffers
     443             :          *-----------------------------------------------------------------*/
     444             : 
     445        1459 :         nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 );
     446        1459 :         IF( NE_32( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ), IVAS_ERR_OK ) )
     447             :         {
     448           0 :             return error;
     449             :         }
     450             :     }
     451             : 
     452        1460 :     return IVAS_ERR_OK;
     453             : }
     454             : 
     455             : 
     456             : /*--------------------------------------------------------------------------*
     457             :  * ivas_set_surplus_brate_dec()
     458             :  *
     459             :  * set bit-rate surplus in combined format coding
     460             :  *--------------------------------------------------------------------------*/
     461        6418 : void ivas_set_surplus_brate_dec(
     462             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
     463             :     Word32 *ism_total_brate  /* i/o: ISM total bitrate      */
     464             : )
     465             : {
     466             :     Word16 n, bits_ism, bits_element[MAX_NUM_OBJECTS];
     467             :     Word32 ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
     468             : 
     469        6418 :     *ism_total_brate = 0;
     470        6418 :     move32();
     471             : 
     472        6418 :     test();
     473        6418 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     474             :     {
     475        3652 :         *ism_total_brate = ivas_interformat_brate_fx( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
     476        3652 :         move32();
     477             : 
     478        3652 :         st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, *ism_total_brate );
     479        3652 :         move32();
     480             : 
     481             :         /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
     482        3652 :         st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
     483        3652 :         move32();
     484             : 
     485        3652 :         st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
     486        3652 :         move16();
     487        3652 :         if ( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
     488             :         {
     489           0 :             st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
     490           0 :             move16();
     491             :         }
     492             :     }
     493        2766 :     ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     494             :     {
     495             :         Word16 brate_limit_flag, ism_imp[MAX_NUM_OBJECTS], tmp;
     496             : 
     497       10097 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     498             :         {
     499        7331 :             ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
     500        7331 :             move16();
     501             :         }
     502             : 
     503        2766 :         brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, st_ivas->nchan_ism );
     504             : 
     505        2766 :         ism_total_brate_ref = 0;
     506        2766 :         move32();
     507       10097 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     508             :         {
     509        7331 :             ism_total_brate_ref = L_add( ism_total_brate_ref, st_ivas->hSCE[n]->element_brate );
     510             :         }
     511             : 
     512             :         /* bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC ); */
     513        2766 :         bits_ism = extract_l( Mpy_32_32( ism_total_brate_ref, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     514             : 
     515        2766 :         tmp = 0;
     516        2766 :         move16();
     517        2766 :         IF( bits_ism != 0 )
     518             :         {
     519        2766 :             tmp = idiv1616( bits_ism, st_ivas->nchan_ism );
     520             :         }
     521        2766 :         set16_fx( bits_element, tmp, st_ivas->nchan_ism );
     522        2766 :         bits_element[st_ivas->nchan_ism - 1] = add( bits_element[st_ivas->nchan_ism - 1], bits_ism % st_ivas->nchan_ism );
     523        2766 :         move16();
     524        2766 :         bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
     525             : 
     526        2766 :         *ism_total_brate = 0;
     527        2766 :         move32();
     528       10097 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     529             :         {
     530        7331 :             st_ivas->hSCE[n]->element_brate = element_brate[n];
     531        7331 :             move32();
     532             : 
     533        7331 :             *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag ) );
     534        7331 :             move32();
     535             : 
     536        7331 :             test();
     537        7331 :             test();
     538        7331 :             IF( GT_16( ism_imp[n], 1 ) && EQ_16( st_ivas->flag_omasa_brate, 1 ) && brate_limit_flag >= 0 )
     539             :             {
     540         130 :                 *ism_total_brate = L_sub( *ism_total_brate, ADJUST_ISM_BRATE_NEG );
     541         130 :                 move32();
     542             :             }
     543             : 
     544        7331 :             test();
     545        7331 :             test();
     546        7331 :             test();
     547        7331 :             IF( EQ_16( brate_limit_flag, -1 ) && GE_16( ism_imp[n], 1 ) && GE_16( st_ivas->nchan_ism, 3 ) && GT_32( L_sub( ism_total_brate_ref, *ism_total_brate ), IVAS_48k ) )
     548             :             {
     549           0 :                 *ism_total_brate = L_add( *ism_total_brate, ADJUST_ISM_BRATE_POS );
     550           0 :                 move32();
     551             :             }
     552             :         }
     553        2766 :         st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, *ism_total_brate );
     554        2766 :         move32();
     555             : 
     556             :         /* 'st->total_brate' is set in ivas_ism_config */
     557             :     }
     558             :     ELSE
     559             :     {
     560           0 :         st_ivas->hCPE[0]->brate_surplus = 0;
     561           0 :         move32();
     562             :     }
     563             : 
     564        6418 :     return;
     565             : }
     566             : 
     567             : 
     568             : /*--------------------------------------------------------------------------*
     569             :  * ivas_omasa_ism_metadata_dec()
     570             :  *
     571             :  * decode ISM metadata in OMASA format
     572             :  *--------------------------------------------------------------------------*/
     573        6418 : ivas_error ivas_omasa_ism_metadata_dec_fx(
     574             :     Decoder_Struct *st_ivas,            /* i/o: IVAS decoder structure            */
     575             :     const Word32 ism_total_brate,       /* i  : ISM total bitrate                 */
     576             :     Word16 *nchan_ism,                  /* o  : number of ISM separated channels  */
     577             :     Word16 *nchan_transport_ism,        /* o  : number of ISM TCs                 */
     578             :     const Word16 dirac_bs_md_write_idx, /* i  : DirAC bitstream write index       */
     579             :     Word16 nb_bits_metadata[]           /* o  : number of ISM metadata bits       */
     580             : )
     581             : {
     582             :     Word16 n, block;
     583             :     Word16 azimuth_ism, elevation_ism, meta_write_index;
     584             :     ivas_error error;
     585             : 
     586             :     /* set ISM parameters */
     587        6418 :     *nchan_ism = st_ivas->nchan_ism;
     588        6418 :     move16();
     589        6418 :     *nchan_transport_ism = st_ivas->nchan_ism;
     590        6418 :     move16();
     591        6418 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     592             :     {
     593        2029 :         *nchan_ism = 1;
     594        2029 :         move16();
     595        2029 :         *nchan_transport_ism = 1;
     596        2029 :         move16();
     597             :     }
     598        4389 :     ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     599             :     {
     600        1623 :         *nchan_ism = 0;
     601        1623 :         move16();
     602        1623 :         *nchan_transport_ism = 1;
     603        1623 :         move16();
     604             :     }
     605             : 
     606        6418 :     test();
     607        6418 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     608             :     {
     609             :         /* decode ISM metadata */
     610        4795 :         IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
     611             :                                                        nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ),
     612             :                    IVAS_ERR_OK ) )
     613             :         {
     614           0 :             return error;
     615             :         }
     616             : 
     617        4795 :         IF( st_ivas->hDirAC != NULL )
     618             :         {
     619        3592 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     620             :             {
     621        6462 :                 FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     622             :                 {
     623             :                     // azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
     624             :                     // elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
     625        4679 :                     azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->azimuth_fx /*Q22*/ ), 22 ) ); // Q0
     626        4679 :                     if ( st_ivas->hIsmMetaData[n]->azimuth_fx < 0 )
     627             :                     {
     628        2474 :                         azimuth_ism = negate( azimuth_ism );
     629             :                     }
     630        4679 :                     elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->elevation_fx /*Q22*/ ), 22 ) ); // Q0
     631        4679 :                     if ( st_ivas->hIsmMetaData[n]->elevation_fx < 0 )
     632             :                     {
     633        1486 :                         elevation_ism = negate( elevation_ism );
     634             :                     }
     635             : 
     636       23395 :                     FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
     637             :                     {
     638       18716 :                         meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
     639       18716 :                         move16();
     640       18716 :                         st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
     641       18716 :                         move16();
     642       18716 :                         st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
     643       18716 :                         move16();
     644             :                     }
     645             :                 }
     646             :             }
     647             :             ELSE /* ISM_MASA_MODE_MASA_ONE_OBJ */
     648             :             {
     649        1809 :                 azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
     650        1809 :                 if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
     651             :                 {
     652         986 :                     azimuth_ism = negate( azimuth_ism );
     653             :                 }
     654        1809 :                 elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
     655        1809 :                 if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
     656             :                 {
     657         574 :                     elevation_ism = negate( elevation_ism );
     658             :                 }
     659             : 
     660        9045 :                 FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
     661             :                 {
     662        7236 :                     meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
     663        7236 :                     move16();
     664        7236 :                     st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
     665        7236 :                     move16();
     666        7236 :                     st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
     667        7236 :                     move16();
     668             :                 }
     669             :             }
     670             :         }
     671             :     }
     672             : 
     673        6418 :     return IVAS_ERR_OK;
     674             : }
     675             : 
     676             : /*--------------------------------------------------------------------------*
     677             :  * ivas_omasa_dirac_rend_jbm_fx()
     678             :  *
     679             :  * Rendering in OMASA format for JBM
     680             :  *--------------------------------------------------------------------------*/
     681             : 
     682        2705 : void ivas_omasa_dirac_rend_jbm_fx(
     683             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                      */
     684             :     const UWord16 nSamplesAsked,  /* i  : number of samples requested              */
     685             :     UWord16 *nSamplesRendered,    /* o  : number of samples rendered               */
     686             :     UWord16 *nSamplesAvailable,   /* o  : number of samples still to render        */
     687             :     const Word16 nchan_transport, /* i  : number of transport channels             */
     688             :     Word32 *output_f[]            /* o  : rendered time signal                     Q11*/
     689             : )
     690             : {
     691             :     Word16 subframes_rendered;
     692             :     Word16 slots_rendered;
     693             :     Word16 n;
     694             :     Word32 data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
     695             : 
     696        2705 :     test();
     697        2705 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     698             :     {
     699        1634 :         Copy32( output_f[CPE_CHANNELS], data_separated_objects[0], nSamplesAsked );
     700             :     }
     701             :     ELSE
     702             :     {
     703        3820 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     704             :         {
     705        2749 :             Copy32( output_f[n + CPE_CHANNELS], data_separated_objects[n], nSamplesAsked );
     706             :         }
     707             :     }
     708             : 
     709        2705 :     subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
     710        2705 :     move16();
     711        2705 :     slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
     712        2705 :     move16();
     713             : 
     714        2705 :     ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
     715             : 
     716       13525 :     FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
     717             :     {
     718       10820 :         scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29
     719             :     }
     720             : 
     721        2705 :     ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered );
     722             : 
     723       13525 :     FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
     724             :     {
     725       10820 :         scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30
     726             :     }
     727             : 
     728        2705 :     return;
     729             : }
     730             : 
     731             : /*--------------------------------------------------------------------------*
     732             :  * ivas_omasa_dirac_td_binaural_render()
     733             :  *
     734             :  * Binaural rendering in OMASA format for JBM
     735             :  *--------------------------------------------------------------------------*/
     736             : 
     737         122 : ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
     738             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                      */
     739             :     const UWord16 nSamplesAsked,  /* i  : number of samples requested              */
     740             :     UWord16 *nSamplesRendered,    /* o  : number of samples rendered               */
     741             :     UWord16 *nSamplesAvailable,   /* o  : number of samples still to render        */
     742             :     const Word16 nchan_transport, /* i  : number of transport channels             */
     743             :     Word32 *output_fx[]           /* o  : rendered time signal                     Q11*/
     744             : )
     745             : {
     746             :     Word16 n;
     747         122 :     Word16 gain_fx = OMASA_TDREND_MATCHING_GAIN_FX; // Q15
     748         122 :     move16();
     749             :     ivas_error error;
     750             :     Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS];
     751             :     Word32 *p_sepobj_fx[MAX_NUM_OBJECTS]; // Q11
     752             :     Word32 data_separated_objects_fx[MAX_NUM_OBJECTS][L_FRAME48k];
     753         122 :     move16();
     754             : 
     755         610 :     FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
     756             :     {
     757         488 :         p_sepobj_fx[n] = &data_separated_objects_fx[n][0];
     758             :     }
     759             : 
     760             :     /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
     761         122 :     IF( st_ivas->hSpatParamRendCom->slots_rendered == 0 )
     762             :     {
     763             :         Word16 tcBufferSize;
     764             : 
     765         108 :         tcBufferSize = imult1616( st_ivas->hSpatParamRendCom->num_slots, st_ivas->hSpatParamRendCom->slot_size );
     766             : 
     767         540 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     768             :         {
     769         432 :             tc_local_fx[n] = st_ivas->hTcBuffer->tc_fx[n + 2]; // Q11
     770         432 :             v_multc_fixed_16( tc_local_fx[n], gain_fx, tc_local_fx[n], tcBufferSize );
     771             : 
     772         432 :             delay_signal32_fx( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size );
     773             :         }
     774             :     }
     775             : 
     776         122 :     ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_fx );
     777             : 
     778             :     /* reset combined orientation access index before calling the td renderer */
     779         122 :     ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
     780             : 
     781         122 :     IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
     782             :     {
     783           0 :         return error;
     784             :     }
     785             : 
     786         366 :     FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
     787             :     {
     788         244 :         v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
     789             :     }
     790             : 
     791         122 :     return IVAS_ERR_OK;
     792             : }
     793             : 
     794             : /*--------------------------------------------------------------------------*
     795             :  * ivas_omasa_rearrange_channels()
     796             :  *
     797             :  * in case of external rendering, rearrange the channels order
     798             :  *--------------------------------------------------------------------------*/
     799             : 
     800         603 : void ivas_omasa_rearrange_channels_fx(
     801             :     Word32 *output[],                 /* o  : output synthesis signal         Q11*/
     802             :     const Word16 nchan_transport_ism, /* o  : number of ISM TCs               */
     803             :     const Word16 output_frame         /* i  : output frame length per channel */
     804             : )
     805             : {
     806             :     Word16 n;
     807             :     Word32 tmp_buff[CPE_CHANNELS][L_FRAME48k]; // Q11
     808             : 
     809         603 :     Copy32( output[0], tmp_buff[0], output_frame );
     810         603 :     Copy32( output[1], tmp_buff[1], output_frame );
     811             : 
     812        2115 :     FOR( n = 0; n < nchan_transport_ism; n++ )
     813             :     {
     814        1512 :         Copy32( output[CPE_CHANNELS + n], output[n], output_frame );
     815             :     }
     816         603 :     Copy32( tmp_buff[0], output[n], output_frame );
     817         603 :     Copy32( tmp_buff[1], output[add( n, 1 )], output_frame );
     818             : 
     819         603 :     return;
     820             : }

Generated by: LCOV version 1.14