LCOV - code coverage report
Current view: top level - lib_enc - ivas_omasa_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 380 396 96.0 %
Date: 2025-05-23 08:37:30 Functions: 13 13 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 "ivas_prot.h"
      39             : #include "prot.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_enc.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Local constants
      50             :  *------------------------------------------------------------------------*/
      51             : 
      52             : #define OMASA_FEC_MAX 5
      53             : 
      54             : /*-------------------------------------------------------------------------
      55             :  * Local function prototypes
      56             :  *------------------------------------------------------------------------*/
      57             : 
      58             : static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, ISM_METADATA_HANDLE hIsmMeta[], float *data_f[], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MASA_FREQUENCY_BANDS], float diffuseness_m[MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp );
      59             : 
      60             : static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, float *data_f[], const int16_t input_frame, const int16_t nchan_inp );
      61             : 
      62             : static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] );
      63             : 
      64             : static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
      65             : 
      66             : static void computeReferencePower_omasa( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float *reference_power, const int16_t enc_param_start_band, const int16_t num_freq_bands );
      67             : 
      68             : /*--------------------------------------------------------------------------*
      69             :  * ivas_omasa_enc_open()
      70             :  *
      71             :  * Allocate and initialize OMASA handle
      72             :  *--------------------------------------------------------------------------*/
      73             : 
      74         464 : ivas_error ivas_omasa_enc_open(
      75             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
      76             : )
      77             : {
      78             :     int16_t i, j;
      79             :     OMASA_ENC_HANDLE hOMasa;
      80             :     int16_t numAnalysisChannels;
      81             :     int16_t input_frame;
      82             :     ivas_error error;
      83             : 
      84         464 :     error = IVAS_ERR_OK;
      85             : 
      86         464 :     assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
      87             : 
      88         464 :     if ( ( hOMasa = (OMASA_ENC_HANDLE) malloc( sizeof( OMASA_ENC_STATE ) ) ) == NULL )
      89             :     {
      90           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
      91             :     }
      92             : 
      93         464 :     numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
      94             : 
      95             :     /* open/initialize CLDFB */
      96         464 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
      97        1906 :     for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
      98             :     {
      99        1442 :         if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
     100             :         {
     101           0 :             return error;
     102             :         }
     103             :     }
     104             : 
     105             :     /* intensity 3-dim */
     106        1856 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     107             :     {
     108        1392 :         hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) );
     109             : 
     110        6960 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     111             :         {
     112        5568 :             if ( ( hOMasa->direction_vector_m[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
     113             :             {
     114           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     115             :             }
     116        5568 :             set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
     117             :         }
     118             :     }
     119             : 
     120        1856 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     121             :     {
     122       45936 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     123             :         {
     124       44544 :             if ( ( hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
     125             :             {
     126           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     127             :             }
     128       44544 :             set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
     129             :         }
     130             :     }
     131             : 
     132         464 :     set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     133             : 
     134        2320 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
     135             :     {
     136        1856 :         set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
     137             :     }
     138         464 :     set_zero( hOMasa->broadband_energy_sm, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     139         464 :     set_zero( hOMasa->broadband_energy_prev, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     140         464 :     hOMasa->prev_selected_object = 0;
     141         464 :     hOMasa->changing_object = 0;
     142         464 :     hOMasa->since_obj_change_cnt = 0;
     143             : 
     144         464 :     input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
     145      420304 :     for ( i = 0; i < input_frame; i++ )
     146             :     {
     147      419840 :         hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
     148      419840 :         hOMasa->fade_out_gain[i] = ( 1.0f + cosf( ( (float) i ) / ( (float) input_frame ) * EVS_PI ) ) / 2.0f;
     149      419840 :         hOMasa->fade_in_gain[i] = 1.0f - hOMasa->fade_out_gain[i];
     150             :     }
     151             : 
     152         464 :     hOMasa->index_buffer_intensity = 0;
     153             : 
     154         464 :     st_ivas->hOMasa = hOMasa;
     155             : 
     156         464 :     return error;
     157             : }
     158             : 
     159             : 
     160             : /*--------------------------------------------------------------------------*
     161             :  * ivas_omasa_enc_close()
     162             :  *
     163             :  * Close OMASA handle
     164             :  *--------------------------------------------------------------------------*/
     165             : 
     166        1066 : void ivas_omasa_enc_close(
     167             :     OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
     168             : )
     169             : {
     170             :     int16_t i, j;
     171             : 
     172        1066 :     if ( hOMasa == NULL || *hOMasa == NULL )
     173             :     {
     174         602 :         return;
     175             :     }
     176             : 
     177        1906 :     for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     178             :     {
     179        1442 :         deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     180             :     }
     181             : 
     182        1856 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     183             :     {
     184        6960 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     185             :         {
     186        5568 :             free( ( *hOMasa )->direction_vector_m[i][j] );
     187        5568 :             ( *hOMasa )->direction_vector_m[i][j] = NULL;
     188             :         }
     189             : 
     190       45936 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     191             :         {
     192       44544 :             free( ( *hOMasa )->buffer_intensity_real[i][j] );
     193       44544 :             ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
     194             :         }
     195             : 
     196        1392 :         free( ( *hOMasa )->direction_vector_m[i] );
     197        1392 :         ( *hOMasa )->direction_vector_m[i] = NULL;
     198             :     }
     199             : 
     200         464 :     free( *hOMasa );
     201         464 :     ( *hOMasa ) = NULL;
     202             : 
     203         464 :     return;
     204             : }
     205             : 
     206             : 
     207             : /*--------------------------------------------------------------------------*
     208             :  * ivas_omasa_enc_config()
     209             :  *
     210             :  * oMASA encoder configuration
     211             :  *--------------------------------------------------------------------------*/
     212             : 
     213        9000 : ivas_error ivas_omasa_enc_config(
     214             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
     215             : )
     216             : {
     217             :     int16_t k, sce_id, nSCE_old;
     218             :     int32_t ivas_total_brate, ism_total_brate;
     219             :     ENCODER_CONFIG_HANDLE hEncoderConfig;
     220             :     ivas_error error;
     221             : 
     222        9000 :     hEncoderConfig = st_ivas->hEncoderConfig;
     223        9000 :     ivas_total_brate = hEncoderConfig->ivas_total_brate;
     224        9000 :     nSCE_old = st_ivas->nSCE;
     225             : 
     226        9000 :     st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, hEncoderConfig->nchan_ism );
     227        9000 :     st_ivas->nchan_transport = 2;
     228             : 
     229             :     /* reconfiguration in case of bitrate switching */
     230        9000 :     if ( hEncoderConfig->last_ivas_total_brate != ivas_total_brate )
     231             :     {
     232        1634 :         ivas_set_omasa_TC( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
     233             : 
     234        1634 :         k = 0;
     235       12910 :         while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
     236             :         {
     237       11276 :             k++;
     238             :         }
     239             : 
     240        1634 :         ism_total_brate = 0;
     241        3746 :         for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
     242             :         {
     243        2112 :             ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
     244             :         }
     245             : 
     246        1634 :         if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     247             :         {
     248         403 :             if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     249             :             {
     250           0 :                 return error;
     251             :             }
     252             :         }
     253        1231 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
     254             :         {
     255         439 :             if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nSCE, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     256             :             {
     257           0 :                 return error;
     258             :             }
     259             :         }
     260             : 
     261             :         /* reconfigure core-coders for ISMs */
     262        1634 :         if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, 1, 2, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate, MC_MODE_NONE ) ) != IVAS_ERR_OK )
     263             :         {
     264           0 :             return error;
     265             :         }
     266             : 
     267             :         /* re-write IVAS format signalling - actual 'ism_mode' was not known before */
     268        1634 :         if ( st_ivas->nSCE > 0 )
     269             :         {
     270        1190 :             reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
     271             :         }
     272             :         else
     273             :         {
     274         444 :             reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
     275             :         }
     276             : 
     277        1634 :         ivas_write_format( st_ivas );
     278             : 
     279             :         /* OMASA encoder handle */
     280        1634 :         if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hOMasa == NULL )
     281             :         {
     282         437 :             if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
     283             :             {
     284           0 :                 return error;
     285             :             }
     286             :         }
     287        1197 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hOMasa != NULL )
     288             :         {
     289         439 :             ivas_omasa_enc_close( &( st_ivas->hOMasa ) );
     290         439 :             st_ivas->hOMasa = NULL;
     291             :         }
     292             : 
     293             :         /* OMASA energy handle */
     294        1634 :         if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy == NULL )
     295             :         {
     296         437 :             if ( ( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = (OMASA_ENCODER_ENERGY_HANDLE) malloc( sizeof( OMASA_ENCODER_ENERGY_STATE ) ) ) == NULL )
     297             :             {
     298           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA energy handle\n" ) );
     299             :             }
     300             :         }
     301        1197 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy != NULL )
     302             :         {
     303         439 :             free( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy );
     304         439 :             st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = NULL;
     305             :         }
     306             : 
     307        1634 :         st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
     308             : 
     309        1634 :         if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO )
     310             :         {
     311         709 :             hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     312             :         }
     313             :         else
     314             :         {
     315         925 :             hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
     316             :         }
     317             :     }
     318             : 
     319             :     /* Configure MASA encoder based on frame parameters */
     320        9000 :     if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
     321             :     {
     322           0 :         return error;
     323             :     }
     324             : 
     325        9000 :     if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
     326             :     {
     327             :         /* Configure oMASA analysis based on MASA config */
     328        5858 :         ivas_omasa_set_config( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
     329             :     }
     330             : 
     331        9000 :     return IVAS_ERR_OK;
     332             : }
     333             : 
     334             : 
     335             : /*--------------------------------------------------------------------------*
     336             :  * ivas_omasa_set_config()
     337             :  *
     338             :  * Frame-by-frame config for oMASA
     339             :  *--------------------------------------------------------------------------*/
     340             : 
     341        5858 : void ivas_omasa_set_config(
     342             :     OMASA_ENC_HANDLE hOMasa,   /* i/o: OMASA encoder handle */
     343             :     MASA_ENCODER_HANDLE hMasa, /* i  : MASA encoder handle  */
     344             :     const int32_t input_Fs,    /* i  : Input sample rate    */
     345             :     const ISM_MODE ism_mode    /* i  : ISM mode             */
     346             : )
     347             : {
     348             :     uint8_t i, maxBin;
     349             : 
     350             :     /* Determine the number of bands */
     351        5858 :     if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     352             :     {
     353             :         /* use full resolution for the ISM+MASA merge and reduce later */
     354        3996 :         hOMasa->nbands = 24;
     355             :     }
     356             :     else
     357             :     {
     358        1862 :         hOMasa->nbands = hMasa->config.numCodingBands;
     359             :     }
     360             : 
     361        5858 :     hOMasa->nCodingBands = hMasa->config.numCodingBands;
     362             : 
     363             :     /* Determine the number of subframes */
     364        5858 :     hOMasa->nSubframes = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
     365             : 
     366             :     /* Determine band grouping */
     367        5858 :     if ( hOMasa->nbands == 24 )
     368             :     {
     369        3996 :         mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
     370             :     }
     371             :     else
     372             :     {
     373       15680 :         for ( i = 0; i < hOMasa->nbands + 1; i++ )
     374             :         {
     375       13818 :             hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
     376             :         }
     377             :     }
     378             : 
     379        5858 :     maxBin = (uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
     380             : 
     381      106960 :     for ( i = 1; i < hOMasa->nbands + 1; i++ )
     382             :     {
     383      106960 :         if ( hOMasa->band_grouping[i] >= maxBin )
     384             :         {
     385        5858 :             hOMasa->band_grouping[i] = maxBin;
     386        5858 :             hOMasa->nbands = i;
     387        5858 :             break;
     388             :         }
     389             :     }
     390             : 
     391        5858 :     mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     392        5858 :     if ( hOMasa->nSubframes == 1 )
     393             :     {
     394        1426 :         hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
     395             :     }
     396             : 
     397        5858 :     return;
     398             : }
     399             : 
     400             : 
     401             : /*--------------------------------------------------------------------------*
     402             :  * ivas_omasa_enc()
     403             :  *
     404             :  * Main OMASA encoding function
     405             :  *--------------------------------------------------------------------------*/
     406             : 
     407        5858 : void ivas_omasa_enc(
     408             :     OMASA_ENC_HANDLE hOMasa,        /* i/o: OMASA encoder handle                        */
     409             :     MASA_ENCODER_HANDLE hMasa,      /* i/o: MASA encoder handle                         */
     410             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle                         */
     411             :     float *data_in_f[],             /* i/o: Input / transport audio signals             */
     412             :     const int16_t input_frame,      /* i  : Input frame size                            */
     413             :     const int16_t nchan_transport,  /* i  : Number of transport channels                */
     414             :     const int16_t nchan_ism,        /* i  : Number of objects for parameter analysis    */
     415             :     const ISM_MODE ism_mode,        /* i  : ISM mode                                    */
     416             :     float *data_separated_object,   /* o  : Separated object audio signal               */
     417             :     int16_t *idx_separated_object   /* o  : Index of the separated object               */
     418             : )
     419             : {
     420             :     int16_t i, j;
     421             :     float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     422             : 
     423             :     /* Determine separated object (when applicable) */
     424        5858 :     if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     425             :     {
     426             :         float broadband_energy[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
     427             :         int16_t loudest_object;
     428             :         int16_t selected_object;
     429             :         int16_t nchan_all_inp;
     430             :         float alpha;
     431             :         uint8_t fade_out_separate_object;
     432             :         uint8_t fade_in_separate_object;
     433             : 
     434             :         /* Estimate broadband energies */
     435        3916 :         nchan_all_inp = nchan_ism + nchan_transport;
     436        3916 :         set_zero( broadband_energy, nchan_all_inp );
     437       25272 :         for ( i = 0; i < nchan_all_inp; i++ )
     438             :         {
     439    19569516 :             for ( j = 0; j < input_frame; j++ )
     440             :             {
     441    19548160 :                 broadband_energy[i] += data_in_f[i][j] * data_in_f[i][j];
     442             :             }
     443             :         }
     444             : 
     445             :         /* Temporal averaging */
     446        3916 :         alpha = 0.8f;
     447       25272 :         for ( i = 0; i < nchan_all_inp; i++ )
     448             :         {
     449       21356 :             hOMasa->broadband_energy_sm[i] = ( 1.0f - alpha ) * broadband_energy[i] + alpha * hOMasa->broadband_energy_sm[i];
     450             :         }
     451             : 
     452             :         /* Determine loudest object */
     453        3916 :         loudest_object = 0;
     454       13524 :         for ( i = 1; i < nchan_ism; i++ )
     455             :         {
     456        9608 :             if ( hOMasa->broadband_energy_sm[i] > hOMasa->broadband_energy_sm[loudest_object] )
     457             :             {
     458        1998 :                 loudest_object = i;
     459             :             }
     460             :         }
     461             : 
     462             :         /* Determine object to separate */
     463        3916 :         selected_object = hOMasa->prev_selected_object;
     464        3916 :         fade_out_separate_object = 0;
     465        3916 :         fade_in_separate_object = 0;
     466        3916 :         if ( hOMasa->changing_object )
     467             :         {
     468         125 :             hOMasa->changing_object = 0;
     469         125 :             selected_object = loudest_object;
     470         125 :             fade_in_separate_object = 1;
     471             :         }
     472             :         else
     473             :         {
     474        3791 :             if ( loudest_object != hOMasa->prev_selected_object )
     475             :             {
     476             :                 float selected_ene;
     477             :                 float total_ene;
     478             :                 float selected_ratio;
     479             :                 float adaptive_threshold_dB;
     480             :                 float ratio_objects_dB;
     481         763 :                 float hardswitch_threshold = 0.25f;
     482             : 
     483             :                 /* Compute the energy of the current and the previous selected object in the current and the previous frame */
     484         763 :                 selected_ene = broadband_energy[loudest_object] + broadband_energy[hOMasa->prev_selected_object] + hOMasa->broadband_energy_prev[loudest_object] + hOMasa->broadband_energy_prev[hOMasa->prev_selected_object];
     485             : 
     486             :                 /* Compute the energy of all objects and MASA channels in the current and the previous frame */
     487         763 :                 total_ene = 0.0f;
     488        4917 :                 for ( i = 0; i < nchan_all_inp; i++ )
     489             :                 {
     490        4154 :                     total_ene += broadband_energy[i] + hOMasa->broadband_energy_prev[i];
     491             :                 }
     492             : 
     493             :                 /* Compute the ratio */
     494         763 :                 selected_ratio = selected_ene / ( total_ene + EPSILON );
     495             : 
     496         763 :                 adaptive_threshold_dB = selected_ratio * 9.0f + 1.0f; /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */
     497         763 :                 ratio_objects_dB = 10.0f * log10f( hOMasa->broadband_energy_sm[loudest_object] / ( hOMasa->broadband_energy_sm[hOMasa->prev_selected_object] + EPSILON ) );
     498             : 
     499             :                 /* Adaptively determine whether to change the separated object. If they are quiet compared to the total energy, change easier, as other signals mask the change. */
     500         763 :                 if ( ratio_objects_dB > adaptive_threshold_dB )
     501             :                 {
     502         184 :                     if ( selected_ratio < hardswitch_threshold ) /* If low level compared to all audio channels, perform hardswitch */
     503             :                     {
     504          53 :                         selected_object = loudest_object;
     505             :                     }
     506             :                     else /* If high level compared to all audio channels, perform switch via fade out fade in */
     507             :                     {
     508         131 :                         hOMasa->changing_object = 1;
     509         131 :                         fade_out_separate_object = 1;
     510             :                     }
     511             :                 }
     512             :             }
     513             :         }
     514             : 
     515             :         /* Set values for next frame */
     516       25272 :         for ( i = 0; i < nchan_all_inp; i++ )
     517             :         {
     518       21356 :             hOMasa->broadband_energy_prev[i] = broadband_energy[i];
     519             :         }
     520             : 
     521             :         /* force absolute MD coding in case of change of separated object */
     522        3916 :         if ( hOMasa->prev_selected_object != selected_object )
     523             :         {
     524         178 :             hOMasa->since_obj_change_cnt = 0;
     525         178 :             hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     526             :         }
     527             :         else
     528             :         {
     529        3738 :             hOMasa->since_obj_change_cnt++;
     530        3738 :             hOMasa->since_obj_change_cnt = min( OMASA_FEC_MAX, hOMasa->since_obj_change_cnt );
     531        3738 :             if ( hOMasa->since_obj_change_cnt < OMASA_FEC_MAX )
     532             :             {
     533        1293 :                 hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     534             :             }
     535             :         }
     536        3916 :         hOMasa->prev_selected_object = selected_object;
     537             : 
     538             :         /* Separate the selected object */
     539        3916 :         *idx_separated_object = selected_object;
     540        3916 :         mvr2r( data_in_f[selected_object], data_separated_object, input_frame );
     541        3916 :         if ( fade_out_separate_object )
     542             :         {
     543         131 :             v_mult( data_separated_object, hOMasa->fade_out_gain, data_separated_object, input_frame );
     544         131 :             v_mult( data_in_f[selected_object], hOMasa->fade_in_gain, data_in_f[selected_object], input_frame );
     545             :         }
     546        3785 :         else if ( fade_in_separate_object )
     547             :         {
     548         125 :             v_mult( data_separated_object, hOMasa->fade_in_gain, data_separated_object, input_frame );
     549         125 :             v_mult( data_in_f[selected_object], hOMasa->fade_out_gain, data_in_f[selected_object], input_frame );
     550             :         }
     551             :         else
     552             :         {
     553        3660 :             set_zero( data_in_f[selected_object], input_frame );
     554             :         }
     555             :     }
     556             : 
     557             :     /* Analysis */
     558        5858 :     if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     559        3996 :     {
     560             :         OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */
     561             :         OMASA_SPATIAL_META_HANDLE hOMasaMeta;
     562             :         uint8_t n_bands_orig, n_subframes_orig;
     563             :         uint8_t numCodingBands_orig, joinedSubframes_orig;
     564             : 
     565        3996 :         hOMasaMeta = &OMasaMeta;
     566        3996 :         hOMasaMeta->num_dirs = 1;
     567             : 
     568             :         /* merge MASA directions before adding ISM to the mixture */
     569        3996 :         if ( hMasa->config.numberOfDirections == 2 )
     570             :         {
     571        2198 :             n_bands_orig = hMasa->config.numCodingBands;
     572        2198 :             hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
     573             : 
     574        2198 :             ivas_masa_combine_directions( hMasa );
     575             : 
     576        2198 :             hMasa->config.numCodingBands = (int8_t) n_bands_orig;
     577             :         }
     578             : 
     579             :         /* force computation into high resolution */
     580             : 
     581        3996 :         n_subframes_orig = hOMasa->nSubframes;
     582        3996 :         hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
     583             : 
     584             :         /* Estimate MASA parameters from the objects */
     585             :         /* NB: only first direction is populated */
     586             :         /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */
     587        3996 :         ivas_omasa_param_est_enc( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in_f, hOMasaMeta->directional_meta[0].elevation, hOMasaMeta->directional_meta[0].azimuth, hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].spread_coherence, hOMasaMeta->common_meta.surround_coherence[0],
     588        3996 :                                   hOMasaMeta->common_meta.diffuse_to_total_ratio[0], input_frame, nchan_ism );
     589             : 
     590             :         /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */
     591       15984 :         for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     592             :         {
     593       11988 :             mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS );
     594       11988 :             mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS );
     595       11988 :             mvr2r( hOMasaMeta->common_meta.diffuse_to_total_ratio[0], hOMasaMeta->common_meta.diffuse_to_total_ratio[i], MASA_FREQUENCY_BANDS );
     596             :         }
     597             : 
     598             :         /* restore resolution parameters */
     599        3996 :         hOMasa->nSubframes = n_subframes_orig;
     600             : 
     601             :         /* perform MASA+ISM merge in full resolution */
     602        3996 :         numCodingBands_orig = hMasa->config.numCodingBands;
     603        3996 :         joinedSubframes_orig = hMasa->config.joinedSubframes;
     604             : 
     605        3996 :         hMasa->config.numCodingBands = hOMasa->nbands;
     606        3996 :         hMasa->config.joinedSubframes = 0;
     607             : 
     608        3996 :         ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
     609             : 
     610        3996 :         hMasa->config.numCodingBands = numCodingBands_orig;
     611        3996 :         hMasa->config.joinedSubframes = joinedSubframes_orig;
     612             :     }
     613        1862 :     else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     614             :     {
     615             :         /* Estimate energies and ratios */
     616        1862 :         ivas_omasa_energy_and_ratio_est( hOMasa, hMasa->data.hOmasaData, data_in_f, input_frame, nchan_ism );
     617             :     }
     618             : 
     619             :     /* Downmix */
     620        5858 :     ivas_omasa_dmx( data_in_f, data_out_f, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains, hOMasa->interpolator );
     621             : 
     622             :     /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */
     623        5858 :     if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     624             :     {
     625        2054 :         hIsmMeta[0]->azimuth = hIsmMeta[*idx_separated_object]->azimuth;
     626        2054 :         hIsmMeta[0]->elevation = hIsmMeta[*idx_separated_object]->elevation;
     627             :     }
     628             : 
     629             :     /* Merge transport signals */
     630        5858 :     ivas_merge_masa_transports( data_out_f, &( data_in_f[nchan_ism] ), data_in_f, input_frame, nchan_transport );
     631             : 
     632        5858 :     return;
     633             : }
     634             : 
     635             : 
     636             : /*-------------------------------------------------------------------------*
     637             :  * ivas_set_ism_importance_interformat()
     638             :  *
     639             :  * Set the importance of particular ISM streams in combined-format coding
     640             :  *-------------------------------------------------------------------------*/
     641             : 
     642        7058 : void ivas_set_ism_importance_interformat(
     643             :     const int32_t ism_total_brate,  /* i/o: ISms total bitrate                  */
     644             :     const int16_t nchan_transport,  /* i  : number of transported channels      */
     645             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles                */
     646             :     SCE_ENC_HANDLE hSCE[],          /* i/o: SCE encoder handles                 */
     647             :     const float lp_noise_CPE,       /* i  : LP filtered total noise estimation  */
     648             :     int16_t ism_imp[]               /* o  : ISM importance flags                */
     649             : )
     650             : {
     651             :     Encoder_State *st;
     652             :     int16_t ch, ctype, active_flag;
     653             : 
     654       19434 :     for ( ch = 0; ch < nchan_transport; ch++ )
     655             :     {
     656       12376 :         st = hSCE[ch]->hCoreCoder[0];
     657             : 
     658       12376 :         active_flag = st->vad_flag;
     659             : 
     660       12376 :         if ( active_flag == 0 )
     661             :         {
     662         272 :             if ( st->lp_noise > 15 || lp_noise_CPE - st->lp_noise < 30 )
     663             :             {
     664         272 :                 active_flag = 1;
     665             :             }
     666             :         }
     667             : 
     668             :         /* do not use the low-rate core-coder mode at highest bit-rates */
     669       12376 :         if ( ism_total_brate / nchan_transport > IVAS_48k )
     670             :         {
     671        1428 :             active_flag = 1;
     672             :         }
     673             : 
     674       12376 :         ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
     675             : 
     676       12376 :         st->low_rate_mode = 0;
     677       12376 :         if ( active_flag == 0 )
     678             :         {
     679           0 :             ism_imp[ch] = ISM_INACTIVE_IMP;
     680           0 :             st->low_rate_mode = 1;
     681             :         }
     682       12376 :         else if ( ctype == INACTIVE || ctype == UNVOICED )
     683             :         {
     684         449 :             ism_imp[ch] = ISM_LOW_IMP;
     685             :         }
     686       11927 :         else if ( ctype == VOICED )
     687             :         {
     688        3111 :             ism_imp[ch] = ISM_MEDIUM_IMP;
     689             :         }
     690             :         else /* GENERIC */
     691             :         {
     692        8816 :             ism_imp[ch] = ISM_HIGH_IMP;
     693             :         }
     694             : 
     695       12376 :         hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
     696             :     }
     697             : 
     698        7058 :     return;
     699             : }
     700             : 
     701             : 
     702             : /*--------------------------------------------------------------------------*
     703             :  * ivas_set_surplus_brate_enc()
     704             :  *
     705             :  * set bit-rate surplus in combined format coding
     706             :  *--------------------------------------------------------------------------*/
     707             : 
     708        9000 : void ivas_set_surplus_brate_enc(
     709             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure  */
     710             : #ifdef DEBUG_MODE_INFO
     711             :     ,
     712             :     const int16_t *nb_bits_metadata /* i  : number of metadata bits */
     713             : #endif
     714             : )
     715             : {
     716        9000 :     if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     717             :     {
     718        1862 :         st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
     719             :         /* note: ISM st->total_brate is iset in ivas_sce_enc() */
     720             :     }
     721        7138 :     else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     722             :     {
     723             :         /* it is already set in ivas_ism_enc() */
     724             :     }
     725             :     else
     726             :     {
     727        1942 :         st_ivas->hCPE[0]->brate_surplus = 0;
     728             :     }
     729             : 
     730             : #ifdef DEBUG_MODE_INFO
     731             :     if ( st_ivas->hSCE[0] != NULL )
     732             :     {
     733             :         int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
     734             :         float tmpF = 0;
     735             : 
     736             :         if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     737             :         {
     738             :             tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 );
     739             :         }
     740             :         else
     741             :         {
     742             :             for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
     743             :             {
     744             :                 tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 );
     745             :             }
     746             :         }
     747             :         tmpF /= 1000.f;
     748             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */
     749             :         tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF;
     750             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */
     751             :         tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f;
     752             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */
     753             :     }
     754             : #endif
     755             : 
     756        9000 :     return;
     757             : }
     758             : 
     759             : 
     760             : /*--------------------------------------------------------------------------*
     761             :  * ivas_omasa_ener_brate()
     762             :  *
     763             :  *
     764             :  *--------------------------------------------------------------------------*/
     765             : 
     766             : /*! r: OMASA energy bitrate flag */
     767        3142 : int16_t ivas_omasa_ener_brate(
     768             :     const int16_t nchan_ism,        /* i  : number of ISMs                   */
     769             :     const int32_t ivas_total_brate, /* i  : IVAS total bitrate               */
     770             :     float *data_f[],                /* i  : Input / transport audio signals  */
     771             :     const int16_t input_frame       /* i  : Input frame size                 */
     772             : )
     773             : {
     774             :     int16_t i, flag_omasa_ener_brate;
     775             :     float energy_ism, energy_masa;
     776             : 
     777        3142 :     flag_omasa_ener_brate = 0;
     778             : 
     779        3142 :     if ( nchan_ism >= 3 && ivas_total_brate == IVAS_128k )
     780             :     {
     781         126 :         energy_ism = 0.0f;
     782         570 :         for ( i = 0; i < nchan_ism; i++ )
     783             :         {
     784         444 :             energy_ism += sum2_f( data_f[i], input_frame );
     785             :         }
     786             : 
     787         126 :         energy_masa = 0.0f;
     788         378 :         for ( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
     789             :         {
     790         252 :             energy_masa += sum2_f( data_f[i], input_frame );
     791             :         }
     792             : 
     793         126 :         energy_ism = energy_ism / ( energy_masa + 1.0f ) * 2.0f / (float) ( nchan_ism );
     794             : 
     795         126 :         if ( energy_ism < 1.0f )
     796             :         {
     797          38 :             flag_omasa_ener_brate = 1;
     798             :         }
     799             :     }
     800             : 
     801        3142 :     return flag_omasa_ener_brate;
     802             : }
     803             : 
     804             : 
     805             : /*--------------------------------------------------------------------------*
     806             :  * Local functions
     807             :  *--------------------------------------------------------------------------*/
     808             : 
     809             : /* Estimate MASA parameters from the objects */
     810        3996 : static void ivas_omasa_param_est_enc(
     811             :     OMASA_ENC_HANDLE hOMasa,
     812             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
     813             :     ISM_METADATA_HANDLE hIsmMeta[],
     814             :     float *data_f[],
     815             :     float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     816             :     float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     817             :     float energyRatio[MASA_FREQUENCY_BANDS],
     818             :     float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     819             :     float surroundingCoherence[MASA_FREQUENCY_BANDS],
     820             :     float diffuseness_m[MASA_FREQUENCY_BANDS],
     821             :     const int16_t input_frame,
     822             :     const int16_t nchan_ism )
     823             : {
     824             :     float reference_power[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
     825             :     int16_t ts, i, j, d, k;
     826             :     int16_t num_freq_bins, num_freq_bands, index;
     827             :     float dir_v[DIRAC_NUM_DIMS];
     828             :     int16_t l_ts;
     829             :     float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
     830             :     float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
     831             :     float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     832             :     float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     833             :     float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     834             :     float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     835             :     float diffuseness_vector[MASA_FREQUENCY_BANDS];
     836             :     int16_t band_m_idx, block_m_idx;
     837             :     float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
     838             :     float norm_tmp;
     839             :     int16_t mrange[2], brange[2];
     840        3996 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
     841             : 
     842        3996 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     843        3996 :     num_freq_bands = hOMasa->nbands;
     844        3996 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
     845             : 
     846             :     /* Need to initialize renormalization_factors, and variables to be normalized */
     847        3996 :     set_zero( renormalization_factor_diff, hOMasa->nbands );
     848        3996 :     set_zero( diffuseness_m, hOMasa->nbands );
     849             : 
     850             :     /* Compute ISM to FOA matrices */
     851       17156 :     for ( i = 0; i < nchan_ism; i++ )
     852             :     {
     853       13160 :         hOMasa->chnlToFoaMtx[0][i] = 1.0f;
     854       13160 :         hOMasa->chnlToFoaMtx[1][i] = sinf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
     855       13160 :         hOMasa->chnlToFoaMtx[2][i] = sinf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
     856       13160 :         hOMasa->chnlToFoaMtx[3][i] = cosf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
     857             :     }
     858             : 
     859             :     /* do processing over all CLDFB time slots */
     860       19980 :     for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
     861             :     {
     862       15984 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     863       15984 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     864             : 
     865      396000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     866             :         {
     867      380016 :             hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
     868      380016 :             hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
     869      380016 :             hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
     870             :         }
     871             : 
     872       15984 :         set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
     873             : 
     874       88304 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
     875             :         {
     876      311616 :             for ( i = 0; i < nchan_ism; i++ )
     877             :             {
     878      239296 :                 cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
     879             :             }
     880             : 
     881             :             /* Compute energy */
     882     1792416 :             for ( i = 0; i < num_freq_bands; i++ )
     883             :             {
     884     1720096 :                 brange[0] = hOMasa->band_grouping[i];
     885     1720096 :                 brange[1] = hOMasa->band_grouping[i + 1];
     886     5843616 :                 for ( j = brange[0]; j < brange[1]; j++ )
     887             :                 {
     888    17930240 :                     for ( k = 0; k < nchan_ism; k++ )
     889             :                     {
     890    13806720 :                         hOmasaEnergy->energy_ism[block_m_idx][i] += Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
     891             :                     }
     892             :                 }
     893             :             }
     894             : 
     895             :             /* Compute FOA */
     896             :             /* W */
     897       72320 :             mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     898       72320 :             mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     899      239296 :             for ( i = 1; i < nchan_ism; i++ )
     900             :             {
     901      166976 :                 v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     902      166976 :                 v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     903             :             }
     904             : 
     905             :             /* Y */
     906       72320 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
     907       72320 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
     908      239296 :             for ( i = 1; i < nchan_ism; i++ )
     909             :             {
     910      166976 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
     911      166976 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
     912             :             }
     913             : 
     914             :             /* Z */
     915       72320 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
     916       72320 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
     917      239296 :             for ( i = 1; i < nchan_ism; i++ )
     918             :             {
     919      166976 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
     920      166976 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
     921             :             }
     922             : 
     923             :             /* X */
     924       72320 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
     925       72320 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
     926      239296 :             for ( i = 1; i < nchan_ism; i++ )
     927             :             {
     928      166976 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
     929      166976 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
     930             :             }
     931             : 
     932             :             /* Direction estimation */
     933       72320 :             computeIntensityVector_enc( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
     934       72320 :             computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
     935             : 
     936             :             /* Power estimation for diffuseness */
     937       72320 :             computeReferencePower_omasa( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], 0, num_freq_bands );
     938             : 
     939             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     940       72320 :             hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
     941       72320 :             index = hOMasa->index_buffer_intensity;
     942      289280 :             for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     943             :             {
     944             :                 /* only real part needed */
     945      216960 :                 mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
     946             :             }
     947       72320 :             mvr2r( reference_power[ts], &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     948             : 
     949       72320 :             computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
     950             : 
     951     1792416 :             for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     952             :             {
     953     1720096 :                 norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
     954             : 
     955     1720096 :                 hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
     956     1720096 :                 hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
     957     1720096 :                 hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
     958             : 
     959     1720096 :                 diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
     960     1720096 :                 renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx];
     961             :             }
     962             :         }
     963             : 
     964      396000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     965             :         {
     966     1520064 :             for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
     967             :             {
     968     1140048 :                 dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
     969             :             }
     970             : 
     971      380016 :             ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] );
     972             :         }
     973             : 
     974             :         /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
     975      396000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     976             :         {
     977      380016 :             spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
     978      380016 :             surroundingCoherence[band_m_idx] = 0.0f;
     979             :         }
     980             :     }
     981             : 
     982             :     /* Determine energy ratios */
     983       99000 :     for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     984             :     {
     985       95004 :         if ( renormalization_factor_diff[band_m_idx] > EPSILON )
     986             :         {
     987       95004 :             diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
     988             :         }
     989             :         else
     990             :         {
     991           0 :             diffuseness_m[band_m_idx] = 0.0f;
     992             :         }
     993             : 
     994       95004 :         energyRatio[band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
     995             :     }
     996             : 
     997        3996 :     return;
     998             : }
     999             : 
    1000             : 
    1001             : /* Estimate energies and ratios */
    1002        1862 : static void ivas_omasa_energy_and_ratio_est(
    1003             :     OMASA_ENC_HANDLE hOMasa,
    1004             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
    1005             :     float *data_f[],
    1006             :     const int16_t input_frame,
    1007             :     const int16_t nchan_ism )
    1008             : {
    1009             :     int16_t ts, i, j, k;
    1010             :     int16_t num_freq_bands;
    1011             :     int16_t l_ts;
    1012             :     float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
    1013             :     float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
    1014             :     int16_t block_m_idx;
    1015             :     int16_t mrange[2], brange[2];
    1016             :     float tftile_energy;
    1017             :     float ism_ratio_sum;
    1018        1862 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
    1019             : 
    1020        1862 :     num_freq_bands = hOMasa->nbands;
    1021        1862 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
    1022             : 
    1023             :     /* do processing over all CLDFB time slots */
    1024        8176 :     for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
    1025             :     {
    1026        6314 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
    1027        6314 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
    1028             : 
    1029             :         /* Reset variable */
    1030       40530 :         for ( i = 0; i < hOMasa->nbands; i++ )
    1031             :         {
    1032       34216 :             set_zero( hOmasaEnergy->energy_ratio_ism[block_m_idx][i], nchan_ism );
    1033             :         }
    1034        6314 :         set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
    1035             : 
    1036             :         /* Compute CLDFB */
    1037       36106 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
    1038             :         {
    1039      130272 :             for ( i = 0; i < nchan_ism; i++ )
    1040             :             {
    1041      100480 :                 cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
    1042             :             }
    1043             : 
    1044             :             /* Compute energy */
    1045      221088 :             for ( i = 0; i < num_freq_bands; i++ )
    1046             :             {
    1047      191296 :                 brange[0] = hOMasa->band_grouping[i];
    1048      191296 :                 brange[1] = hOMasa->band_grouping[i + 1];
    1049     1835456 :                 for ( j = brange[0]; j < brange[1]; j++ )
    1050             :                 {
    1051     7242880 :                     for ( k = 0; k < nchan_ism; k++ )
    1052             :                     {
    1053     5598720 :                         tftile_energy = Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
    1054     5598720 :                         hOmasaEnergy->energy_ism[block_m_idx][i] += tftile_energy;
    1055     5598720 :                         hOmasaEnergy->energy_ratio_ism[block_m_idx][i][k] += tftile_energy;
    1056             :                     }
    1057             :                 }
    1058             :             }
    1059             :         }
    1060             : 
    1061             :         /* Compute ISM energy ratios */
    1062       40530 :         for ( i = 0; i < num_freq_bands; i++ )
    1063             :         {
    1064       34216 :             ism_ratio_sum = 0.0f;
    1065      148936 :             for ( j = 0; j < nchan_ism; j++ )
    1066             :             {
    1067      114720 :                 hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] /= ( hOmasaEnergy->energy_ism[block_m_idx][i] + EPSILON );
    1068      114720 :                 ism_ratio_sum += hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j];
    1069             :             }
    1070             : 
    1071       34216 :             if ( ism_ratio_sum == 0.0f )
    1072             :             {
    1073           0 :                 float temp_ism_ratio = 1.0f / ( (float) nchan_ism );
    1074           0 :                 for ( j = 0; j < nchan_ism; j++ )
    1075             :                 {
    1076           0 :                     hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] = temp_ism_ratio;
    1077             :                 }
    1078             :             }
    1079             :         }
    1080             :     }
    1081             : 
    1082        1862 :     return;
    1083             : }
    1084             : 
    1085             : 
    1086             : /* Compute downmix */
    1087        5858 : static void ivas_omasa_dmx(
    1088             :     float *data_in_f[],
    1089             :     float data_out_f[][L_FRAME48k],
    1090             :     const int16_t input_frame,
    1091             :     const int16_t nchan_transport,
    1092             :     const int16_t nchan_ism,
    1093             :     ISM_METADATA_HANDLE hIsmMeta[],
    1094             :     float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
    1095             :     const float interpolator[L_FRAME48k] )
    1096             : {
    1097             :     int16_t i, j, k;
    1098             :     float azimuth, elevation;
    1099             :     float gains[MASA_MAX_TRANSPORT_CHANNELS];
    1100             :     float g1, g2;
    1101             : 
    1102       17574 :     for ( i = 0; i < nchan_transport; i++ )
    1103             :     {
    1104       11716 :         set_zero( data_out_f[i], input_frame );
    1105             :     }
    1106             : 
    1107       25298 :     for ( i = 0; i < nchan_ism; i++ )
    1108             :     {
    1109       19440 :         azimuth = hIsmMeta[i]->azimuth;
    1110       19440 :         elevation = hIsmMeta[i]->elevation;
    1111             : 
    1112       19440 :         ivas_get_stereo_panning_gains( azimuth, elevation, gains );
    1113             : 
    1114             :         /* Downmix using the panning gains */
    1115       58320 :         for ( j = 0; j < nchan_transport; j++ )
    1116             :         {
    1117       38880 :             if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
    1118             :             {
    1119    32614184 :                 for ( k = 0; k < input_frame; k++ )
    1120             :                 {
    1121    32578560 :                     g1 = interpolator[k];
    1122    32578560 :                     g2 = 1.0f - g1;
    1123    32578560 :                     data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
    1124             :                 }
    1125             :             }
    1126       38880 :             prev_gains[i][j] = gains[j];
    1127             :         }
    1128             :     }
    1129             : 
    1130        5858 :     return;
    1131             : }
    1132             : 
    1133             : 
    1134       72320 : static void computeIntensityVector_enc(
    1135             :     const int16_t *band_grouping,
    1136             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
    1137             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
    1138             :     const int16_t num_frequency_bands,
    1139             :     float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
    1140             : {
    1141             :     /* Reminder
    1142             :      * X = a + ib; Y = c + id
    1143             :      * X*Y = ac - bd + i(ad +bc)
    1144             :      */
    1145             :     int16_t i, j;
    1146             :     float real, img;
    1147             :     int16_t brange[2];
    1148             : 
    1149     1792416 :     for ( i = 0; i < num_frequency_bands; i++ )
    1150             :     {
    1151     1720096 :         brange[0] = band_grouping[i];
    1152     1720096 :         brange[1] = band_grouping[i + 1];
    1153             : 
    1154     1720096 :         intensity_real[0][i] = 0;
    1155     1720096 :         intensity_real[1][i] = 0;
    1156     1720096 :         intensity_real[2][i] = 0;
    1157             : 
    1158     5843616 :         for ( j = brange[0]; j < brange[1]; j++ )
    1159             :         {
    1160     4123520 :             real = Cldfb_RealBuffer[0][j];
    1161     4123520 :             img = Cldfb_ImagBuffer[0][j];
    1162     4123520 :             intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
    1163     4123520 :             intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
    1164     4123520 :             intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
    1165             :         }
    1166             :     }
    1167             : 
    1168       72320 :     return;
    1169             : }
    1170             : 
    1171             : 
    1172       72320 : static void computeReferencePower_omasa(
    1173             :     const int16_t *band_grouping,                                /* i  : Band grouping for estimation    */
    1174             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       */
    1175             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       */
    1176             :     float *reference_power,                                      /* o  : Estimated power                 */
    1177             :     const int16_t enc_param_start_band,                          /* i  : first band to process           */
    1178             :     const int16_t num_freq_bands                                 /* i  : Number of frequency bands       */
    1179             : )
    1180             : {
    1181             :     int16_t brange[2];
    1182             :     int16_t ch_idx, i, j;
    1183             : 
    1184     1792416 :     for ( i = 0; i < num_freq_bands; i++ )
    1185             :     {
    1186     1720096 :         brange[0] = band_grouping[i + enc_param_start_band];
    1187     1720096 :         brange[1] = band_grouping[i + enc_param_start_band + 1];
    1188     1720096 :         reference_power[i] = 0;
    1189             : 
    1190     8600480 :         for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
    1191             :         {
    1192             :             /* abs()^2 */
    1193    23374464 :             for ( j = brange[0]; j < brange[1]; j++ )
    1194             :             {
    1195    16494080 :                 reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
    1196             :             }
    1197             :         }
    1198             :     }
    1199             : 
    1200       72320 :     v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
    1201             : 
    1202       72320 :     return;
    1203             : }

Generated by: LCOV version 1.14