LCOV - code coverage report
Current view: top level - lib_enc - ivas_omasa_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 386 396 97.5 %
Date: 2025-05-28 04:28:20 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       13912 : 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       13912 :     error = IVAS_ERR_OK;
      85             : 
      86       13912 :     assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
      87             : 
      88       13912 :     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       13912 :     numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
      94             : 
      95             :     /* open/initialize CLDFB */
      96       13912 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
      97       55928 :     for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
      98             :     {
      99       42016 :         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       55648 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     107             :     {
     108       41736 :         hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) );
     109             : 
     110      208680 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     111             :         {
     112      166944 :             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      166944 :             set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
     117             :         }
     118             :     }
     119             : 
     120       55648 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     121             :     {
     122     1377288 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     123             :         {
     124     1335552 :             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     1335552 :             set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
     129             :         }
     130             :     }
     131             : 
     132       13912 :     set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     133             : 
     134       69560 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
     135             :     {
     136       55648 :         set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
     137             :     }
     138       13912 :     set_zero( hOMasa->broadband_energy_sm, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     139       13912 :     set_zero( hOMasa->broadband_energy_prev, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     140       13912 :     hOMasa->prev_selected_object = 0;
     141       13912 :     hOMasa->changing_object = 0;
     142       13912 :     hOMasa->since_obj_change_cnt = 0;
     143             : 
     144       13912 :     input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
     145    12806872 :     for ( i = 0; i < input_frame; i++ )
     146             :     {
     147    12792960 :         hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
     148    12792960 :         hOMasa->fade_out_gain[i] = ( 1.0f + cosf( ( (float) i ) / ( (float) input_frame ) * EVS_PI ) ) / 2.0f;
     149    12792960 :         hOMasa->fade_in_gain[i] = 1.0f - hOMasa->fade_out_gain[i];
     150             :     }
     151             : 
     152       13912 :     hOMasa->index_buffer_intensity = 0;
     153             : 
     154       13912 :     st_ivas->hOMasa = hOMasa;
     155             : 
     156       13912 :     return error;
     157             : }
     158             : 
     159             : 
     160             : /*--------------------------------------------------------------------------*
     161             :  * ivas_omasa_enc_close()
     162             :  *
     163             :  * Close OMASA handle
     164             :  *--------------------------------------------------------------------------*/
     165             : 
     166       17975 : void ivas_omasa_enc_close(
     167             :     OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
     168             : )
     169             : {
     170             :     int16_t i, j;
     171             : 
     172       17975 :     if ( hOMasa == NULL || *hOMasa == NULL )
     173             :     {
     174        4063 :         return;
     175             :     }
     176             : 
     177       55928 :     for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     178             :     {
     179       42016 :         deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     180             :     }
     181             : 
     182       55648 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     183             :     {
     184      208680 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     185             :         {
     186      166944 :             free( ( *hOMasa )->direction_vector_m[i][j] );
     187      166944 :             ( *hOMasa )->direction_vector_m[i][j] = NULL;
     188             :         }
     189             : 
     190     1377288 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     191             :         {
     192     1335552 :             free( ( *hOMasa )->buffer_intensity_real[i][j] );
     193     1335552 :             ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
     194             :         }
     195             : 
     196       41736 :         free( ( *hOMasa )->direction_vector_m[i] );
     197       41736 :         ( *hOMasa )->direction_vector_m[i] = NULL;
     198             :     }
     199             : 
     200       13912 :     free( *hOMasa );
     201       13912 :     ( *hOMasa ) = NULL;
     202             : 
     203       13912 :     return;
     204             : }
     205             : 
     206             : 
     207             : /*--------------------------------------------------------------------------*
     208             :  * ivas_omasa_enc_config()
     209             :  *
     210             :  * oMASA encoder configuration
     211             :  *--------------------------------------------------------------------------*/
     212             : 
     213      290550 : 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      290550 :     hEncoderConfig = st_ivas->hEncoderConfig;
     223      290550 :     ivas_total_brate = hEncoderConfig->ivas_total_brate;
     224      290550 :     nSCE_old = st_ivas->nSCE;
     225             : 
     226      290550 :     st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, hEncoderConfig->nchan_ism );
     227      290550 :     st_ivas->nchan_transport = 2;
     228             : 
     229             :     /* reconfiguration in case of bitrate switching */
     230      290550 :     if ( hEncoderConfig->last_ivas_total_brate != ivas_total_brate )
     231             :     {
     232       49690 :         ivas_set_omasa_TC( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
     233             : 
     234       49690 :         k = 0;
     235      394623 :         while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
     236             :         {
     237      344933 :             k++;
     238             :         }
     239             : 
     240       49690 :         ism_total_brate = 0;
     241      113396 :         for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
     242             :         {
     243       63706 :             ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
     244             :         }
     245             : 
     246       49690 :         if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     247             :         {
     248       12150 :             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       37540 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
     254             :         {
     255       13730 :             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       49690 :         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       49690 :         if ( st_ivas->nSCE > 0 )
     269             :         {
     270       35974 :             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       13716 :             reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
     275             :         }
     276             : 
     277       49690 :         ivas_write_format( st_ivas );
     278             : 
     279             :         /* OMASA encoder handle */
     280       49690 :         if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hOMasa == NULL )
     281             :         {
     282       13704 :             if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
     283             :             {
     284           0 :                 return error;
     285             :             }
     286             :         }
     287       35986 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hOMasa != NULL )
     288             :         {
     289       13706 :             ivas_omasa_enc_close( &( st_ivas->hOMasa ) );
     290       13706 :             st_ivas->hOMasa = NULL;
     291             :         }
     292             : 
     293             :         /* OMASA energy handle */
     294       49690 :         if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy == NULL )
     295             :         {
     296       13704 :             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       35986 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy != NULL )
     302             :         {
     303       13706 :             free( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy );
     304       13706 :             st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = NULL;
     305             :         }
     306             : 
     307       49690 :         st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
     308             : 
     309       49690 :         if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO )
     310             :         {
     311       21449 :             hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     312             :         }
     313             :         else
     314             :         {
     315       28241 :             hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
     316             :         }
     317             :     }
     318             : 
     319             :     /* Configure MASA encoder based on frame parameters */
     320      290550 :     if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
     321             :     {
     322           0 :         return error;
     323             :     }
     324             : 
     325      290550 :     if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
     326             :     {
     327             :         /* Configure oMASA analysis based on MASA config */
     328      190738 :         ivas_omasa_set_config( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
     329             :     }
     330             : 
     331      290550 :     return IVAS_ERR_OK;
     332             : }
     333             : 
     334             : 
     335             : /*--------------------------------------------------------------------------*
     336             :  * ivas_omasa_set_config()
     337             :  *
     338             :  * Frame-by-frame config for oMASA
     339             :  *--------------------------------------------------------------------------*/
     340             : 
     341      190738 : 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      190738 :     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      127126 :         hOMasa->nbands = 24;
     355             :     }
     356             :     else
     357             :     {
     358       63612 :         hOMasa->nbands = hMasa->config.numCodingBands;
     359             :     }
     360             : 
     361      190738 :     hOMasa->nCodingBands = hMasa->config.numCodingBands;
     362             : 
     363             :     /* Determine the number of subframes */
     364      190738 :     hOMasa->nSubframes = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
     365             : 
     366             :     /* Determine band grouping */
     367      190738 :     if ( hOMasa->nbands == 24 )
     368             :     {
     369      127126 :         mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
     370             :     }
     371             :     else
     372             :     {
     373      598010 :         for ( i = 0; i < hOMasa->nbands + 1; i++ )
     374             :         {
     375      534398 :             hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
     376             :         }
     377             :     }
     378             : 
     379      190738 :     maxBin = (uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
     380             : 
     381     3482610 :     for ( i = 1; i < hOMasa->nbands + 1; i++ )
     382             :     {
     383     3482610 :         if ( hOMasa->band_grouping[i] >= maxBin )
     384             :         {
     385      190738 :             hOMasa->band_grouping[i] = maxBin;
     386      190738 :             hOMasa->nbands = i;
     387      190738 :             break;
     388             :         }
     389             :     }
     390             : 
     391      190738 :     mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     392      190738 :     if ( hOMasa->nSubframes == 1 )
     393             :     {
     394       78511 :         hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
     395             :     }
     396             : 
     397      190738 :     return;
     398             : }
     399             : 
     400             : 
     401             : /*--------------------------------------------------------------------------*
     402             :  * ivas_omasa_enc()
     403             :  *
     404             :  * Main OMASA encoding function
     405             :  *--------------------------------------------------------------------------*/
     406             : 
     407      190738 : 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      190738 :     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      128366 :         nchan_all_inp = nchan_ism + nchan_transport;
     436      128366 :         set_zero( broadband_energy, nchan_all_inp );
     437      826172 :         for ( i = 0; i < nchan_all_inp; i++ )
     438             :         {
     439   635653966 :             for ( j = 0; j < input_frame; j++ )
     440             :             {
     441   634956160 :                 broadband_energy[i] += data_in_f[i][j] * data_in_f[i][j];
     442             :             }
     443             :         }
     444             : 
     445             :         /* Temporal averaging */
     446      128366 :         alpha = 0.8f;
     447      826172 :         for ( i = 0; i < nchan_all_inp; i++ )
     448             :         {
     449      697806 :             hOMasa->broadband_energy_sm[i] = ( 1.0f - alpha ) * broadband_energy[i] + alpha * hOMasa->broadband_energy_sm[i];
     450             :         }
     451             : 
     452             :         /* Determine loudest object */
     453      128366 :         loudest_object = 0;
     454      441074 :         for ( i = 1; i < nchan_ism; i++ )
     455             :         {
     456      312708 :             if ( hOMasa->broadband_energy_sm[i] > hOMasa->broadband_energy_sm[loudest_object] )
     457             :             {
     458      133916 :                 loudest_object = i;
     459             :             }
     460             :         }
     461             : 
     462             :         /* Determine object to separate */
     463      128366 :         selected_object = hOMasa->prev_selected_object;
     464      128366 :         fade_out_separate_object = 0;
     465      128366 :         fade_in_separate_object = 0;
     466      128366 :         if ( hOMasa->changing_object )
     467             :         {
     468        5975 :             hOMasa->changing_object = 0;
     469        5975 :             selected_object = loudest_object;
     470        5975 :             fade_in_separate_object = 1;
     471             :         }
     472             :         else
     473             :         {
     474      122391 :             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       23271 :                 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       23271 :                 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       23271 :                 total_ene = 0.0f;
     488      151184 :                 for ( i = 0; i < nchan_all_inp; i++ )
     489             :                 {
     490      127913 :                     total_ene += broadband_energy[i] + hOMasa->broadband_energy_prev[i];
     491             :                 }
     492             : 
     493             :                 /* Compute the ratio */
     494       23271 :                 selected_ratio = selected_ene / ( total_ene + EPSILON );
     495             : 
     496       23271 :                 adaptive_threshold_dB = selected_ratio * 9.0f + 1.0f; /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */
     497       23271 :                 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       23271 :                 if ( ratio_objects_dB > adaptive_threshold_dB )
     501             :                 {
     502        7992 :                     if ( selected_ratio < hardswitch_threshold ) /* If low level compared to all audio channels, perform hardswitch */
     503             :                     {
     504        1968 :                         selected_object = loudest_object;
     505             :                     }
     506             :                     else /* If high level compared to all audio channels, perform switch via fade out fade in */
     507             :                     {
     508        6024 :                         hOMasa->changing_object = 1;
     509        6024 :                         fade_out_separate_object = 1;
     510             :                     }
     511             :                 }
     512             :             }
     513             :         }
     514             : 
     515             :         /* Set values for next frame */
     516      826172 :         for ( i = 0; i < nchan_all_inp; i++ )
     517             :         {
     518      697806 :             hOMasa->broadband_energy_prev[i] = broadband_energy[i];
     519             :         }
     520             : 
     521             :         /* force absolute MD coding in case of change of separated object */
     522      128366 :         if ( hOMasa->prev_selected_object != selected_object )
     523             :         {
     524        7939 :             hOMasa->since_obj_change_cnt = 0;
     525        7939 :             hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     526             :         }
     527             :         else
     528             :         {
     529      120427 :             hOMasa->since_obj_change_cnt++;
     530      120427 :             hOMasa->since_obj_change_cnt = min( OMASA_FEC_MAX, hOMasa->since_obj_change_cnt );
     531      120427 :             if ( hOMasa->since_obj_change_cnt < OMASA_FEC_MAX )
     532             :             {
     533       33127 :                 hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     534             :             }
     535             :         }
     536      128366 :         hOMasa->prev_selected_object = selected_object;
     537             : 
     538             :         /* Separate the selected object */
     539      128366 :         *idx_separated_object = selected_object;
     540      128366 :         mvr2r( data_in_f[selected_object], data_separated_object, input_frame );
     541      128366 :         if ( fade_out_separate_object )
     542             :         {
     543        6024 :             v_mult( data_separated_object, hOMasa->fade_out_gain, data_separated_object, input_frame );
     544        6024 :             v_mult( data_in_f[selected_object], hOMasa->fade_in_gain, data_in_f[selected_object], input_frame );
     545             :         }
     546      122342 :         else if ( fade_in_separate_object )
     547             :         {
     548        5975 :             v_mult( data_separated_object, hOMasa->fade_in_gain, data_separated_object, input_frame );
     549        5975 :             v_mult( data_in_f[selected_object], hOMasa->fade_out_gain, data_in_f[selected_object], input_frame );
     550             :         }
     551             :         else
     552             :         {
     553      116367 :             set_zero( data_in_f[selected_object], input_frame );
     554             :         }
     555             :     }
     556             : 
     557             :     /* Analysis */
     558      190738 :     if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     559      127126 :     {
     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      127126 :         hOMasaMeta = &OMasaMeta;
     566      127126 :         hOMasaMeta->num_dirs = 1;
     567             : 
     568             :         /* merge MASA directions before adding ISM to the mixture */
     569      127126 :         if ( hMasa->config.numberOfDirections == 2 )
     570             :         {
     571       60590 :             n_bands_orig = hMasa->config.numCodingBands;
     572       60590 :             hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
     573             : 
     574       60590 :             ivas_masa_combine_directions( hMasa );
     575             : 
     576       60590 :             hMasa->config.numCodingBands = (int8_t) n_bands_orig;
     577             :         }
     578             : 
     579             :         /* force computation into high resolution */
     580             : 
     581      127126 :         n_subframes_orig = hOMasa->nSubframes;
     582      127126 :         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      127126 :         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      127126 :                                   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      508504 :         for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     592             :         {
     593      381378 :             mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS );
     594      381378 :             mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS );
     595      381378 :             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      127126 :         hOMasa->nSubframes = n_subframes_orig;
     600             : 
     601             :         /* perform MASA+ISM merge in full resolution */
     602      127126 :         numCodingBands_orig = hMasa->config.numCodingBands;
     603      127126 :         joinedSubframes_orig = hMasa->config.joinedSubframes;
     604             : 
     605      127126 :         hMasa->config.numCodingBands = hOMasa->nbands;
     606      127126 :         hMasa->config.joinedSubframes = 0;
     607             : 
     608      127126 :         ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
     609             : 
     610      127126 :         hMasa->config.numCodingBands = numCodingBands_orig;
     611      127126 :         hMasa->config.joinedSubframes = joinedSubframes_orig;
     612             :     }
     613       63612 :     else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     614             :     {
     615             :         /* Estimate energies and ratios */
     616       63612 :         ivas_omasa_energy_and_ratio_est( hOMasa, hMasa->data.hOmasaData, data_in_f, input_frame, nchan_ism );
     617             :     }
     618             : 
     619             :     /* Downmix */
     620      190738 :     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      190738 :     if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     624             :     {
     625       64754 :         hIsmMeta[0]->azimuth = hIsmMeta[*idx_separated_object]->azimuth;
     626       64754 :         hIsmMeta[0]->elevation = hIsmMeta[*idx_separated_object]->elevation;
     627             :     }
     628             : 
     629             :     /* Merge transport signals */
     630      190738 :     ivas_merge_masa_transports( data_out_f, &( data_in_f[nchan_ism] ), data_in_f, input_frame, nchan_transport );
     631             : 
     632      190738 :     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      228178 : 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      635054 :     for ( ch = 0; ch < nchan_transport; ch++ )
     655             :     {
     656      406876 :         st = hSCE[ch]->hCoreCoder[0];
     657             : 
     658      406876 :         active_flag = st->vad_flag;
     659             : 
     660      406876 :         if ( active_flag == 0 )
     661             :         {
     662       97347 :             if ( st->lp_noise > 15 || lp_noise_CPE - st->lp_noise < 30 )
     663             :             {
     664       81978 :                 active_flag = 1;
     665             :             }
     666             :         }
     667             : 
     668             :         /* do not use the low-rate core-coder mode at highest bit-rates */
     669      406876 :         if ( ism_total_brate / nchan_transport > IVAS_48k )
     670             :         {
     671       44746 :             active_flag = 1;
     672             :         }
     673             : 
     674      406876 :         ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
     675             : 
     676      406876 :         st->low_rate_mode = 0;
     677      406876 :         if ( active_flag == 0 )
     678             :         {
     679       15337 :             ism_imp[ch] = ISM_INACTIVE_IMP;
     680       15337 :             st->low_rate_mode = 1;
     681             :         }
     682      391539 :         else if ( ctype == INACTIVE || ctype == UNVOICED )
     683             :         {
     684       35170 :             ism_imp[ch] = ISM_LOW_IMP;
     685             :         }
     686      356369 :         else if ( ctype == VOICED )
     687             :         {
     688       86502 :             ism_imp[ch] = ISM_MEDIUM_IMP;
     689             :         }
     690             :         else /* GENERIC */
     691             :         {
     692      269867 :             ism_imp[ch] = ISM_HIGH_IMP;
     693             :         }
     694             : 
     695      406876 :         hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
     696             :     }
     697             : 
     698      228178 :     return;
     699             : }
     700             : 
     701             : 
     702             : /*--------------------------------------------------------------------------*
     703             :  * ivas_set_surplus_brate_enc()
     704             :  *
     705             :  * set bit-rate surplus in combined format coding
     706             :  *--------------------------------------------------------------------------*/
     707             : 
     708      290550 : 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      290550 :     if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     717             :     {
     718       63612 :         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      226938 :     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       62372 :         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      290550 :     return;
     757             : }
     758             : 
     759             : 
     760             : /*--------------------------------------------------------------------------*
     761             :  * ivas_omasa_ener_brate()
     762             :  *
     763             :  *
     764             :  *--------------------------------------------------------------------------*/
     765             : 
     766             : /*! r: OMASA energy bitrate flag */
     767       99812 : 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       99812 :     flag_omasa_ener_brate = 0;
     778             : 
     779       99812 :     if ( nchan_ism >= 3 && ivas_total_brate == IVAS_128k )
     780             :     {
     781        3786 :         energy_ism = 0.0f;
     782       17274 :         for ( i = 0; i < nchan_ism; i++ )
     783             :         {
     784       13488 :             energy_ism += sum2_f( data_f[i], input_frame );
     785             :         }
     786             : 
     787        3786 :         energy_masa = 0.0f;
     788       11358 :         for ( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
     789             :         {
     790        7572 :             energy_masa += sum2_f( data_f[i], input_frame );
     791             :         }
     792             : 
     793        3786 :         energy_ism = energy_ism / ( energy_masa + 1.0f ) * 2.0f / (float) ( nchan_ism );
     794             : 
     795        3786 :         if ( energy_ism < 1.0f )
     796             :         {
     797        1374 :             flag_omasa_ener_brate = 1;
     798             :         }
     799             :     }
     800             : 
     801       99812 :     return flag_omasa_ener_brate;
     802             : }
     803             : 
     804             : 
     805             : /*--------------------------------------------------------------------------*
     806             :  * Local functions
     807             :  *--------------------------------------------------------------------------*/
     808             : 
     809             : /* Estimate MASA parameters from the objects */
     810      127126 : 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      127126 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
     841             : 
     842      127126 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     843      127126 :     num_freq_bands = hOMasa->nbands;
     844      127126 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
     845             : 
     846             :     /* Need to initialize renormalization_factors, and variables to be normalized */
     847      127126 :     set_zero( renormalization_factor_diff, hOMasa->nbands );
     848      127126 :     set_zero( diffuseness_m, hOMasa->nbands );
     849             : 
     850             :     /* Compute ISM to FOA matrices */
     851      537686 :     for ( i = 0; i < nchan_ism; i++ )
     852             :     {
     853      410560 :         hOMasa->chnlToFoaMtx[0][i] = 1.0f;
     854      410560 :         hOMasa->chnlToFoaMtx[1][i] = sinf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
     855      410560 :         hOMasa->chnlToFoaMtx[2][i] = sinf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
     856      410560 :         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      635630 :     for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
     861             :     {
     862      508504 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     863      508504 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     864             : 
     865    12555800 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     866             :         {
     867    12047296 :             hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
     868    12047296 :             hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
     869    12047296 :             hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
     870             :         }
     871             : 
     872      508504 :         set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
     873             : 
     874     2960336 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
     875             :         {
     876    10378560 :             for ( i = 0; i < nchan_ism; i++ )
     877             :             {
     878     7926728 :                 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    60568424 :             for ( i = 0; i < num_freq_bands; i++ )
     883             :             {
     884    58116592 :                 brange[0] = hOMasa->band_grouping[i];
     885    58116592 :                 brange[1] = hOMasa->band_grouping[i + 1];
     886   196469392 :                 for ( j = brange[0]; j < brange[1]; j++ )
     887             :                 {
     888   592681920 :                     for ( k = 0; k < nchan_ism; k++ )
     889             :                     {
     890   454329120 :                         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     2451832 :             mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     898     2451832 :             mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     899     7926728 :             for ( i = 1; i < nchan_ism; i++ )
     900             :             {
     901     5474896 :                 v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     902     5474896 :                 v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     903             :             }
     904             : 
     905             :             /* Y */
     906     2451832 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
     907     2451832 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
     908     7926728 :             for ( i = 1; i < nchan_ism; i++ )
     909             :             {
     910     5474896 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
     911     5474896 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
     912             :             }
     913             : 
     914             :             /* Z */
     915     2451832 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
     916     2451832 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
     917     7926728 :             for ( i = 1; i < nchan_ism; i++ )
     918             :             {
     919     5474896 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
     920     5474896 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
     921             :             }
     922             : 
     923             :             /* X */
     924     2451832 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
     925     2451832 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
     926     7926728 :             for ( i = 1; i < nchan_ism; i++ )
     927             :             {
     928     5474896 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
     929     5474896 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
     930             :             }
     931             : 
     932             :             /* Direction estimation */
     933     2451832 :             computeIntensityVector_enc( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
     934     2451832 :             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     2451832 :             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     2451832 :             hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
     941     2451832 :             index = hOMasa->index_buffer_intensity;
     942     9807328 :             for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     943             :             {
     944             :                 /* only real part needed */
     945     7355496 :                 mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
     946             :             }
     947     2451832 :             mvr2r( reference_power[ts], &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     948             : 
     949     2451832 :             computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
     950             : 
     951    60568424 :             for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     952             :             {
     953    58116592 :                 norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
     954             : 
     955    58116592 :                 hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
     956    58116592 :                 hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
     957    58116592 :                 hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
     958             : 
     959    58116592 :                 diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
     960    58116592 :                 renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx];
     961             :             }
     962             :         }
     963             : 
     964    12555800 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     965             :         {
     966    48189184 :             for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
     967             :             {
     968    36141888 :                 dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
     969             :             }
     970             : 
     971    12047296 :             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    12555800 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     976             :         {
     977    12047296 :             spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
     978    12047296 :             surroundingCoherence[band_m_idx] = 0.0f;
     979             :         }
     980             :     }
     981             : 
     982             :     /* Determine energy ratios */
     983     3138950 :     for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     984             :     {
     985     3011824 :         if ( renormalization_factor_diff[band_m_idx] > EPSILON )
     986             :         {
     987     2390500 :             diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
     988             :         }
     989             :         else
     990             :         {
     991      621324 :             diffuseness_m[band_m_idx] = 0.0f;
     992             :         }
     993             : 
     994     3011824 :         energyRatio[band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
     995             :     }
     996             : 
     997      127126 :     return;
     998             : }
     999             : 
    1000             : 
    1001             : /* Estimate energies and ratios */
    1002       63612 : 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       63612 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
    1019             : 
    1020       63612 :     num_freq_bands = hOMasa->nbands;
    1021       63612 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
    1022             : 
    1023             :     /* do processing over all CLDFB time slots */
    1024      239208 :     for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
    1025             :     {
    1026      175596 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
    1027      175596 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
    1028             : 
    1029             :         /* Reset variable */
    1030     1206302 :         for ( i = 0; i < hOMasa->nbands; i++ )
    1031             :         {
    1032     1030706 :             set_zero( hOmasaEnergy->energy_ratio_ism[block_m_idx][i], nchan_ism );
    1033             :         }
    1034      175596 :         set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands );
    1035             : 
    1036             :         /* Compute CLDFB */
    1037     1193388 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
    1038             :         {
    1039     4387872 :             for ( i = 0; i < nchan_ism; i++ )
    1040             :             {
    1041     3370080 :                 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     8550368 :             for ( i = 0; i < num_freq_bands; i++ )
    1046             :             {
    1047     7532576 :                 brange[0] = hOMasa->band_grouping[i];
    1048     7532576 :                 brange[1] = hOMasa->band_grouping[i + 1];
    1049    63080736 :                 for ( j = brange[0]; j < brange[1]; j++ )
    1050             :                 {
    1051   241002880 :                     for ( k = 0; k < nchan_ism; k++ )
    1052             :                     {
    1053   185454720 :                         tftile_energy = Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
    1054   185454720 :                         hOmasaEnergy->energy_ism[block_m_idx][i] += tftile_energy;
    1055   185454720 :                         hOmasaEnergy->energy_ratio_ism[block_m_idx][i][k] += tftile_energy;
    1056             :                     }
    1057             :                 }
    1058             :             }
    1059             :         }
    1060             : 
    1061             :         /* Compute ISM energy ratios */
    1062     1206302 :         for ( i = 0; i < num_freq_bands; i++ )
    1063             :         {
    1064     1030706 :             ism_ratio_sum = 0.0f;
    1065     4485686 :             for ( j = 0; j < nchan_ism; j++ )
    1066             :             {
    1067     3454980 :                 hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] /= ( hOmasaEnergy->energy_ism[block_m_idx][i] + EPSILON );
    1068     3454980 :                 ism_ratio_sum += hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j];
    1069             :             }
    1070             : 
    1071     1030706 :             if ( ism_ratio_sum == 0.0f )
    1072             :             {
    1073      327584 :                 float temp_ism_ratio = 1.0f / ( (float) nchan_ism );
    1074     1362576 :                 for ( j = 0; j < nchan_ism; j++ )
    1075             :                 {
    1076     1034992 :                     hOmasaEnergy->energy_ratio_ism[block_m_idx][i][j] = temp_ism_ratio;
    1077             :                 }
    1078             :             }
    1079             :         }
    1080             :     }
    1081             : 
    1082       63612 :     return;
    1083             : }
    1084             : 
    1085             : 
    1086             : /* Compute downmix */
    1087      190738 : 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      572214 :     for ( i = 0; i < nchan_transport; i++ )
    1103             :     {
    1104      381476 :         set_zero( data_out_f[i], input_frame );
    1105             :     }
    1106             : 
    1107      811928 :     for ( i = 0; i < nchan_ism; i++ )
    1108             :     {
    1109      621190 :         azimuth = hIsmMeta[i]->azimuth;
    1110      621190 :         elevation = hIsmMeta[i]->elevation;
    1111             : 
    1112      621190 :         ivas_get_stereo_panning_gains( azimuth, elevation, gains );
    1113             : 
    1114             :         /* Downmix using the panning gains */
    1115     1863570 :         for ( j = 0; j < nchan_transport; j++ )
    1116             :         {
    1117     1242380 :             if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
    1118             :             {
    1119   878949472 :                 for ( k = 0; k < input_frame; k++ )
    1120             :                 {
    1121   877977280 :                     g1 = interpolator[k];
    1122   877977280 :                     g2 = 1.0f - g1;
    1123   877977280 :                     data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
    1124             :                 }
    1125             :             }
    1126     1242380 :             prev_gains[i][j] = gains[j];
    1127             :         }
    1128             :     }
    1129             : 
    1130      190738 :     return;
    1131             : }
    1132             : 
    1133             : 
    1134     2451832 : 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    60568424 :     for ( i = 0; i < num_frequency_bands; i++ )
    1150             :     {
    1151    58116592 :         brange[0] = band_grouping[i];
    1152    58116592 :         brange[1] = band_grouping[i + 1];
    1153             : 
    1154    58116592 :         intensity_real[0][i] = 0;
    1155    58116592 :         intensity_real[1][i] = 0;
    1156    58116592 :         intensity_real[2][i] = 0;
    1157             : 
    1158   196469392 :         for ( j = brange[0]; j < brange[1]; j++ )
    1159             :         {
    1160   138352800 :             real = Cldfb_RealBuffer[0][j];
    1161   138352800 :             img = Cldfb_ImagBuffer[0][j];
    1162   138352800 :             intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
    1163   138352800 :             intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
    1164   138352800 :             intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
    1165             :         }
    1166             :     }
    1167             : 
    1168     2451832 :     return;
    1169             : }
    1170             : 
    1171             : 
    1172     2451832 : 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    60568424 :     for ( i = 0; i < num_freq_bands; i++ )
    1185             :     {
    1186    58116592 :         brange[0] = band_grouping[i + enc_param_start_band];
    1187    58116592 :         brange[1] = band_grouping[i + enc_param_start_band + 1];
    1188    58116592 :         reference_power[i] = 0;
    1189             : 
    1190   290582960 :         for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
    1191             :         {
    1192             :             /* abs()^2 */
    1193   785877568 :             for ( j = brange[0]; j < brange[1]; j++ )
    1194             :             {
    1195   553411200 :                 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     2451832 :     v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
    1201             : 
    1202     2451832 :     return;
    1203             : }

Generated by: LCOV version 1.14