LCOV - code coverage report
Current view: top level - lib_rend - ivas_omasa_ana.c (source / functions) Hit Total Coverage
Test: Coverage on main @ fec202a8f89be4a2f278a9fc377bfb58b58fab11 Lines: 189 196 96.4 %
Date: 2025-09-11 08:49:05 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include "options.h"
      34             : #include <stdlib.h>
      35             : #include <math.h>
      36             : #include "ivas_cnst.h"
      37             : #include "ivas_prot_rend.h"
      38             : #include "ivas_prot.h"
      39             : #include "prot.h"
      40             : #include "ivas_stat_rend.h"
      41             : #include "ivas_rom_com.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Local function prototypes
      50             :  *------------------------------------------------------------------------*/
      51             : 
      52             : static void ivas_omasa_param_est_ana( OMASA_ANA_HANDLE hOMasa, float data_f[][L_FRAME48k], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_ism );
      53             : 
      54             : static void ivas_omasa_dmx( float data_in_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, const float ism_azimuth[MAX_NUM_OBJECTS], const float ism_elevation[MAX_NUM_OBJECTS], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] );
      55             : 
      56             : 
      57             : /*--------------------------------------------------------------------------*
      58             :  * ivas_omasa_ana_open()
      59             :  *
      60             :  * Allocate and initialize OMASA handle
      61             :  *--------------------------------------------------------------------------*/
      62             : 
      63          36 : ivas_error ivas_omasa_ana_open(
      64             :     OMASA_ANA_HANDLE *hOMasaPtr, /* i/o: OMASA data handle pointer */
      65             :     int32_t input_Fs,            /* i  : Sampling frequency        */
      66             :     uint16_t total_num_objects   /* i  : Number of objects         */
      67             : )
      68             : {
      69             :     int16_t i, j;
      70             :     OMASA_ANA_HANDLE hOMasa;
      71             :     int16_t numAnalysisChannels;
      72             :     int16_t maxBin, input_frame;
      73             :     ivas_error error;
      74             : 
      75          36 :     error = IVAS_ERR_OK;
      76             : 
      77          36 :     if ( ( hOMasa = (OMASA_ANA_HANDLE) malloc( sizeof( OMASA_ANA_DATA ) ) ) == NULL )
      78             :     {
      79           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA\n" ) );
      80             :     }
      81             : 
      82          36 :     numAnalysisChannels = (int16_t) total_num_objects;
      83             : 
      84             :     /* Determine the number of bands */
      85          36 :     hOMasa->nbands = MASA_FREQUENCY_BANDS;
      86             : 
      87             :     /* Determine band grouping */
      88          36 :     mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
      89             : 
      90          36 :     maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
      91         864 :     for ( i = 1; i < hOMasa->nbands + 1; i++ )
      92             :     {
      93         864 :         if ( hOMasa->band_grouping[i] >= maxBin )
      94             :         {
      95          36 :             hOMasa->band_grouping[i] = maxBin;
      96          36 :             hOMasa->nbands = i;
      97          36 :             break;
      98             :         }
      99             :     }
     100             : 
     101             :     /* Determine block grouping */
     102          36 :     mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     103             : 
     104             :     /* open/initialize CLDFB */
     105          36 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
     106         132 :     for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
     107             :     {
     108          96 :         if ( ( error = openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
     109             :         {
     110           0 :             return error;
     111             :         }
     112             :     }
     113             : 
     114          84 :     for ( ; i < MAX_NUM_OBJECTS; i++ )
     115             :     {
     116          48 :         hOMasa->cldfbAnaEnc[i] = NULL;
     117             :     }
     118             : 
     119             :     /* intensity 3-dim */
     120         144 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     121             :     {
     122         108 :         if ( ( hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ) ) == NULL )
     123             :         {
     124           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     125             :         }
     126             : 
     127         540 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     128             :         {
     129         432 :             if ( ( hOMasa->direction_vector_m[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
     130             :             {
     131           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     132             :             }
     133         432 :             set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
     134             :         }
     135             :     }
     136             : 
     137         144 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     138             :     {
     139        3564 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     140             :         {
     141        3456 :             if ( ( hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL )
     142             :             {
     143           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     144             :             }
     145        3456 :             set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
     146             :         }
     147             :     }
     148             : 
     149          36 :     set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     150             : 
     151         180 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
     152             :     {
     153         144 :         set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
     154             :     }
     155             : 
     156          36 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
     157       34596 :     for ( i = 0; i < input_frame; i++ )
     158             :     {
     159       34560 :         hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
     160             :     }
     161             : 
     162          36 :     hOMasa->index_buffer_intensity = 0;
     163             : 
     164          36 :     if ( ( hOMasa->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     165             :     {
     166           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     167             :     }
     168             : 
     169          36 :     if ( ( hOMasa->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     170             :     {
     171           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     172             :     }
     173          36 :     generate_gridEq( hOMasa->sph_grid16 );
     174             : 
     175         180 :     for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     176             :     {
     177         144 :         set_zero( hOMasa->energy[i], MASA_FREQUENCY_BANDS );
     178             :     }
     179             : 
     180          36 :     set_zero( hOMasa->ism_azimuth, MAX_NUM_OBJECTS );
     181          36 :     set_zero( hOMasa->ism_elevation, MAX_NUM_OBJECTS );
     182             : 
     183          36 :     ( *hOMasaPtr ) = hOMasa;
     184             : 
     185          36 :     return error;
     186             : }
     187             : 
     188             : 
     189             : /*--------------------------------------------------------------------------*
     190             :  * ivas_omasa_ana_close()
     191             :  *
     192             :  * Close OMASA handle
     193             :  *--------------------------------------------------------------------------*/
     194             : 
     195       33528 : void ivas_omasa_ana_close(
     196             :     OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
     197             : )
     198             : {
     199             :     int16_t i, j;
     200             : 
     201       33528 :     if ( hOMasa == NULL || *hOMasa == NULL )
     202             :     {
     203       33492 :         return;
     204             :     }
     205             : 
     206         132 :     for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     207             :     {
     208          96 :         deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     209             :     }
     210             : 
     211         144 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     212             :     {
     213         540 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     214             :         {
     215         432 :             free( ( *hOMasa )->direction_vector_m[i][j] );
     216         432 :             ( *hOMasa )->direction_vector_m[i][j] = NULL;
     217             :         }
     218             : 
     219        3564 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     220             :         {
     221        3456 :             free( ( *hOMasa )->buffer_intensity_real[i][j] );
     222        3456 :             ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
     223             :         }
     224             : 
     225         108 :         free( ( *hOMasa )->direction_vector_m[i] );
     226         108 :         ( *hOMasa )->direction_vector_m[i] = NULL;
     227             :     }
     228             : 
     229          36 :     free( ( *hOMasa )->hMasaOut );
     230          36 :     ( *hOMasa )->hMasaOut = NULL;
     231          36 :     free( ( *hOMasa )->sph_grid16 );
     232          36 :     ( *hOMasa )->sph_grid16 = NULL;
     233             : 
     234          36 :     free( ( *hOMasa ) );
     235          36 :     ( *hOMasa ) = NULL;
     236             : 
     237          36 :     return;
     238             : }
     239             : 
     240             : 
     241             : /*--------------------------------------------------------------------------*
     242             :  * ivas_omasa_ana()
     243             :  *
     244             :  * OMASA analysis function
     245             :  *--------------------------------------------------------------------------*/
     246             : 
     247        7836 : void ivas_omasa_ana(
     248             :     OMASA_ANA_HANDLE hOMasa,       /* i/o: OMASA analysis handle                       */
     249             :     float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals             */
     250             :     const int16_t input_frame,     /* i  : Input frame size                            */
     251             :     const int16_t nchan_transport, /* i  : Number of transport channels                */
     252             :     const int16_t nchan_ism        /* i  : Number of objects for parameter analysis    */
     253             : )
     254             : {
     255             :     float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     256             :     float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     257             :     float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     258             :     float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     259             :     float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     260             : 
     261             :     /* Estimate MASA parameters from the objects */
     262        7836 :     ivas_omasa_param_est_ana( hOMasa, data_in_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_ism );
     263             : 
     264             :     /* Create MASA metadata buffer from the estimated values */
     265        7836 :     ivas_create_masa_out_meta( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence );
     266             : 
     267             :     /* Downmix */
     268        7836 :     ivas_omasa_dmx( data_in_f, input_frame, nchan_transport, nchan_ism, hOMasa->ism_azimuth, hOMasa->ism_elevation, hOMasa->prev_object_dm_gains, hOMasa->interpolator );
     269             : 
     270        7836 :     return;
     271             : }
     272             : 
     273             : 
     274             : /*--------------------------------------------------------------------------*
     275             :  * Local functions
     276             :  *--------------------------------------------------------------------------*/
     277             : 
     278             : /* Estimate MASA parameters from the objects */
     279        7836 : static void ivas_omasa_param_est_ana(
     280             :     OMASA_ANA_HANDLE hOMasa,
     281             :     float data_f[][L_FRAME48k],
     282             :     float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     283             :     float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     284             :     float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     285             :     float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     286             :     float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     287             :     const int16_t input_frame,
     288             :     const int16_t nchan_ism )
     289             : {
     290             :     float reference_power[MASA_FREQUENCY_BANDS];
     291             :     int16_t ts, i, d, j;
     292             :     int16_t num_freq_bins, num_freq_bands, index;
     293             :     float dir_v[DIRAC_NUM_DIMS];
     294             :     int16_t l_ts;
     295             :     float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     296             :     float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     297             :     float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     298             :     float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     299             :     float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     300             :     float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     301             :     float diffuseness_vector[MASA_FREQUENCY_BANDS];
     302             :     float diffuseness_m[MASA_FREQUENCY_BANDS];
     303             : 
     304             :     int16_t band_m_idx, block_m_idx;
     305             :     float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
     306             :     float norm_tmp;
     307             :     int16_t mrange[2];
     308             :     int16_t brange[2];
     309             : 
     310        7836 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     311        7836 :     num_freq_bands = hOMasa->nbands;
     312        7836 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
     313             : 
     314             : 
     315             :     /* Compute ISM to FOA matrices */
     316       28332 :     for ( i = 0; i < nchan_ism; i++ )
     317             :     {
     318       20496 :         hOMasa->chnlToFoaMtx[0][i] = 1.0f;
     319       20496 :         hOMasa->chnlToFoaMtx[1][i] = sinf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
     320       20496 :         hOMasa->chnlToFoaMtx[2][i] = sinf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
     321       20496 :         hOMasa->chnlToFoaMtx[3][i] = cosf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
     322             :     }
     323             : 
     324             :     /* do processing over all CLDFB time slots */
     325       39180 :     for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     326             :     {
     327       31344 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     328       31344 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     329             : 
     330      783600 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     331             :         {
     332      752256 :             hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
     333      752256 :             hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
     334      752256 :             hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
     335             :         }
     336             : 
     337             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     338       31344 :         set_zero( renormalization_factor_diff, hOMasa->nbands );
     339       31344 :         set_zero( diffuseness_m, hOMasa->nbands );
     340       31344 :         set_zero( hOMasa->energy[block_m_idx], MASA_FREQUENCY_BANDS );
     341             : 
     342      156720 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
     343             :         {
     344      453312 :             for ( i = 0; i < nchan_ism; i++ )
     345             :             {
     346      327936 :                 cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
     347             :             }
     348             : 
     349             :             /* Compute channel-based energy for metadata processing */
     350     3134400 :             for ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     351             :             {
     352     3009024 :                 brange[0] = hOMasa->band_grouping[band_m_idx];
     353     3009024 :                 brange[1] = hOMasa->band_grouping[band_m_idx + 1];
     354    10531584 :                 for ( j = brange[0]; j < brange[1]; j++ )
     355             :                 {
     356    27198720 :                     for ( i = 0; i < nchan_ism; i++ )
     357             :                     {
     358    19676160 :                         hOMasa->energy[block_m_idx][band_m_idx] += Chnl_RealBuffer[i][j] * Chnl_RealBuffer[i][j] + Chnl_ImagBuffer[i][j] * Chnl_ImagBuffer[i][j];
     359             :                     }
     360             :                 }
     361             :             }
     362             : 
     363             :             /* Compute FOA */
     364             :             /* W */
     365      125376 :             mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     366      125376 :             mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     367      327936 :             for ( i = 1; i < nchan_ism; i++ )
     368             :             {
     369      202560 :                 v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     370      202560 :                 v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     371             :             }
     372             : 
     373             :             /* Y */
     374      125376 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
     375      125376 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
     376      327936 :             for ( i = 1; i < nchan_ism; i++ )
     377             :             {
     378      202560 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
     379      202560 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
     380             :             }
     381             : 
     382             :             /* Z */
     383      125376 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
     384      125376 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
     385      327936 :             for ( i = 1; i < nchan_ism; i++ )
     386             :             {
     387      202560 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
     388      202560 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
     389             :             }
     390             : 
     391             :             /* X */
     392      125376 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
     393      125376 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
     394      327936 :             for ( i = 1; i < nchan_ism; i++ )
     395             :             {
     396      202560 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
     397      202560 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
     398             :             }
     399             : 
     400             :             /* Direction estimation */
     401      125376 :             computeIntensityVector_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
     402      125376 :             computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
     403             : 
     404             :             /* Power estimation for diffuseness */
     405      125376 :             computeReferencePower_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power, num_freq_bands );
     406             : 
     407             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     408      125376 :             hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
     409      125376 :             index = hOMasa->index_buffer_intensity;
     410      501504 :             for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     411             :             {
     412             :                 /* only real part needed */
     413      376128 :                 mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
     414             :             }
     415      125376 :             mvr2r( reference_power, &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     416             : 
     417      125376 :             computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
     418             : 
     419     3134400 :             for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     420             :             {
     421     3009024 :                 norm_tmp = reference_power[band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
     422             : 
     423     3009024 :                 hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
     424     3009024 :                 hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
     425     3009024 :                 hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
     426             : 
     427     3009024 :                 diffuseness_m[band_m_idx] += reference_power[band_m_idx] * diffuseness_vector[band_m_idx];
     428     3009024 :                 renormalization_factor_diff[band_m_idx] += reference_power[band_m_idx];
     429             :             }
     430             :         }
     431             : 
     432      783600 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     433             :         {
     434     3009024 :             for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
     435             :             {
     436     2256768 :                 dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
     437             :             }
     438      752256 :             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] );
     439             :         }
     440             : 
     441             :         /* Determine energy ratios */
     442      783600 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     443             :         {
     444      752256 :             if ( renormalization_factor_diff[band_m_idx] > EPSILON )
     445             :             {
     446      751392 :                 diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
     447             :             }
     448             :             else
     449             :             {
     450         864 :                 diffuseness_m[band_m_idx] = 0.0f;
     451             :             }
     452             : 
     453      752256 :             energyRatio[block_m_idx][band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
     454             :         }
     455             : 
     456             :         /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
     457      783600 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     458             :         {
     459      752256 :             spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
     460      752256 :             surroundingCoherence[block_m_idx][band_m_idx] = 0.0f;
     461             :         }
     462             :     }
     463             : 
     464        7836 :     return;
     465             : }
     466             : 
     467             : 
     468             : /* Compute downmix */
     469        7836 : static void ivas_omasa_dmx(
     470             :     float data_in_f[][L_FRAME48k],
     471             :     const int16_t input_frame,
     472             :     const int16_t nchan_transport,
     473             :     const int16_t nchan_ism,
     474             :     const float ism_azimuth[MAX_NUM_OBJECTS],
     475             :     const float ism_elevation[MAX_NUM_OBJECTS],
     476             :     float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
     477             :     const float interpolator[L_FRAME48k] )
     478             : {
     479             :     int16_t i, j, k;
     480             :     float azimuth, elevation;
     481             :     float gains[MASA_MAX_TRANSPORT_CHANNELS];
     482             :     float g1, g2;
     483             :     float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     484             : 
     485       19590 :     for ( i = 0; i < nchan_transport; i++ )
     486             :     {
     487       11754 :         set_zero( data_out_f[i], input_frame );
     488             :     }
     489             : 
     490       28332 :     for ( i = 0; i < nchan_ism; i++ )
     491             :     {
     492       20496 :         if ( nchan_transport == 1 )
     493             :         {
     494       10248 :             v_add( data_out_f[0], data_in_f[i], data_out_f[0], input_frame );
     495             :         }
     496             :         else
     497             :         {
     498       10248 :             azimuth = ism_azimuth[i];
     499       10248 :             elevation = ism_elevation[i];
     500             : 
     501       10248 :             ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] );
     502             : 
     503             :             /* Downmix using the panning gains */
     504       30744 :             for ( j = 0; j < nchan_transport; j++ )
     505             :             {
     506       20496 :                 if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
     507             :                 {
     508    17298000 :                     for ( k = 0; k < input_frame; k++ )
     509             :                     {
     510    17280000 :                         g1 = interpolator[k];
     511    17280000 :                         g2 = 1.0f - g1;
     512    17280000 :                         data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
     513             :                     }
     514             :                 }
     515       20496 :                 prev_gains[i][j] = gains[j];
     516             :             }
     517             :         }
     518             :     }
     519             : 
     520       19590 :     for ( i = 0; i < nchan_transport; i++ )
     521             :     {
     522       11754 :         mvr2r( data_out_f[i], data_in_f[i], input_frame );
     523             :     }
     524             : 
     525        7836 :     return;
     526             : }
     527             : 
     528             : 
     529             : /*--------------------------------------------------------------------------*
     530             :  * computeIntensityVector_ana()
     531             :  *
     532             :  *
     533             :  *--------------------------------------------------------------------------*/
     534             : 
     535      154368 : void computeIntensityVector_ana(
     536             :     const int16_t *band_grouping,                                /* i  : Band grouping for estimation    */
     537             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       */
     538             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       */
     539             :     const int16_t num_frequency_bands,                           /* i  : Number of frequency bands       */
     540             :     float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]   /* o  : Intensity vector                */
     541             : )
     542             : {
     543             :     /* Reminder
     544             :      * X = a + ib; Y = c + id
     545             :      * X*Y = ac - bd + i(ad +bc)
     546             :      */
     547             :     int16_t i, j;
     548             :     float real, img;
     549             :     int16_t brange[2];
     550             : 
     551     3859200 :     for ( i = 0; i < num_frequency_bands; i++ )
     552             :     {
     553     3704832 :         brange[0] = band_grouping[i];
     554     3704832 :         brange[1] = band_grouping[i + 1];
     555             : 
     556     3704832 :         intensity_real[0][i] = 0;
     557     3704832 :         intensity_real[1][i] = 0;
     558     3704832 :         intensity_real[2][i] = 0;
     559             : 
     560    12966912 :         for ( j = brange[0]; j < brange[1]; j++ )
     561             :         {
     562     9262080 :             real = Cldfb_RealBuffer[0][j];
     563     9262080 :             img = Cldfb_ImagBuffer[0][j];
     564     9262080 :             intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
     565     9262080 :             intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
     566     9262080 :             intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
     567             :         }
     568             :     }
     569             : 
     570      154368 :     return;
     571             : }
     572             : 
     573             : 
     574             : /*--------------------------------------------------------------------------*
     575             :  * computeReferencePower_ana()
     576             :  *
     577             :  *
     578             :  *--------------------------------------------------------------------------*/
     579             : 
     580      144704 : void computeReferencePower_ana(
     581             :     const int16_t *band_grouping,                                /* i  : Band grouping for estimation    */
     582             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       */
     583             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       */
     584             :     float *reference_power,                                      /* o  : Estimated power                 */
     585             :     const int16_t num_freq_bands                                 /* i  : Number of frequency bands       */
     586             : )
     587             : {
     588             :     int16_t brange[2];
     589             :     int16_t ch_idx, i, j;
     590             : 
     591     3617600 :     for ( i = 0; i < num_freq_bands; i++ )
     592             :     {
     593     3472896 :         brange[0] = band_grouping[i];
     594     3472896 :         brange[1] = band_grouping[i + 1];
     595     3472896 :         reference_power[i] = 0;
     596             : 
     597    17364480 :         for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
     598             :         {
     599             :             /* abs()^2 */
     600    48620544 :             for ( j = brange[0]; j < brange[1]; j++ )
     601             :             {
     602    34728960 :                 reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
     603             :             }
     604             :         }
     605             :     }
     606             : 
     607      144704 :     v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
     608             : 
     609      144704 :     return;
     610             : }

Generated by: LCOV version 1.14