LCOV - code coverage report
Current view: top level - lib_rend - ivas_omasa_ana.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 185 194 95.4 %
Date: 2025-05-23 08:37:30 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           2 : 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           2 :     error = IVAS_ERR_OK;
      76             : 
      77           2 :     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           2 :     numAnalysisChannels = (int16_t) total_num_objects;
      83             : 
      84             :     /* Determine the number of bands */
      85           2 :     hOMasa->nbands = MASA_FREQUENCY_BANDS;
      86             : 
      87             :     /* Determine band grouping */
      88           2 :     mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
      89             : 
      90           2 :     maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
      91          48 :     for ( i = 1; i < hOMasa->nbands + 1; i++ )
      92             :     {
      93          48 :         if ( hOMasa->band_grouping[i] >= maxBin )
      94             :         {
      95           2 :             hOMasa->band_grouping[i] = maxBin;
      96           2 :             hOMasa->nbands = i;
      97           2 :             break;
      98             :         }
      99             :     }
     100             : 
     101             :     /* Determine block grouping */
     102           2 :     mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     103             : 
     104             :     /* open/initialize CLDFB */
     105           2 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
     106          10 :     for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
     107             :     {
     108           8 :         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           2 :     for ( ; i < MAX_NUM_OBJECTS; i++ )
     115             :     {
     116           0 :         hOMasa->cldfbAnaEnc[i] = NULL;
     117             :     }
     118             : 
     119             :     /* intensity 3-dim */
     120           8 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     121             :     {
     122           6 :         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          30 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     128             :         {
     129          24 :             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          24 :             set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
     134             :         }
     135             :     }
     136             : 
     137           8 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     138             :     {
     139         198 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     140             :         {
     141         192 :             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         192 :             set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
     146             :         }
     147             :     }
     148             : 
     149           2 :     set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     150             : 
     151          10 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
     152             :     {
     153           8 :         set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS );
     154             :     }
     155             : 
     156           2 :     input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
     157        1922 :     for ( i = 0; i < input_frame; i++ )
     158             :     {
     159        1920 :         hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
     160             :     }
     161             : 
     162           2 :     hOMasa->index_buffer_intensity = 0;
     163             : 
     164           2 :     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           2 :     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           2 :     generate_gridEq( hOMasa->sph_grid16 );
     174             : 
     175          10 :     for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     176             :     {
     177           8 :         set_zero( hOMasa->energy[i], MASA_FREQUENCY_BANDS );
     178             :     }
     179             : 
     180           2 :     set_zero( hOMasa->ism_azimuth, MAX_NUM_OBJECTS );
     181           2 :     set_zero( hOMasa->ism_elevation, MAX_NUM_OBJECTS );
     182             : 
     183           2 :     ( *hOMasaPtr ) = hOMasa;
     184             : 
     185           2 :     return error;
     186             : }
     187             : 
     188             : 
     189             : /*--------------------------------------------------------------------------*
     190             :  * ivas_omasa_ana_close()
     191             :  *
     192             :  * Close OMASA handle
     193             :  *--------------------------------------------------------------------------*/
     194             : 
     195        5264 : void ivas_omasa_ana_close(
     196             :     OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
     197             : )
     198             : {
     199             :     int16_t i, j;
     200             : 
     201        5264 :     if ( hOMasa == NULL || *hOMasa == NULL )
     202             :     {
     203        5262 :         return;
     204             :     }
     205             : 
     206          10 :     for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     207             :     {
     208           8 :         deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     209             :     }
     210             : 
     211           8 :     for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     212             :     {
     213          30 :         for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     214             :         {
     215          24 :             free( ( *hOMasa )->direction_vector_m[i][j] );
     216          24 :             ( *hOMasa )->direction_vector_m[i][j] = NULL;
     217             :         }
     218             : 
     219         198 :         for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     220             :         {
     221         192 :             free( ( *hOMasa )->buffer_intensity_real[i][j] );
     222         192 :             ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
     223             :         }
     224             : 
     225           6 :         free( ( *hOMasa )->direction_vector_m[i] );
     226           6 :         ( *hOMasa )->direction_vector_m[i] = NULL;
     227             :     }
     228             : 
     229           2 :     free( ( *hOMasa )->hMasaOut );
     230           2 :     ( *hOMasa )->hMasaOut = NULL;
     231           2 :     free( ( *hOMasa )->sph_grid16 );
     232           2 :     ( *hOMasa )->sph_grid16 = NULL;
     233             : 
     234           2 :     free( ( *hOMasa ) );
     235           2 :     ( *hOMasa ) = NULL;
     236             : 
     237           2 :     return;
     238             : }
     239             : 
     240             : 
     241             : /*--------------------------------------------------------------------------*
     242             :  * ivas_omasa_ana()
     243             :  *
     244             :  * OMASA analysis function
     245             :  *--------------------------------------------------------------------------*/
     246             : 
     247         300 : 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         300 :     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         300 :     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         300 :     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         300 :     return;
     271             : }
     272             : 
     273             : 
     274             : /*--------------------------------------------------------------------------*
     275             :  * Local functions
     276             :  *--------------------------------------------------------------------------*/
     277             : 
     278             : /* Estimate MASA parameters from the objects */
     279         300 : 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         300 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     311         300 :     num_freq_bands = hOMasa->nbands;
     312         300 :     l_ts = input_frame / CLDFB_NO_COL_MAX;
     313             : 
     314             : 
     315             :     /* Compute ISM to FOA matrices */
     316        1500 :     for ( i = 0; i < nchan_ism; i++ )
     317             :     {
     318        1200 :         hOMasa->chnlToFoaMtx[0][i] = 1.0f;
     319        1200 :         hOMasa->chnlToFoaMtx[1][i] = sinf( ( hOMasa->ism_azimuth[i] / 180.0f * EVS_PI ) ) * cosf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
     320        1200 :         hOMasa->chnlToFoaMtx[2][i] = sinf( ( hOMasa->ism_elevation[i] / 180.0f * EVS_PI ) );
     321        1200 :         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        1500 :     for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     326             :     {
     327        1200 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     328        1200 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     329             : 
     330       30000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     331             :         {
     332       28800 :             hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
     333       28800 :             hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
     334       28800 :             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        1200 :         set_zero( renormalization_factor_diff, hOMasa->nbands );
     339        1200 :         set_zero( diffuseness_m, hOMasa->nbands );
     340        1200 :         set_zero( hOMasa->energy[block_m_idx], MASA_FREQUENCY_BANDS );
     341             : 
     342        6000 :         for ( ts = mrange[0]; ts < mrange[1]; ts++ )
     343             :         {
     344       24000 :             for ( i = 0; i < nchan_ism; i++ )
     345             :             {
     346       19200 :                 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      120000 :             for ( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     351             :             {
     352      115200 :                 brange[0] = hOMasa->band_grouping[band_m_idx];
     353      115200 :                 brange[1] = hOMasa->band_grouping[band_m_idx + 1];
     354      403200 :                 for ( j = brange[0]; j < brange[1]; j++ )
     355             :                 {
     356     1440000 :                     for ( i = 0; i < nchan_ism; i++ )
     357             :                     {
     358     1152000 :                         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        4800 :             mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     366        4800 :             mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     367       19200 :             for ( i = 1; i < nchan_ism; i++ )
     368             :             {
     369       14400 :                 v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
     370       14400 :                 v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
     371             :             }
     372             : 
     373             :             /* Y */
     374        4800 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
     375        4800 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
     376       19200 :             for ( i = 1; i < nchan_ism; i++ )
     377             :             {
     378       14400 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
     379       14400 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
     380             :             }
     381             : 
     382             :             /* Z */
     383        4800 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
     384        4800 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
     385       19200 :             for ( i = 1; i < nchan_ism; i++ )
     386             :             {
     387       14400 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
     388       14400 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
     389             :             }
     390             : 
     391             :             /* X */
     392        4800 :             v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
     393        4800 :             v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
     394       19200 :             for ( i = 1; i < nchan_ism; i++ )
     395             :             {
     396       14400 :                 v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
     397       14400 :                 v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
     398             :             }
     399             : 
     400             :             /* Direction estimation */
     401        4800 :             computeIntensityVector_ana( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
     402        4800 :             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        4800 :             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        4800 :             hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
     409        4800 :             index = hOMasa->index_buffer_intensity;
     410       19200 :             for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
     411             :             {
     412             :                 /* only real part needed */
     413       14400 :                 mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
     414             :             }
     415        4800 :             mvr2r( reference_power, &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     416             : 
     417        4800 :             computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
     418             : 
     419      120000 :             for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     420             :             {
     421      115200 :                 norm_tmp = reference_power[band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
     422             : 
     423      115200 :                 hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
     424      115200 :                 hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
     425      115200 :                 hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
     426             : 
     427      115200 :                 diffuseness_m[band_m_idx] += reference_power[band_m_idx] * diffuseness_vector[band_m_idx];
     428      115200 :                 renormalization_factor_diff[band_m_idx] += reference_power[band_m_idx];
     429             :             }
     430             :         }
     431             : 
     432       30000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     433             :         {
     434      115200 :             for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
     435             :             {
     436       86400 :                 dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
     437             :             }
     438       28800 :             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       30000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     443             :         {
     444       28800 :             if ( renormalization_factor_diff[band_m_idx] > EPSILON )
     445             :             {
     446       28800 :                 diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
     447             :             }
     448             :             else
     449             :             {
     450           0 :                 diffuseness_m[band_m_idx] = 0.0f;
     451             :             }
     452             : 
     453       28800 :             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       30000 :         for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     458             :         {
     459       28800 :             spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
     460       28800 :             surroundingCoherence[block_m_idx][band_m_idx] = 0.0f;
     461             :         }
     462             :     }
     463             : 
     464         300 :     return;
     465             : }
     466             : 
     467             : 
     468             : /* Compute downmix */
     469         300 : 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             : 
     486         900 :     for ( i = 0; i < nchan_transport; i++ )
     487             :     {
     488         600 :         set_zero( data_out_f[i], input_frame );
     489             :     }
     490             : 
     491        1500 :     for ( i = 0; i < nchan_ism; i++ )
     492             :     {
     493        1200 :         azimuth = ism_azimuth[i];
     494        1200 :         elevation = ism_elevation[i];
     495             : 
     496        1200 :         ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] );
     497             : 
     498             :         /* Downmix using the panning gains */
     499        3600 :         for ( j = 0; j < nchan_transport; j++ )
     500             :         {
     501        2400 :             if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
     502             :             {
     503     2121888 :                 for ( k = 0; k < input_frame; k++ )
     504             :                 {
     505     2119680 :                     g1 = interpolator[k];
     506     2119680 :                     g2 = 1.0f - g1;
     507     2119680 :                     data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
     508             :                 }
     509             :             }
     510        2400 :             prev_gains[i][j] = gains[j];
     511             :         }
     512             :     }
     513             : 
     514         900 :     for ( i = 0; i < nchan_transport; i++ )
     515             :     {
     516         600 :         mvr2r( data_out_f[i], data_in_f[i], input_frame );
     517             :     }
     518             : 
     519         300 :     return;
     520             : }
     521             : 
     522             : 
     523             : /*--------------------------------------------------------------------------*
     524             :  * computeIntensityVector_ana()
     525             :  *
     526             :  *
     527             :  *--------------------------------------------------------------------------*/
     528             : 
     529       19200 : void computeIntensityVector_ana(
     530             :     const int16_t *band_grouping,                                /* i  : Band grouping for estimation    */
     531             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       */
     532             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       */
     533             :     const int16_t num_frequency_bands,                           /* i  : Number of frequency bands       */
     534             :     float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]   /* o  : Intensity vector                */
     535             : )
     536             : {
     537             :     /* Reminder
     538             :      * X = a + ib; Y = c + id
     539             :      * X*Y = ac - bd + i(ad +bc)
     540             :      */
     541             :     int16_t i, j;
     542             :     float real, img;
     543             :     int16_t brange[2];
     544             : 
     545      480000 :     for ( i = 0; i < num_frequency_bands; i++ )
     546             :     {
     547      460800 :         brange[0] = band_grouping[i];
     548      460800 :         brange[1] = band_grouping[i + 1];
     549             : 
     550      460800 :         intensity_real[0][i] = 0;
     551      460800 :         intensity_real[1][i] = 0;
     552      460800 :         intensity_real[2][i] = 0;
     553             : 
     554     1612800 :         for ( j = brange[0]; j < brange[1]; j++ )
     555             :         {
     556     1152000 :             real = Cldfb_RealBuffer[0][j];
     557     1152000 :             img = Cldfb_ImagBuffer[0][j];
     558     1152000 :             intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
     559     1152000 :             intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
     560     1152000 :             intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
     561             :         }
     562             :     }
     563             : 
     564       19200 :     return;
     565             : }
     566             : 
     567             : 
     568             : /*--------------------------------------------------------------------------*
     569             :  * computeReferencePower_ana()
     570             :  *
     571             :  *
     572             :  *--------------------------------------------------------------------------*/
     573             : 
     574       14400 : void computeReferencePower_ana(
     575             :     const int16_t *band_grouping,                                /* i  : Band grouping for estimation    */
     576             :     float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       */
     577             :     float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       */
     578             :     float *reference_power,                                      /* o  : Estimated power                 */
     579             :     const int16_t num_freq_bands                                 /* i  : Number of frequency bands       */
     580             : )
     581             : {
     582             :     int16_t brange[2];
     583             :     int16_t ch_idx, i, j;
     584             : 
     585      360000 :     for ( i = 0; i < num_freq_bands; i++ )
     586             :     {
     587      345600 :         brange[0] = band_grouping[i];
     588      345600 :         brange[1] = band_grouping[i + 1];
     589      345600 :         reference_power[i] = 0;
     590             : 
     591     1728000 :         for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
     592             :         {
     593             :             /* abs()^2 */
     594     4838400 :             for ( j = brange[0]; j < brange[1]; j++ )
     595             :             {
     596     3456000 :                 reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
     597             :             }
     598             :         }
     599             :     }
     600             : 
     601       14400 :     v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
     602             : 
     603       14400 :     return;
     604             : }

Generated by: LCOV version 1.14