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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 231 243 95.1 %
Date: 2025-05-03 01:55:50 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             :     }
     131           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     132             :     {
     133          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     134             :         {
     135          96 :             IF( ( hDirAC->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     136             :             {
     137           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     138             :             }
     139          96 :             set32_fx( hDirAC->buffer_intensity_real_fx[i][j], 0, MASA_FREQUENCY_BANDS );
     140             :         }
     141             :     }
     142           1 :     set32_fx( hDirAC->buffer_energy_fx, 0, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     143             : 
     144           1 :     hDirAC->index_buffer_intensity = 0;
     145           1 :     move16();
     146             : 
     147           1 :     IF( ( hDirAC->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     148             :     {
     149           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     150             :     }
     151             : 
     152           1 :     IF( ( hDirAC->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     153             :     {
     154           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     155             :     }
     156           1 :     generate_gridEq_fx( hDirAC->sph_grid16 );
     157             : 
     158           1 :     ( *hDirACPtr ) = hDirAC;
     159             : 
     160           1 :     return error;
     161             : }
     162             : 
     163             : 
     164             : /*--------------------------------------------------------------------------*
     165             :  * ivas_dirac_ana_close()
     166             :  *
     167             :  * Close DIRAC handle
     168             :  *--------------------------------------------------------------------------*/
     169             : 
     170         658 : void ivas_dirac_ana_close_fx(
     171             :     DIRAC_ANA_HANDLE( *hDirAC ) /* i/o: analysis DIRAC handle */
     172             : )
     173             : {
     174             :     Word16 i, j;
     175             : 
     176         658 :     test();
     177         658 :     IF( hDirAC == NULL || *hDirAC == NULL )
     178             :     {
     179         657 :         return;
     180             :     }
     181             : 
     182           5 :     FOR( i = 0; i < ( *hDirAC )->num_Cldfb_instances; i++ )
     183             :     {
     184           4 :         deleteCldfb_ivas_fx( &( ( *hDirAC )->cldfbAnaEnc[i] ) );
     185             :     }
     186             : 
     187           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     188             :     {
     189          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     190             :         {
     191          12 :             free( ( *hDirAC )->direction_vector_m_fx[i][j] );
     192          12 :             ( *hDirAC )->direction_vector_m_fx[i][j] = NULL;
     193             :         }
     194           3 :         free( ( *hDirAC )->direction_vector_m_fx[i] );
     195           3 :         ( *hDirAC )->direction_vector_m_fx[i] = NULL;
     196             : 
     197          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     198             :         {
     199          96 :             free( ( *hDirAC )->buffer_intensity_real_fx[i][j] );
     200          96 :             ( *hDirAC )->buffer_intensity_real_fx[i][j] = NULL;
     201             :         }
     202             :     }
     203             : 
     204           1 :     free( ( *hDirAC )->hMasaOut );
     205           1 :     ( *hDirAC )->hMasaOut = NULL;
     206           1 :     free( ( *hDirAC )->sph_grid16 );
     207           1 :     ( *hDirAC )->sph_grid16 = NULL;
     208             : 
     209           1 :     free( ( *hDirAC ) );
     210           1 :     ( *hDirAC ) = NULL;
     211             : 
     212           1 :     return;
     213             : }
     214             : 
     215             : 
     216             : /*--------------------------------------------------------------------------*
     217             :  * ivas_dirac_ana()
     218             :  *
     219             :  * DIRAC analysis function
     220             :  *--------------------------------------------------------------------------*/
     221             : 
     222         150 : void ivas_dirac_ana_fx(
     223             :     DIRAC_ANA_HANDLE hDirAC,      /* i/o: DIRAC analysis handle               */
     224             :     Word32 data_fx[][L_FRAME48k], /* i/o: Input / transport audio signals, Q7 */
     225             :     const Word16 input_frame,     /* i  : Input frame size                    */
     226             :     const Word16 nchan_transport  /* i  : Number of transport channels        */
     227             : )
     228             : {
     229             :     Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     230             :     Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     231             :     Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     232             :     Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     233             :     Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     234         150 :     Word16 energyRatio_q, surroundingCoherence_q = 0, spreadCoherence_q = 0;
     235         150 :     move16();
     236         150 :     move16();
     237             :     /* Estimate MASA parameters from the SBA signals */
     238         150 :     ivas_dirac_param_est_ana_fx( hDirAC, data_fx, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame );
     239         150 :     energyRatio_q = 30;
     240         150 :     move16();
     241             :     /* Create MASA metadata buffer from the estimated values */
     242         150 :     ivas_create_masa_out_meta_fx( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, energyRatio_q, spreadCoherence_q, surroundingCoherence_q );
     243             : 
     244             :     /* Downmix */
     245         150 :     ivas_dirac_dmx_fx( data_fx, input_frame, nchan_transport ); // output Q of data_fx is same as that of input
     246             : 
     247         150 :     return;
     248             : }
     249             : 
     250             : 
     251             : /*--------------------------------------------------------------------------*
     252             :  * Local functions
     253             :  *--------------------------------------------------------------------------*/
     254             : 
     255             : /* Estimate MASA parameters from the SBA signals */
     256         150 : static void ivas_dirac_param_est_ana_fx(
     257             :     DIRAC_ANA_HANDLE hDirAC,
     258             :     Word32 data_fx[][L_FRAME48k],                                                   /* Q7  */
     259             :     Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /* Q22 */
     260             :     Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],     /* Q22 */
     261             :     Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],          /* Q30 */
     262             :     Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],      /* Qx  */
     263             :     Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* Qx  */
     264             :     const Word16 input_frame )
     265             : {
     266             :     Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
     267             :     Word16 ts, i, d, j;
     268             :     Word16 num_freq_bands, index;
     269             :     Word32 dir_v[DIRAC_NUM_DIMS];
     270             :     Word16 dir_q;
     271             :     Word16 l_ts;
     272             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     273             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     274             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     275             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     276             :     Word16 diffuseness_vector_exp[MASA_FREQUENCY_BANDS];
     277             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     278             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
     279             : 
     280             :     Word16 band_m_idx, block_m_idx;
     281             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
     282             :     Word32 norm_tmp_fx;
     283             :     Word16 mrange[2];
     284             :     Word16 brange[2];
     285             :     Word16 numAnalysisChannels;
     286             :     Word16 io_q;
     287             :     Word16 scale_fact, scale_fact2;
     288         150 :     Word16 q_factor_intensity, q_factor_intensity_old = 0;
     289         150 :     Word16 q_factor_energy = 0, q_factor_energy_old = 0;
     290         150 :     Word16 exp = 0, exp_div = 0;
     291         150 :     num_freq_bands = hDirAC->nbands;
     292             :     /* l_ts = input_frame / CLDFB_NO_COL_MAX; */
     293         150 :     l_ts = shr( input_frame, 4 );
     294         150 :     numAnalysisChannels = FOA_CHANNELS;
     295         150 :     move16();
     296         150 :     move16();
     297         150 :     move16();
     298         150 :     move16();
     299         150 :     move16();
     300         150 :     move16();
     301         150 :     move16();
     302         150 :     move16();
     303             : 
     304             :     /* do processing over all CLDFB time slots */
     305         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     306             :     {
     307         600 :         mrange[0] = hDirAC->block_grouping[block_m_idx];
     308         600 :         move16();
     309         600 :         mrange[1] = hDirAC->block_grouping[block_m_idx + 1];
     310         600 :         move16();
     311             : 
     312       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     313             :         {
     314       14400 :             hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
     315       14400 :             move32();
     316       14400 :             hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
     317       14400 :             move32();
     318       14400 :             hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
     319       14400 :             move32();
     320             :         }
     321             : 
     322             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     323         600 :         set32_fx( renormalization_factor_diff_fx, 0, hDirAC->nbands );
     324         600 :         set32_fx( diffuseness_m_fx, 0, hDirAC->nbands );
     325         600 :         set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     326         600 :         set32_fx( hDirAC->energy_fx[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     327             : 
     328        3000 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
     329             :         {
     330       12000 :             FOR( i = 0; i < numAnalysisChannels; i++ )
     331             :             {
     332        9600 :                 io_q = Q7; // Input Q of data_fx
     333        9600 :                 move16();
     334        9600 :                 cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][imult1616( l_ts, ts )] ), Foa_RealBuffer_fx[i], Foa_ImagBuffer_fx[i], l_ts, hDirAC->cldfbAnaEnc[i], &io_q );
     335             :             }
     336        2400 :             scale_fact = getScaleFactor32( (const Word32 *) Foa_RealBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
     337        2400 :             scale_fact = s_min( getScaleFactor32( (const Word32 *) Foa_ImagBuffer_fx, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ), scale_fact );
     338        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     339             :             {
     340      180000 :                 FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     341             :                 {
     342      172800 :                     Foa_RealBuffer_fx[i][j] = L_shl( Foa_RealBuffer_fx[i][j], sub( scale_fact, Q3 ) ); // Q( scale_fact + Q1 )
     343      172800 :                     move32();
     344      172800 :                     Foa_ImagBuffer_fx[i][j] = L_shl( Foa_ImagBuffer_fx[i][j], sub( scale_fact, Q3 ) ); // Q( scale_fact + Q1 )
     345      172800 :                     move32();
     346             :                 }
     347             :             }
     348             :             /* Compute omni energy for metadata processing */
     349       60000 :             FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     350             :             {
     351       57600 :                 brange[0] = hDirAC->band_grouping[band_m_idx];
     352       57600 :                 move16();
     353       57600 :                 brange[1] = hDirAC->band_grouping[band_m_idx + 1];
     354       57600 :                 move16();
     355      201600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
     356             :                 {
     357      144000 :                     hDirAC->energy_fx[block_m_idx][band_m_idx] = ( L_add( hDirAC->energy_fx[block_m_idx][band_m_idx], L_add( Mpy_32_32( Foa_RealBuffer_fx[0][j], Foa_RealBuffer_fx[0][j] ), Mpy_32_32( Foa_ImagBuffer_fx[0][j], Foa_ImagBuffer_fx[0][j] ) ) ) ); // 2*( scale_fact + Q1 )-31
     358      144000 :                     move32();
     359             :                 }
     360             :             }
     361             :             /* Direction estimation */
     362        2400 :             computeIntensityVector_ana_fx( hDirAC->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); // 2 * ( scale_fact + Q1 ) - 31
     363        2400 :             exp = sub( shl( sub( scale_fact, Q1 ), 1 ), 31 );
     364             : 
     365        2400 :             computeDirectionVectors_fx( 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], &exp );
     366             : 
     367             :             /* Power estimation for diffuseness */
     368        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 );
     369             : 
     370             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     371        2400 :             hDirAC->index_buffer_intensity = add( ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
     372        2400 :             move16();
     373        2400 :             index = hDirAC->index_buffer_intensity;
     374        2400 :             move16();
     375        2400 :             Word16 guard_bits = find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF );
     376        2400 :             scale_fact2 = getScaleFactor32( (const Word32 *) intensity_real_fx, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS );
     377        2400 :             IF( GT_16( guard_bits, scale_fact2 ) )
     378             :             {
     379           0 :                 FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     380             :                 {
     381           0 :                     FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     382             :                     {
     383           0 :                         intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], sub( guard_bits, scale_fact2 ) );
     384           0 :                         move32();
     385             :                     }
     386             :                 }
     387           0 :                 q_factor_intensity = sub( sub( shl( sub( scale_fact, 1 ), 1 ), 31 ), sub( guard_bits, scale_fact2 ) );
     388             :             }
     389             :             ELSE
     390             :             {
     391        9600 :                 FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     392             :                 {
     393      180000 :                     FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     394             :                     {
     395      172800 :                         intensity_real_fx[i][j] = L_shl( intensity_real_fx[i][j], sub( scale_fact2, guard_bits ) );
     396      172800 :                         move32();
     397             :                     }
     398             :                 }
     399        2400 :                 q_factor_intensity = add( sub( shl( sub( scale_fact, 1 ), 1 ), 31 ), sub( scale_fact2, guard_bits ) );
     400             :             }
     401        2400 :             scale_fact2 = getScaleFactor32( reference_power_fx[ts], MASA_FREQUENCY_BANDS );
     402        2400 :             IF( GT_16( guard_bits, scale_fact2 ) )
     403             :             {
     404             : 
     405        2300 :                 FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     406             :                 {
     407        2208 :                     reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], sub( guard_bits, scale_fact2 ) );
     408        2208 :                     move32();
     409             :                 }
     410             : 
     411          92 :                 q_factor_energy = sub( sub( shl( scale_fact, 1 ), 31 ), sub( guard_bits, scale_fact2 ) );
     412             :             }
     413             :             ELSE
     414             :             {
     415       57700 :                 FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     416             :                 {
     417       55392 :                     reference_power_fx[ts][j] = L_shl( reference_power_fx[ts][j], sub( scale_fact2, guard_bits ) );
     418       55392 :                     move32();
     419             :                 }
     420             : 
     421        2308 :                 q_factor_energy = add( sub( shl( scale_fact, 1 ), 31 ), sub( scale_fact2, guard_bits ) );
     422             :             }
     423             : 
     424        2400 :             IF( q_factor_intensity_old != 0 )
     425             :             {
     426             : 
     427        2242 :                 IF( LT_16( q_factor_intensity_old, q_factor_intensity ) )
     428             :                 {
     429        6372 :                     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     430             :                     {
     431      119475 :                         FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     432             :                         {
     433      114696 :                             intensity_real_fx[i][j] = L_shr( intensity_real_fx[i][j], sub( q_factor_intensity, q_factor_intensity_old ) );
     434      114696 :                             move32();
     435             :                         }
     436             :                     }
     437        1593 :                     q_factor_intensity = q_factor_intensity_old;
     438        1593 :                     move16();
     439             :                 }
     440             :                 ELSE
     441             :                 {
     442        2596 :                     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     443             :                     {
     444       30144 :                         FOR( j = 0; j < index - 1; j++ )
     445             :                         {
     446             :                             /* only real part needed */
     447      704925 :                             FOR( Word16 k = 0; k < num_freq_bands; k++ )
     448             :                             {
     449      676728 :                                 hDirAC->buffer_intensity_real_fx[i][j][k] = L_shr( hDirAC->buffer_intensity_real_fx[i][j][k], sub( q_factor_intensity_old, q_factor_intensity ) );
     450      676728 :                                 move32();
     451             :                             }
     452             :                         }
     453             :                     }
     454             :                 }
     455             :             }
     456        2400 :             IF( q_factor_energy_old != 0 )
     457             :             {
     458             : 
     459        2239 :                 IF( LT_16( q_factor_energy_old, q_factor_energy ) )
     460             :                 {
     461             : 
     462       89243 :                     FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
     463             :                     {
     464       87780 :                         reference_power_fx[ts][j] = L_shr( reference_power_fx[ts][j], sub( q_factor_energy, q_factor_energy_old ) );
     465       87780 :                         move32();
     466             :                     }
     467             : 
     468        1463 :                     q_factor_energy = q_factor_energy_old;
     469        1463 :                     move16();
     470             :                 }
     471             :                 ELSE
     472             :                 {
     473       12075 :                     FOR( i = 0; i < index - 1; i++ )
     474             :                     {
     475      282475 :                         FOR( j = 0; j < num_freq_bands; j++ )
     476             :                         {
     477     6779400 :                             FOR( Word16 k = 0; k < num_freq_bands; k++ )
     478             :                             {
     479     6508224 :                                 hDirAC->buffer_energy_fx[add( imult1616( i, j ), k )] = L_shr( hDirAC->buffer_energy_fx[add( imult1616( i, j ), k )], sub( q_factor_energy_old, q_factor_energy_old ) );
     480     6508224 :                                 move32();
     481             :                             }
     482             :                         }
     483             :                     }
     484             :                 }
     485             :             }
     486             : 
     487        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     488             :             {
     489             :                 /* only real part needed */
     490        7200 :                 Copy32( intensity_real_fx[i], &( hDirAC->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands );
     491             :             }
     492        2400 :             Copy32( reference_power_fx[ts], &( hDirAC->buffer_energy_fx[imult1616( sub( index, 1 ), num_freq_bands )] ), num_freq_bands );
     493             : 
     494        2400 :             computeDiffuseness_fx( hDirAC->buffer_intensity_real_fx, hDirAC->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, q_factor_intensity, q_factor_energy, diffuseness_vector_exp );
     495        2400 :             q_factor_intensity_old = q_factor_intensity;
     496        2400 :             move16();
     497        2400 :             q_factor_energy_old = q_factor_energy;
     498        2400 :             move16();
     499       60000 :             FOR( j = 0; j < MASA_FREQUENCY_BANDS; j++ )
     500             :             {
     501       57600 :                 if ( LT_16( diffuseness_vector_exp[j], 10 ) )
     502             :                 {
     503        7665 :                     diffuseness_vector_fx[j] = 0;
     504        7665 :                     move16();
     505             :                 }
     506             :             }
     507             : 
     508       60000 :             FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     509             :             {
     510       57600 :                 norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], ( L_sub( ONE_IN_Q30, L_shr( diffuseness_vector_fx[band_m_idx], sub( 30, diffuseness_vector_exp[band_m_idx] ) ) ) ) ); // q_factor_energy-1
     511             : 
     512       57600 :                 hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), hDirAC->direction_vector_m_fx[0][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32)
     513       57600 :                 move32();
     514       57600 :                 hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), hDirAC->direction_vector_m_fx[1][block_m_idx][band_m_idx] ); // Q (q_factor_energy + exp -32)
     515       57600 :                 move32();
     516       57600 :                 hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), hDirAC->direction_vector_m_fx[2][block_m_idx][band_m_idx] ); //  Q (q_factor_energy + exp -32)
     517       57600 :                 move32();
     518             : 
     519       57600 :                 diffuseness_m_fx[band_m_idx] = L_add( diffuseness_m_fx[band_m_idx], Mpy_32_32( reference_power_fx[ts][band_m_idx], L_shr( diffuseness_vector_fx[band_m_idx], sub( 30, diffuseness_vector_exp[band_m_idx] ) ) ) ); // Qq_factor_energy-1
     520       57600 :                 move32();
     521       57600 :                 renormalization_factor_diff_fx[band_m_idx] = L_add( renormalization_factor_diff_fx[band_m_idx], reference_power_fx[ts][band_m_idx] ); // Qq_factor_energy
     522       57600 :                 move32();
     523             :             }
     524             :         }
     525             : 
     526       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     527             :         {
     528       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     529             :             {
     530       43200 :                 dir_v[d] = hDirAC->direction_vector_m_fx[d][block_m_idx][band_m_idx];
     531       43200 :                 move32();
     532             :             }
     533       14400 :             dir_q = add( q_factor_energy, sub( exp, 32 ) );
     534       14400 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v, dir_q, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] );
     535             :         }
     536             :         /* Determine energy ratios */
     537       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     538             :         {
     539       14400 :             IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
     540             :             {
     541       12601 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &exp_div );
     542       12601 :                 move32();
     543             :             }
     544             :             ELSE
     545             :             {
     546        1799 :                 diffuseness_m_fx[band_m_idx] = 0;
     547        1799 :                 move32();
     548             :             }
     549       14400 :             exp_div = sub( 30, exp_div );
     550       14400 :             energyRatio[block_m_idx][band_m_idx] = L_sub( L_shl( 1, 30 ), L_shl( diffuseness_m_fx[band_m_idx], sub( 30, exp_div ) ) ); // Q30
     551       14400 :             move32();
     552             :         }
     553             : 
     554       15000 :         FOR( band_m_idx = 0; band_m_idx < hDirAC->nbands; band_m_idx++ )
     555             :         {
     556       14400 :             spreadCoherence[block_m_idx][band_m_idx] = 0;
     557       14400 :             move32();
     558       14400 :             surroundingCoherence[block_m_idx][band_m_idx] = 0;
     559       14400 :             move32();
     560             :         }
     561             :     }
     562             : 
     563         150 :     return;
     564             : }
     565             : 
     566             : 
     567             : /* Compute downmix */
     568         150 : static void ivas_dirac_dmx_fx(
     569             :     Word32 data_in_fx[][L_FRAME48k], /* Qx (same as the input Q) */
     570             :     const Word16 input_frame,
     571             :     const Word16 nchan_transport )
     572             : {
     573             :     Word16 i;
     574             :     Word32 data_out_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     575             : 
     576         150 :     IF( EQ_16( nchan_transport, 2 ) )
     577             :     {
     578         150 :         v_add_fx( data_in_fx[0], data_in_fx[1], data_out_fx[0], input_frame );
     579         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
     580             : 
     581             : #ifdef VEC_ARITH_OPT_v1
     582         150 :         v_sub_fixed_no_hdrm( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame );
     583             : #else  /* VEC_ARITH_OPT_v1 */
     584             :         v_sub_fixed( data_in_fx[0], data_in_fx[1], data_out_fx[1], input_frame, 0 );
     585             : #endif /* VEC_ARITH_OPT_v1 */
     586         150 :         v_multc_fixed( data_out_fx[1], ONE_IN_Q30, data_out_fx[1], input_frame );
     587             : 
     588         450 :         FOR( i = 0; i < nchan_transport; i++ )
     589             :         {
     590         300 :             Copy32( data_out_fx[i], data_in_fx[i], input_frame );
     591             :         }
     592             :     }
     593             :     /* output Q is same as input Q*/
     594         150 :     return;
     595             : }

Generated by: LCOV version 1.14