LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_ana_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 232 243 95.5 %
Date: 2025-08-23 01:22:27 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, const Word16 data_q );
      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             :     const Word16 data_q )
     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, data_q );
     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             :     const Word16 data_q )
     286             : {
     287             :     Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
     288             :     Word16 ts, i, d, j;
     289             :     Word16 num_freq_bands, index;
     290             :     Word32 dir_v_fx[DIRAC_NUM_DIMS];
     291             :     Word16 dir_v_q;
     292             :     Word16 l_ts;
     293             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     294             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     295             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     296             :     Word16 intensity_real_q[MASA_FREQUENCY_BANDS];
     297             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     298             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     299             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
     300             :     Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
     301         150 :     Word16 diffuseness_q = 0;
     302         150 :     move16();
     303             :     Word16 band_m_idx, block_m_idx;
     304             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
     305             :     Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
     306             :     Word32 norm_tmp_fx;
     307             :     Word16 mrange[2];
     308             :     Word16 brange[2];
     309             :     Word16 numAnalysisChannels;
     310             :     Word16 inp_q;
     311             :     Word16 intensity_q, reference_power_q;
     312         150 :     Word16 temp_e, sf, scaled_data_q, s, shift = 31;
     313         150 :     move16();
     314             :     Word32 temp;
     315             :     Word64 W_temp;
     316         150 :     num_freq_bands = hDirAC->nbands;
     317             :     /* l_ts = input_frame / CLDFB_NO_COL_MAX; */
     318         150 :     l_ts = shr( input_frame, 4 );
     319         150 :     numAnalysisChannels = FOA_CHANNELS;
     320         150 :     move16();
     321         150 :     move16();
     322         150 :     move16();
     323         150 :     move16();
     324         150 :     move16();
     325         150 :     move16();
     326         150 :     move16();
     327         150 :     move16();
     328         750 :     FOR( i = 0; i < numAnalysisChannels; i++ )
     329             :     {
     330         600 :         shift = s_min( shift, L_norm_arr( data_fx[i], input_frame ) );
     331             :     }
     332         150 :     shift = sub( shift, find_guarded_bits_fx( l_ts ) );
     333         750 :     FOR( i = 0; i < numAnalysisChannels; i++ )
     334             :     {
     335         600 :         scale_sig32( data_fx[i], input_frame, shift );
     336             :     }
     337         150 :     scaled_data_q = add( data_q, shift );
     338             : 
     339             :     /* do processing over all CLDFB time slots */
     340         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     341             :     {
     342         600 :         mrange[0] = hDirAC->block_grouping[block_m_idx];
     343         600 :         move16();
     344         600 :         mrange[1] = hDirAC->block_grouping[block_m_idx + 1];
     345         600 :         move16();
     346             : 
     347       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     348             :         {
     349       14400 :             hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
     350       14400 :             move32();
     351       14400 :             hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
     352       14400 :             move32();
     353       14400 :             hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
     354       14400 :             move32();
     355             : 
     356       14400 :             hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
     357       14400 :             move16();
     358       14400 :             hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
     359       14400 :             move16();
     360       14400 :             hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
     361       14400 :             move16();
     362             :         }
     363             : 
     364             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     365         600 :         set32_fx( renormalization_factor_diff_fx, 0, hDirAC->nbands );
     366         600 :         set16_fx( renormalization_factor_diff_e, 31, hDirAC->nbands );
     367         600 :         set32_fx( diffuseness_m_fx, 0, hDirAC->nbands );
     368         600 :         set16_fx( diffuseness_e, 0, hDirAC->nbands );
     369         600 :         set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     370         600 :         set16_fx( hDirAC->energy_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     371             : 
     372        3000 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
     373             :         {
     374        2400 :             Word16 cr_q = MAX_16, ci_q = MAX_16;
     375        2400 :             inp_q = scaled_data_q; // Q of data_fx after scaling
     376        2400 :             move16();
     377        2400 :             move16();
     378        2400 :             move16();
     379       12000 :             FOR( i = 0; i < numAnalysisChannels; i++ )
     380             :             {
     381        9600 :                 inp_q = scaled_data_q;
     382        9600 :                 move16();
     383        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 );
     384        9600 :                 cr_q = s_min( cr_q, getScaleFactor32( Foa_RealBuffer_fx[i], l_ts ) );
     385        9600 :                 ci_q = s_min( ci_q, getScaleFactor32( Foa_ImagBuffer_fx[i], l_ts ) );
     386             :             }
     387        2400 :             sf = sub( s_min( cr_q, ci_q ), 4 );
     388       12000 :             FOR( i = 0; i < numAnalysisChannels; i++ )
     389             :             {
     390        9600 :                 scale_sig32( Foa_RealBuffer_fx[i], l_ts, sf ); // Q-> inp_q + sf
     391        9600 :                 scale_sig32( Foa_ImagBuffer_fx[i], l_ts, sf ); // Q-> inp_q + sf
     392             :             }
     393        2400 :             inp_q = add( inp_q, sf );
     394             :             /* Compute omni energy for metadata processing */
     395       60000 :             FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     396             :             {
     397       57600 :                 brange[0] = hDirAC->band_grouping[band_m_idx];
     398       57600 :                 move16();
     399       57600 :                 brange[1] = hDirAC->band_grouping[band_m_idx + 1];
     400       57600 :                 move16();
     401      201600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
     402             :                 {
     403      144000 :                     W_temp = W_mac_32_32( W_mult_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ); // Q-> 2*inp_q + 1
     404      144000 :                     sf = W_norm( W_temp );
     405      144000 :                     temp = W_extract_h( W_shl( W_temp, sf ) );          // 2*inp_q + 1 + sf - 32
     406      144000 :                     temp_e = sub( 63 - 1, add( shl( inp_q, 1 ), sf ) ); // 31 - ( 2 * inp_q + 1 + sf - 32 )
     407      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, temp_e, &hDirAC->energy_e[block_m_idx][band_m_idx] );
     408      144000 :                     move32();
     409             :                 }
     410             :             }
     411             :             /* Direction estimation */
     412        2400 :             computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, intensity_real_q, inp_q );
     413             : 
     414        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], 0, intensity_real_q );
     415             : 
     416             :             /* Power estimation for diffuseness */
     417        2400 :             computeReferencePower_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands, inp_q, &reference_power_q );
     418             : 
     419             :             /* Aligning intensity_real to a common Q-factor */
     420        2400 :             minimum_fx( intensity_real_q, num_freq_bands, &intensity_q );
     421             : 
     422             :             Word16 tmp;
     423       60000 :             FOR( i = 0; i < num_freq_bands; i++ )
     424             :             {
     425       57600 :                 tmp = sub( intensity_q, intensity_real_q[i] );
     426       57600 :                 intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp );
     427       57600 :                 move32();
     428       57600 :                 intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp );
     429       57600 :                 move32();
     430       57600 :                 intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp );
     431       57600 :                 move32();
     432             :             }
     433             : 
     434             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     435        2400 :             hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
     436        2400 :             move16();
     437        2400 :             index = hDirAC->index_buffer_intensity;
     438        2400 :             move16();
     439        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     440             :             {
     441             :                 /* only real part needed */
     442        7200 :                 Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
     443             :             }
     444        2400 :             hDirAC->buffer_intensity_real_q[index - 1] = intensity_q;
     445        2400 :             move16();
     446        2400 :             Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     447        2400 :             hDirAC->buffer_energy_q[index - 1] = reference_power_q;
     448        2400 :             move16();
     449        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 );
     450             : 
     451       60000 :             FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     452             :             {
     453       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 ); /*reference_power_q*/
     454             : 
     455       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] ), sub( 31 + 1, reference_power_q ), &hDirAC->direction_vector_e[0][block_m_idx][band_m_idx] );
     456       57600 :                 move32();
     457       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] ), sub( 31 + 1, reference_power_q ), &hDirAC->direction_vector_e[1][block_m_idx][band_m_idx] );
     458       57600 :                 move32();
     459       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] ), sub( 31 + 1, reference_power_q ), &hDirAC->direction_vector_e[2][block_m_idx][band_m_idx] );
     460       57600 :                 move32();
     461             : 
     462       57600 :                 W_temp = W_mult0_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] );
     463       57600 :                 s = W_norm( W_temp );
     464       57600 :                 temp = W_extract_h( W_shl( W_temp, s ) );
     465       57600 :                 temp_e = sub( 63, add( add( reference_power_q, diffuseness_q ), s ) ); // 31 - ( reference_power_q + diffuseness_q + s - 32 )
     466             : 
     467       57600 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], temp, temp_e, &diffuseness_e[band_m_idx] );
     468       57600 :                 move32();
     469             : 
     470       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( 31, reference_power_q ), &renormalization_factor_diff_e[band_m_idx] );
     471       57600 :                 move32();
     472             :             }
     473             :         }
     474       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     475             :         {
     476       14400 :             Word16 max_e = MIN_16;
     477       14400 :             move16();
     478       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     479             :             {
     480       43200 :                 max_e = s_max( max_e, hDirAC->direction_vector_e[d][block_m_idx][band_m_idx] );
     481             :             }
     482       14400 :             max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
     483       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     484             :             {
     485       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] ) );
     486       43200 :                 move32();
     487             :             }
     488       14400 :             dir_v_q = sub( 31, max_e );
     489       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] );
     490             :         }
     491             :         /* Determine energy ratios */
     492       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     493             :         {
     494             :             Word16 diffuseness_m_e;
     495       14400 :             IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
     496             :             {
     497       14400 :                 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 );
     498       14400 :                 move32();
     499       14400 :                 diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
     500       14400 :                 diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); // Q31
     501       14400 :                 move32();
     502             :             }
     503             :             ELSE
     504             :             {
     505           0 :                 diffuseness_m_fx[band_m_idx] = 0;
     506           0 :                 move32();
     507             :             }
     508       14400 :             energyRatio_fx[block_m_idx][band_m_idx] = L_sub( ONE_IN_Q31, diffuseness_m_fx[band_m_idx] );
     509       14400 :             move32();
     510             :         }
     511       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     512             :         {
     513       14400 :             spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
     514       14400 :             move32();
     515       14400 :             surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
     516       14400 :             move32();
     517             :         }
     518             :     }
     519             : 
     520         750 :     FOR( i = 0; i < numAnalysisChannels; i++ )
     521             :     {
     522         600 :         scale_sig32( data_fx[i], input_frame, negate( shift ) );
     523             :     }
     524         150 :     return;
     525             : }
     526             : 
     527             : 
     528             : /* Compute downmix */
     529         150 : static void ivas_dirac_dmx_fx(
     530             :     Word32 data_in_fx[][L_FRAME48k], /* Qx (same as the input Q) */
     531             :     const Word16 input_frame,
     532             :     const Word16 nchan_transport )
     533             : {
     534             :     Word16 i;
     535             :     Word32 data_out_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     536             : 
     537         150 :     IF( EQ_16( nchan_transport, 2 ) )
     538             :     {
     539         150 :         v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame );
     540         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
     541             : 
     542         150 :         v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame );
     543         150 :         v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame );
     544             : 
     545         450 :         FOR( i = 0; i < nchan_transport; i++ )
     546             :         {
     547         300 :             Copy32( data_out_fx[i], data_in_fx[i], input_frame );
     548             :         }
     549             :     }
     550             :     /* output Q is same as input Q*/
     551         150 :     return;
     552             : }

Generated by: LCOV version 1.14