LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_ana_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 211 220 95.9 %
Date: 2025-06-27 02:59:36 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include "options.h"
      34             : #include <stdlib.h>
      35             : #include "ivas_cnst.h"
      36             : #include "ivas_prot_rend_fx.h"
      37             : #include "prot_fx.h"
      38             : #include "ivas_stat_rend.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : 
      43             : /*-------------------------------------------------------------------------
      44             :  * Local function prototypes
      45             :  *------------------------------------------------------------------------*/
      46             : static void ivas_dirac_param_est_ana_fx( DIRAC_ANA_HANDLE hDirAC, Word32 data_f[][L_FRAME48k], Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const Word16 input_frame );
      47             : static void ivas_dirac_dmx_fx( Word32 data_in_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_transport );
      48             : 
      49             : 
      50             : /*--------------------------------------------------------------------------*
      51             :  * ivas_dirac_ana_open()
      52             :  *
      53             :  * Allocate and initialize DIRAC handle
      54             :  *--------------------------------------------------------------------------*/
      55             : 
      56           1 : ivas_error ivas_dirac_ana_open_fx(
      57             :     DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */
      58             :     Word32 input_Fs              /* i  : Sampling frequency        */
      59             : )
      60             : {
      61             :     Word16 i, j;
      62             :     DIRAC_ANA_HANDLE hDirAC;
      63             :     Word16 numAnalysisChannels;
      64             :     Word16 maxBin;
      65             :     ivas_error error;
      66             : 
      67           1 :     error = IVAS_ERR_OK;
      68           1 :     move16();
      69             : 
      70           1 :     IF( ( hDirAC = (DIRAC_ANA_HANDLE) malloc( sizeof( DIRAC_ANA_DATA ) ) ) == NULL )
      71             :     {
      72           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DIRAC\n" ) );
      73             :     }
      74             : 
      75           1 :     numAnalysisChannels = FOA_CHANNELS;
      76           1 :     move16();
      77             : 
      78             :     /* Determine the number of bands */
      79           1 :     hDirAC->nbands = MASA_FREQUENCY_BANDS;
      80           1 :     move16();
      81             : 
      82             :     /* Determine band grouping */
      83           1 :     Copy( MASA_band_grouping_24, hDirAC->band_grouping, 24 + 1 );
      84             : 
      85             :     // maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
      86           1 :     Word32 n_input_Fs = L_shl( input_Fs, 1 );
      87           1 :     Word32 val = L_add( Mpy_32_16_1( n_input_Fs, 41 /* INV_CLDFB_BANDWIDTH in Q15 */ ), 1 );
      88           1 :     val = L_shr( val, 1 );
      89           1 :     maxBin = extract_l( val );
      90          24 :     FOR( i = 1; i < hDirAC->nbands + 1; i++ )
      91             :     {
      92          24 :         IF( GE_16( hDirAC->band_grouping[i], maxBin ) )
      93             :         {
      94           1 :             hDirAC->band_grouping[i] = maxBin;
      95           1 :             move16();
      96           1 :             hDirAC->nbands = i;
      97           1 :             move16();
      98           1 :             BREAK;
      99             :         }
     100             :     }
     101             : 
     102             :     /* Determine block grouping */
     103           1 :     Copy( DirAC_block_grouping, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     104             : 
     105             :     /* open/initialize CLDFB */
     106           1 :     hDirAC->num_Cldfb_instances = numAnalysisChannels;
     107           1 :     move16();
     108           5 :     FOR( i = 0; i < hDirAC->num_Cldfb_instances; i++ )
     109             :     {
     110           4 :         IF( NE_32( ( error = openCldfb_ivas_fx( &( hDirAC->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
     111             :         {
     112           0 :             return error;
     113             :         }
     114             :     }
     115           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     116             :     {
     117           3 :         IF( ( hDirAC->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
     118             :         {
     119           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     120             :         }
     121             : 
     122          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     123             :         {
     124          12 :             IF( ( hDirAC->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     125             :             {
     126           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     127             :             }
     128          12 :             set32_fx( hDirAC->direction_vector_m_fx[i][j], 0, MASA_FREQUENCY_BANDS );
     129             :         }
     130           3 :         IF( ( hDirAC->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL )
     131             :         {
     132           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     133             :         }
     134             : 
     135          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     136             :         {
     137          12 :             IF( ( hDirAC->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL )
     138             :             {
     139           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     140             :             }
     141          12 :             set16_fx( hDirAC->direction_vector_e[i][j], 31, MASA_FREQUENCY_BANDS );
     142             :         }
     143             :     }
     144             : 
     145           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     146             :     {
     147          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     148             :         {
     149          96 :             IF( ( hDirAC->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     150             :             {
     151           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     152             :             }
     153          96 :             set32_fx( hDirAC->buffer_intensity_real_fx[i][j], 0, MASA_FREQUENCY_BANDS );
     154             :         }
     155             :     }
     156           1 :     set32_fx( hDirAC->buffer_energy_fx, 0, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     157           1 :     set16_fx( hDirAC->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
     158           1 :     set16_fx( hDirAC->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
     159           1 :     hDirAC->index_buffer_intensity = 0;
     160           1 :     move16();
     161             : 
     162           1 :     IF( ( hDirAC->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     163             :     {
     164           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     165             :     }
     166             : 
     167           1 :     IF( ( hDirAC->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     168             :     {
     169           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     170             :     }
     171           1 :     generate_gridEq_fx( hDirAC->sph_grid16 );
     172             : 
     173           1 :     ( *hDirACPtr ) = hDirAC;
     174             : 
     175           1 :     return error;
     176             : }
     177             : 
     178             : 
     179             : /*--------------------------------------------------------------------------*
     180             :  * ivas_dirac_ana_close()
     181             :  *
     182             :  * Close DIRAC handle
     183             :  *--------------------------------------------------------------------------*/
     184             : 
     185         666 : void ivas_dirac_ana_close_fx(
     186             :     DIRAC_ANA_HANDLE( *hDirAC ) /* i/o: analysis DIRAC handle */
     187             : )
     188             : {
     189             :     Word16 i, j;
     190             : 
     191         666 :     test();
     192         666 :     IF( hDirAC == NULL || *hDirAC == NULL )
     193             :     {
     194         665 :         return;
     195             :     }
     196             : 
     197           5 :     FOR( i = 0; i < ( *hDirAC )->num_Cldfb_instances; i++ )
     198             :     {
     199           4 :         deleteCldfb_ivas_fx( &( ( *hDirAC )->cldfbAnaEnc[i] ) );
     200             :     }
     201             : 
     202           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     203             :     {
     204          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     205             :         {
     206          12 :             free( ( *hDirAC )->direction_vector_m_fx[i][j] );
     207          12 :             ( *hDirAC )->direction_vector_m_fx[i][j] = NULL;
     208             :         }
     209           3 :         free( ( *hDirAC )->direction_vector_m_fx[i] );
     210           3 :         ( *hDirAC )->direction_vector_m_fx[i] = NULL;
     211             : 
     212          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     213             :         {
     214          12 :             free( ( *hDirAC )->direction_vector_e[i][j] );
     215          12 :             ( *hDirAC )->direction_vector_e[i][j] = NULL;
     216             :         }
     217             : 
     218           3 :         free( ( *hDirAC )->direction_vector_e[i] );
     219           3 :         ( *hDirAC )->direction_vector_e[i] = NULL;
     220             : 
     221          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     222             :         {
     223          96 :             free( ( *hDirAC )->buffer_intensity_real_fx[i][j] );
     224          96 :             ( *hDirAC )->buffer_intensity_real_fx[i][j] = NULL;
     225             :         }
     226             :     }
     227             : 
     228           1 :     free( ( *hDirAC )->hMasaOut );
     229           1 :     ( *hDirAC )->hMasaOut = NULL;
     230           1 :     free( ( *hDirAC )->sph_grid16 );
     231           1 :     ( *hDirAC )->sph_grid16 = NULL;
     232             : 
     233           1 :     free( ( *hDirAC ) );
     234           1 :     ( *hDirAC ) = NULL;
     235             : 
     236           1 :     return;
     237             : }
     238             : 
     239             : 
     240             : /*--------------------------------------------------------------------------*
     241             :  * ivas_dirac_ana()
     242             :  *
     243             :  * DIRAC analysis function
     244             :  *--------------------------------------------------------------------------*/
     245             : 
     246         150 : void ivas_dirac_ana_fx(
     247             :     DIRAC_ANA_HANDLE hDirAC,      /* i/o: DIRAC analysis handle               */
     248             :     Word32 data_fx[][L_FRAME48k], /* i/o: Input / transport audio signals, Q7 */
     249             :     const Word16 input_frame,     /* i  : Input frame size                    */
     250             :     const Word16 nchan_transport  /* i  : Number of transport channels        */
     251             : )
     252             : {
     253             :     Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     254             :     Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     255             :     Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     256             :     Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     257             :     Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     258             :     /* Estimate MASA parameters from the SBA signals */
     259         150 :     ivas_dirac_param_est_ana_fx( hDirAC, data_fx, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame );
     260             :     /* Create MASA metadata buffer from the estimated values */
     261             : 
     262         150 :     ivas_create_masa_out_meta_fx( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, Q31, Q31, Q31 );
     263             : 
     264             :     /* Downmix */
     265         150 :     ivas_dirac_dmx_fx( data_fx, input_frame, nchan_transport ); // output Q of data_fx is same as that of input
     266             : 
     267         150 :     return;
     268             : }
     269             : 
     270             : 
     271             : /*--------------------------------------------------------------------------*
     272             :  * Local functions
     273             :  *--------------------------------------------------------------------------*/
     274             : 
     275             : /* Estimate MASA parameters from the SBA signals */
     276         150 : static void ivas_dirac_param_est_ana_fx(
     277             :     DIRAC_ANA_HANDLE hDirAC,
     278             :     Word32 data_fx[][L_FRAME48k],                                                      /* Q7  */
     279             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /* Q22 */
     280             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],     /* Q22 */
     281             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],          /* Q30 */
     282             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],      /* Qx  */
     283             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx  */
     284             :     const Word16 input_frame )
     285             : {
     286             :     Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
     287             :     Word16 ts, i, d, j;
     288             :     Word16 num_freq_bands, index;
     289             :     Word32 dir_v_fx[DIRAC_NUM_DIMS];
     290             :     Word16 dir_v_q;
     291             :     Word16 l_ts;
     292             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     293             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     294             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     295             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     296             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     297             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
     298             :     Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
     299         150 :     Word16 diffuseness_q = 0;
     300         150 :     move16();
     301             :     Word16 band_m_idx, block_m_idx;
     302             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
     303             :     Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
     304             :     Word32 norm_tmp_fx;
     305             :     Word16 mrange[2];
     306             :     Word16 brange[2];
     307             :     Word16 numAnalysisChannels;
     308             :     Word16 inp_q;
     309             :     Word16 intensity_q, reference_power_q;
     310         150 :     num_freq_bands = hDirAC->nbands;
     311             :     /* l_ts = input_frame / CLDFB_NO_COL_MAX; */
     312         150 :     l_ts = shr( input_frame, 4 );
     313         150 :     numAnalysisChannels = FOA_CHANNELS;
     314         150 :     move16();
     315         150 :     move16();
     316         150 :     move16();
     317         150 :     move16();
     318         150 :     move16();
     319         150 :     move16();
     320         150 :     move16();
     321         150 :     move16();
     322             : 
     323             :     /* do processing over all CLDFB time slots */
     324         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     325             :     {
     326         600 :         mrange[0] = hDirAC->block_grouping[block_m_idx];
     327         600 :         move16();
     328         600 :         mrange[1] = hDirAC->block_grouping[block_m_idx + 1];
     329         600 :         move16();
     330             : 
     331       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     332             :         {
     333       14400 :             hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
     334       14400 :             move32();
     335       14400 :             hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
     336       14400 :             move32();
     337       14400 :             hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
     338       14400 :             move32();
     339             : 
     340       14400 :             hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
     341       14400 :             move16();
     342       14400 :             hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
     343       14400 :             move16();
     344       14400 :             hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
     345       14400 :             move16();
     346             :         }
     347             : 
     348             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     349         600 :         set32_fx( renormalization_factor_diff_fx, 0, hDirAC->nbands );
     350         600 :         set16_fx( renormalization_factor_diff_e, 31, hDirAC->nbands );
     351         600 :         set32_fx( diffuseness_m_fx, 0, hDirAC->nbands );
     352         600 :         set16_fx( diffuseness_e, 0, hDirAC->nbands );
     353         600 :         set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     354         600 :         set16_fx( hDirAC->energy_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     355             : 
     356        3000 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
     357             :         {
     358        2400 :             Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e;
     359        2400 :             inp_q = Q7; // Input Q of data_fx
     360        2400 :             move16();
     361        2400 :             move16();
     362        2400 :             move16();
     363       12000 :             FOR( i = 0; i < numAnalysisChannels; i++ )
     364             :             {
     365        9600 :                 inp_q = Q7;
     366        9600 :                 move16();
     367        9600 :                 cldfbAnalysis_ts_fx_var_q( &( data_fx[i][l_ts * ts] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &inp_q );
     368        9600 :                 cr_q = s_min( cr_q, getScaleFactor32( Foa_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
     369        9600 :                 ci_q = s_min( ci_q, getScaleFactor32( Foa_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
     370             :             }
     371        2400 :             sf = sub( s_min( cr_q, ci_q ), 4 );
     372       12000 :             FOR( i = 0; i < numAnalysisChannels; i++ )
     373             :             {
     374        9600 :                 scale_sig32( Foa_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
     375        9600 :                 scale_sig32( Foa_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
     376             :             }
     377        2400 :             inp_q = add( inp_q, sf );
     378        2400 :             c_e = sub( 31, inp_q );
     379             :             /* Compute omni energy for metadata processing */
     380       60000 :             FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     381             :             {
     382       57600 :                 brange[0] = hDirAC->band_grouping[band_m_idx];
     383       57600 :                 move16();
     384       57600 :                 brange[1] = hDirAC->band_grouping[band_m_idx + 1];
     385       57600 :                 move16();
     386      201600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
     387             :                 {
     388      144000 :                     Word32 temp = L_add( Mult_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mult_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e
     389      144000 :                     hDirAC->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->energy_fx[block_m_idx][band_m_idx], hDirAC->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hDirAC->energy_e[block_m_idx][band_m_idx] );
     390      144000 :                     move32();
     391             :                 }
     392             :             }
     393             :             /* Direction estimation */
     394        2400 :             computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */
     395        2400 :             intensity_q = sub( 31, shl( c_e, 1 ) );
     396             : 
     397        2400 :             computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ), NULL );
     398             :             /* Power estimation for diffuseness */
     399        2400 :             computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); //( 2 * ( scale_fact - Q1 ) - 31 - 1 );                                                                                                                               // computeReferencePower_ana( hDirAC->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], num_freq_bands );
     400        2400 :             reference_power_q = sub( shl( inp_q, 1 ), 30 );
     401             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     402        2400 :             hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
     403        2400 :             move16();
     404        2400 :             index = hDirAC->index_buffer_intensity;
     405        2400 :             move16();
     406        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     407             :             {
     408             :                 /* only real part needed */
     409        7200 :                 Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
     410             :             }
     411        2400 :             hDirAC->buffer_intensity_real_q[index - 1] = intensity_q;
     412        2400 :             move16();
     413        2400 :             Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     414        2400 :             hDirAC->buffer_energy_q[index - 1] = reference_power_q;
     415        2400 :             move16();
     416        2400 :             computeDiffuseness_fixed( hDirAC->buffer_intensity_real_fx, hDirAC->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hDirAC->buffer_intensity_real_q, hDirAC->buffer_energy_q, &diffuseness_q );
     417             : 
     418       60000 :             FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     419             :             {
     420       57600 :                 norm_tmp_fx = L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ), 1 ); /*2*inp_q-30*/
     421             : 
     422       57600 :                 hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx], hDirAC->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), shl( c_e, 1 ), &hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] );
     423       57600 :                 move32();
     424       57600 :                 hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx], hDirAC->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), shl( c_e, 1 ), &hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] );
     425       57600 :                 move32();
     426       57600 :                 hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx], hDirAC->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), shl( c_e, 1 ), &hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] );
     427       57600 :                 move32();
     428       57600 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 1 ), sub( shl( c_e, 1 ), 1 ), &diffuseness_e[band_m_idx] );
     429       57600 :                 move32();
     430             : 
     431       57600 :                 renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( shl( c_e, 1 ), 1 ), &renormalization_factor_diff_e[band_m_idx] );
     432       57600 :                 move32();
     433             :             }
     434             :         }
     435       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     436             :         {
     437       14400 :             Word16 max_e = MIN_16;
     438       14400 :             move16();
     439       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     440             :             {
     441       43200 :                 max_e = s_max( max_e, hDirAC->direction_vector_e[d][block_m_idx][band_m_idx] );
     442             :             }
     443       14400 :             max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
     444       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     445             :             {
     446       43200 :                 dir_v_fx[d] = L_shr( hDirAC->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hDirAC->direction_vector_e[d][block_m_idx][band_m_idx] ) );
     447       43200 :                 move32();
     448             :             }
     449       14400 :             dir_v_q = sub( 31, max_e );
     450       14400 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, dir_v_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
     451             :         }
     452             :         /* Determine energy ratios */
     453       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     454             :         {
     455             :             Word16 diffuseness_m_e;
     456       14400 :             IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
     457             :             {
     458       14362 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e );
     459       14362 :                 move32();
     460       14362 :                 diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
     461       14362 :                 diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); // Q31
     462       14362 :                 move32();
     463             :             }
     464             :             ELSE
     465             :             {
     466          38 :                 diffuseness_m_fx[band_m_idx] = 0;
     467          38 :                 move32();
     468             :             }
     469       14400 :             energyRatio_fx[block_m_idx][band_m_idx] = L_sub( ONE_IN_Q31, diffuseness_m_fx[band_m_idx] );
     470       14400 :             move32();
     471             :         }
     472       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     473             :         {
     474       14400 :             spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
     475       14400 :             move32();
     476       14400 :             surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
     477       14400 :             move32();
     478             :         }
     479             :     }
     480             : 
     481         150 :     return;
     482             : }
     483             : 
     484             : 
     485             : /* Compute downmix */
     486         150 : static void ivas_dirac_dmx_fx(
     487             :     Word32 data_in_fx[][L_FRAME48k], /* Qx (same as the input Q) */
     488             :     const Word16 input_frame,
     489             :     const Word16 nchan_transport )
     490             : {
     491             :     Word16 i;
     492             :     Word32 data_out_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     493             : 
     494         150 :     IF( EQ_16( nchan_transport, 2 ) )
     495             :     {
     496         150 :         v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame );
     497         150 :         v_multc_fixed( data_out_fx[0], ONE_IN_Q30, data_out_fx[0], input_frame ); // ONE_IN_Q30 = 0.5* ONE_IN_Q31
     498             : 
     499         150 :         v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame );
     500         150 :         v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame );
     501             : 
     502         450 :         FOR( i = 0; i < nchan_transport; i++ )
     503             :         {
     504         300 :             Copy32( data_out_fx[i], data_in_fx[i], input_frame );
     505             :         }
     506             :     }
     507             :     /* output Q is same as input Q*/
     508         150 :     return;
     509             : }

Generated by: LCOV version 1.14