LCOV - code coverage report
Current view: top level - lib_enc - ivas_ism_param_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ cede165d26d1b794bfc5f5f6f9ec19d4d64a9a3b Lines: 277 286 96.9 %
Date: 2025-11-01 03:16:20 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <math.h>
      35             : #include <assert.h>
      36             : #include "options.h"
      37             : #include "ivas_prot_fx.h"
      38             : #include "prot_fx.h"
      39             : #include "cnst.h"
      40             : #include "ivas_cnst.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : /*-------------------------------------------------------------------------
      45             :  * Local function definitions
      46             :  *------------------------------------------------------------------------*/
      47             : 
      48       20720 : static void ivas_param_ism_compute_obj_parameters_fx(
      49             :     const Word16 nchan_ism,                                                                      /* i  : number of ISM channels     */
      50             :     Word64 reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX], /* i  : Reference power         Qx */
      51             :     PARAM_ISM_CONFIG_HANDLE hParamIsm                                                            /* i/o: Param ISM Enc Handle       */
      52             : )
      53             : {
      54             :     Word16 i, b, m, br, mr;
      55             :     Word16 brange_start, brange_end, mrange_start, mrange_end, time_merge_fac;
      56             :     Word16 power_ratios_m[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS];
      57             :     Word64 ref_power_local_frame[MAX_NUM_OBJECTS];
      58             :     Word64 tmp_ratio;
      59             :     Word16 e_tmp, tmp1, tmp2;
      60             :     Word64 Wtmp;
      61             : 
      62       20720 :     set64_fx( ref_power_local_frame, 0, MAX_NUM_OBJECTS );
      63             : 
      64       20720 :     assert( nchan_ism == 3 || nchan_ism == 4 );
      65             : 
      66      248640 :     FOR( b = 0; b < hParamIsm->nbands; b++ )
      67             :     {
      68             :         /* current frequency band borders */
      69      227920 :         brange_start = hParamIsm->band_grouping[b];
      70      227920 :         brange_end = hParamIsm->band_grouping[b + 1];
      71      227920 :         move16();
      72      227920 :         move16();
      73             : 
      74             :         /* time slots to aggregate for current block */
      75      227920 :         time_merge_fac = idiv1616( PARAM_ISM_MDFT_NO_SLOTS, hParamIsm->nblocks[b] );
      76             : 
      77      455840 :         FOR( m = 0; m < hParamIsm->nblocks[b]; m++ )
      78             :         {
      79             :             Word16 index_1, index_2;
      80             :             Word64 ref_power_local[MAX_NUM_OBJECTS];
      81             : 
      82             :             /* initialize to 0 so unused entries are not considered later */
      83      227920 :             set64_fx( ref_power_local, 0, MAX_NUM_OBJECTS );
      84             : 
      85             :             /* current block borders */
      86      227920 :             mrange_start = i_mult( m, time_merge_fac );
      87      227920 :             mrange_end = i_mult( add( m, 1 ), time_merge_fac );
      88             : 
      89             :             /* for each object, sum up reference power within current T/F tile */
      90             : 
      91     1065350 :             FOR( i = 0; i < nchan_ism; i++ )
      92             :             {
      93     4187150 :                 FOR( mr = mrange_start; mr < mrange_end; mr++ )
      94             :                 {
      95    76130000 :                     FOR( br = brange_start; br < brange_end; br++ )
      96             :                     {
      97    72780280 :                         ref_power_local[i] = W_add( ref_power_local[i], reference_power_obj[i][mr][br] ); // Qx
      98    72780280 :                         move64();
      99             :                     }
     100             :                 }
     101             :                 /* Sum up T/F tiles per object */
     102      837430 :                 ref_power_local_frame[i] = W_add( ref_power_local[i], ref_power_local_frame[i] ); // Qx
     103      837430 :                 move64();
     104             :             }
     105             : 
     106             :             /* find two dominant objects and derive object indices for current T/F tile */
     107      227920 :             IF( GE_64( ref_power_local[0], ref_power_local[1] ) )
     108             :             {
     109      108008 :                 index_1 = 0;
     110      108008 :                 index_2 = 1;
     111      108008 :                 move16();
     112      108008 :                 move16();
     113             :             }
     114             :             ELSE
     115             :             {
     116      119912 :                 index_1 = 1;
     117      119912 :                 index_2 = 0;
     118      119912 :                 move16();
     119      119912 :                 move16();
     120             :             }
     121             : 
     122      609510 :             FOR( i = MAX_PARAM_ISM_WAVE; i < nchan_ism; i++ )
     123             :             {
     124      381590 :                 IF( GT_64( ref_power_local[i], ref_power_local[index_1] ) )
     125             :                 {
     126       71885 :                     index_2 = index_1;
     127       71885 :                     index_1 = i;
     128       71885 :                     move16();
     129       71885 :                     move16();
     130             :                 }
     131      309705 :                 ELSE IF( GT_64( ref_power_local[i], ref_power_local[index_2] ) )
     132             :                 {
     133      107924 :                     index_2 = i;
     134      107924 :                     move16();
     135             :                 }
     136             :             }
     137             : 
     138             :             /* Copy the quantized indices */
     139      227920 :             hParamIsm->obj_indices[b][m][0] = index_1;
     140      227920 :             hParamIsm->obj_indices[b][m][1] = index_2;
     141      227920 :             move16();
     142      227920 :             move16();
     143             : 
     144             :             /* Compute power ratios */
     145      227920 :             IF( W_add( ref_power_local[index_1], ref_power_local[index_2] ) == 0 )
     146             :             {
     147           0 :                 power_ratios_m[b][m] = ONE_IN_Q14 /* 0.5 in Q15 */;
     148           0 :                 move16();
     149             :             }
     150             :             ELSE
     151             :             {
     152      227920 :                 tmp1 = W_norm( ref_power_local[index_1] );
     153      227920 :                 Wtmp = W_add( ref_power_local[index_1], ref_power_local[index_2] );
     154      227920 :                 tmp2 = W_norm( Wtmp );
     155      227920 :                 power_ratios_m[b][m] = BASOP_Util_Divide3232_Scale( W_extract_h( W_shl( ref_power_local[index_1], tmp1 ) ), W_extract_h( W_shl( Wtmp, tmp2 ) ), &e_tmp ); // ((Qx + tmp1) - 16) - ((Qx + tmp2) - 16) + 15 - e_tmp = 15 + tmp1 - tmp2 - e_tmp
     156      227920 :                 power_ratios_m[b][m] = shl_sat( power_ratios_m[b][m], sub( e_tmp, sub( tmp1, tmp2 ) ) );                                                                  // Q15
     157      227920 :                 move16();
     158      227920 :                 move16();
     159             :             }
     160      227920 :             assert( ( power_ratios_m[b][m] >= ONE_IN_Q14 /* 0.5 in Q15 */ ) && ( power_ratios_m[b][m] <= MAX_16 /* 1 in Q15 */ ) );
     161             : 
     162             :             /* Quantize power ratios */
     163             :             /* Power ratio range [0.5,1] is mapped to [0,1] first, rounding via truncation float->integer */
     164      227920 :             hParamIsm->power_ratios_idx[b][m] = extract_h( L_add( L_mult( shl( sub( power_ratios_m[b][m], ONE_IN_Q14 /* 0.5 in Q15 */ ), 1 ), ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ), ONE_IN_Q15 /* 0.5f in Q16 */ ) ); // Q0
     165      227920 :             move16();
     166      227920 :             assert( ( hParamIsm->power_ratios_idx[b][m] >= 0 ) && ( hParamIsm->power_ratios_idx[b][m] <= ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ) );
     167             :         }
     168             :     }
     169             : 
     170             :     /* Check if objects have roughly equal power by comparing reference power of first object against all others*/
     171       20720 :     hParamIsm->flag_equal_energy = 1;
     172       20720 :     move16();
     173       20917 :     FOR( i = 1; i < nchan_ism; i++ )
     174             :     {
     175       20916 :         IF( ref_power_local_frame[i] != 0 )
     176             :         {
     177       20916 :             tmp1 = W_norm( ref_power_local_frame[0] );
     178       20916 :             tmp2 = W_norm( ref_power_local_frame[i] );
     179       20916 :             tmp_ratio = BASOP_Util_Divide3232_Scale( W_extract_h( W_shl( ref_power_local_frame[0], tmp1 ) ), W_extract_h( W_shl( ref_power_local_frame[i], tmp2 ) ), &e_tmp ); // ((Qx + tmp1) - 16) - ((Qx + tmp2) - 16) + 15 - e_tmp = 15 + tmp1 - tmp2 - e_tmp
     180       20916 :             tmp_ratio = W_shl( tmp_ratio, sub( sub( e_tmp, 1 ), sub( tmp1, tmp2 ) ) );                                                                                         // Q14                                                                                        // Q14
     181             : 
     182       20916 :             test();
     183       20916 :             IF( GT_64( tmp_ratio, 15974 /* 0.975f in Q14 */ ) && LT_64( tmp_ratio, 16794 /* 1.025f in Q14*/ ) )
     184             :             {
     185         197 :                 hParamIsm->flag_equal_energy = s_and( hParamIsm->flag_equal_energy, 1 );
     186         197 :                 move16();
     187             :             }
     188             :             ELSE
     189             :             {
     190       20719 :                 hParamIsm->flag_equal_energy = s_and( hParamIsm->flag_equal_energy, 0 );
     191       20719 :                 move16();
     192       20719 :                 break;
     193             :             }
     194             :         }
     195             :     }
     196             : 
     197       20720 :     return;
     198             : }
     199             : 
     200             : 
     201       20720 : static void ivas_param_ism_enc_quantize_DOA_fx(
     202             :     const Word16 nchan_ism,                            /* i  : number of ISM channels                      */
     203             :     ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i  : ISM metadata             */
     204             :     PARAM_ISM_CONFIG_HANDLE hParamIsm                  /* i/o: Param ISM encoder handle */
     205             : )
     206             : {
     207             :     Word16 i, azi_idx, ele_idx;
     208             :     Word32 valQ_fx;
     209             : 
     210             :     /* Loop over objects */
     211       96850 :     FOR( i = 0; i < nchan_ism; i++ )
     212             :     {
     213             :         /* Quantize the elevation and obtain quantized elevation value and index */
     214       76130 :         ele_idx = ism_quant_meta_fx( hIsmMetaData[i]->elevation_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS );
     215             : 
     216             :         /* Obtain the index of quantized azimuth values */
     217       76130 :         azi_idx = ism_quant_meta_fx( hIsmMetaData[i]->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS );
     218             : 
     219             :         /*Replace azimuth with quantized values */
     220       76130 :         hIsmMetaData[i]->azimuth_fx = valQ_fx; // Q22
     221       76130 :         move32();
     222             : 
     223             :         /* Copy the quantized indices */
     224       76130 :         hParamIsm->azi_index[i] = azi_idx;
     225       76130 :         move16();
     226       76130 :         hParamIsm->ele_index[i] = ele_idx;
     227       76130 :         move16();
     228             :     }
     229             : 
     230       20720 :     return;
     231             : }
     232             : 
     233             : 
     234             : /*-------------------------------------------------------------------------*
     235             :  * ivas_param_ism_stereo_dmx()
     236             :  *
     237             :  * Downmix input channels to stereo
     238             :  *-------------------------------------------------------------------------*/
     239       20720 : void ivas_param_ism_stereo_dmx_fx(
     240             :     Encoder_Struct *st_ivas,       /* i  : IVAS encoder structure     */
     241             :     Word32 *data[MAX_NUM_OBJECTS], /* i/o: input signal/stereo dmx Qx */
     242             :     const Word16 input_frame       /* i  : Length of input frame      */
     243             : )
     244             : {
     245             :     Word16 i, j;
     246             :     Word32 tmp;
     247             :     Word16 alpha, azi_shift;
     248             :     Word16 tmp_1, tmp_2, one_by_input_frame;
     249             :     Word16 cardioid_left[MAX_NUM_OBJECTS], cardioid_right[MAX_NUM_OBJECTS]; // Q14
     250             :     Word32 stereo_dmx[2][L_FRAME48k];
     251             :     Word16 dmx_gain, dmx_gain_e;
     252             :     Word64 ene_data, ene_dmx;
     253             :     Word16 grad;
     254             :     Word16 last_dmx_gain, last_dmx_gain_e;
     255             :     Word16 last_cardioid_left; // Q14
     256             :     ISM_METADATA_HANDLE hIsmMetaData;
     257             : 
     258       20720 :     push_wmops( "ivas_param_ism_st_dmx" );
     259             : 
     260             :     /*Initialization*/
     261       20720 :     alpha = ONE_IN_Q14 /* 0.5 in Q15 */;
     262       20720 :     move16();
     263       20720 :     azi_shift = 0; // Q13
     264       20720 :     move16();
     265       20720 :     dmx_gain = 0;
     266       20720 :     move16();
     267       20720 :     ene_dmx = 0;
     268       20720 :     move64();
     269       20720 :     ene_data = 0;
     270       20720 :     move64();
     271       20720 :     last_dmx_gain = st_ivas->hParamIsm->last_dmx_gain_fx;
     272       20720 :     move16();
     273       20720 :     last_dmx_gain_e = st_ivas->hParamIsm->last_dmx_gain_e;
     274       20720 :     move16();
     275             : 
     276             :     /* Set the stereo dmx to zero */
     277       20720 :     set_zero_fx( stereo_dmx[0], L_FRAME48k );
     278       20720 :     set_zero_fx( stereo_dmx[1], L_FRAME48k );
     279             : 
     280       20720 :     one_by_input_frame = BASOP_Util_Divide1616_Scale( 1, input_frame, &tmp_1 );
     281       20720 :     one_by_input_frame = shl( one_by_input_frame, tmp_1 ); // Q15
     282             : 
     283             :     /* Loop over all objects */
     284       96850 :     FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
     285             :     {
     286       76130 :         hIsmMetaData = st_ivas->hIsmMetaData[i];
     287       76130 :         last_cardioid_left = st_ivas->hParamIsm->last_cardioid_left_fx[i];
     288       76130 :         move16();
     289             :         /*Compute the Cardioids for the corresponding object direction */
     290       76130 :         tmp = Mpy_32_32( hIsmMetaData->azimuth_fx, PI_OVER_180_FX ); // Q22
     291       76130 :         tmp_1 = add( EVS_PI_BY_2_FX, azi_shift );                    // Q13
     292       76130 :         tmp = L_sub( L_shr( tmp, Q22 - Q13 ), L_deposit_l( tmp_1 ) );
     293       76130 :         IF( LT_32( tmp, -EVS_PI_FX ) )
     294             :         {
     295       18065 :             tmp = L_add( tmp, 2 * EVS_PI_FX );
     296             :         }
     297       76130 :         cardioid_left[i] = add( shr( alpha, 1 ), mult( sub( ONE_IN_Q15 - 1, alpha ), getCosWord16( extract_l( tmp ) ) ) ); // Q14
     298       76130 :         move16();
     299             : 
     300       76130 :         IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 )
     301             :         {
     302             :             Word16 last_cardioid_right;
     303       76066 :             last_cardioid_right = sub( ONE_IN_Q14 /* 1.0f in Q14 */, last_cardioid_left );
     304             :             /* Smoothing */
     305       76066 :             cardioid_left[i] = add( mult( 24576 /* 0.75f in Q15 */, cardioid_left[i] ), mult( 8192 /* 0.25f in Q15 */, last_cardioid_left ) ); // Q14
     306       76066 :             move16();
     307       76066 :             Word32 grad_32 = L_mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14+Q16 = Q30 */ /* for the right cardioid, multiply with -1 */
     308             :             /* Cardioids sum up to 1 */
     309       76066 :             cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */
     310       76066 :             move16();
     311             :             /* Loop over all samples */
     312    36587746 :             FOR( j = 0; j < ( input_frame >> 1 ); j++ )
     313             :             {
     314    36511680 :                 tmp = data[i][j];
     315    36511680 :                 move32();
     316    36511680 :                 tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_left, L_shr( Mpy_32_32( L_shl( j, 22 ), grad_32 ), 7 ) ) ), 15 ) ); /* Qx DMX Left */
     317    36511680 :                 stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp );                                                                                    /* Qx DMX Left */
     318    36511680 :                 move32();
     319    36511680 :                 tmp = data[i][j];
     320    36511680 :                 move32();
     321    36511680 :                 tmp = W_extract_l( W_shr( W_mult_32_32( tmp, L_add( last_cardioid_right, L_shr( L_negate( Mpy_32_32( L_shl( j, 22 ), grad_32 ) ), 7 ) ) ), 15 ) ); /* Qx DMX Right */
     322    36511680 :                 stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp );                                                                                                 /* Qx DMX Right */
     323    36511680 :                 move32();
     324    36511680 :                 ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */
     325             :             }
     326    36587746 :             FOR( ; j < input_frame; j++ )
     327             :             {
     328    36511680 :                 tmp = data[i][j];
     329    36511680 :                 move32();
     330    36511680 :                 tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); /* Qx DMX Left  */
     331    36511680 :                 stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp );                       /* Qx DMX Left  */
     332    36511680 :                 move32();
     333    36511680 :                 tmp = data[i][j];
     334    36511680 :                 move32();
     335    36511680 :                 tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); /* Qx DMX Right */
     336    36511680 :                 stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp );                        /* Qx DMX Right */
     337    36511680 :                 move32();
     338    36511680 :                 ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */
     339             :             }
     340             :         }
     341             :         ELSE
     342             :         {
     343             :             /* Cardioids sum up to 1 */
     344          64 :             cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */
     345          64 :             move16();
     346             :             /* Loop over all samples */
     347       61504 :             FOR( j = 0; j < input_frame; j++ )
     348             :             {
     349       61440 :                 tmp = data[i][j];
     350       61440 :                 move32();
     351       61440 :                 tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); /* Qx DMX Left  */
     352       61440 :                 stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp );                       /* Qx DMX Left  */
     353       61440 :                 move32();
     354       61440 :                 tmp = data[i][j];
     355       61440 :                 move32();
     356       61440 :                 tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); /* Qx DMX Right */
     357       61440 :                 stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp );                        /* Qx DMX Right */
     358       61440 :                 move32();
     359       61440 :                 ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1  energy of all objects combined */
     360             :             }
     361             :         }
     362       76130 :         st_ivas->hParamIsm->last_cardioid_left_fx[i] = cardioid_left[i]; // Q14
     363       76130 :         move16();
     364             :     }
     365             : 
     366             :     /* Energy compensation */
     367    19911920 :     FOR( j = 0; j < input_frame; j++ )
     368             :     {
     369    19891200 :         ene_dmx = W_mac_32_32( W_mac_32_32( ene_dmx, stereo_dmx[0][j], stereo_dmx[0][j] ), stereo_dmx[1][j], stereo_dmx[1][j] ); /* 2 * Qx + 1 */
     370             :     }
     371       20720 :     tmp_1 = W_norm( ene_data );
     372       20720 :     tmp_2 = W_norm( ene_dmx );
     373       20720 :     ene_data = W_shl( ene_data, tmp_1 );
     374       20720 :     ene_dmx = W_shl( ene_dmx, tmp_2 );
     375       20720 :     dmx_gain = BASOP_Util_Divide3232_Scale( W_extract_h( ene_data ), L_add_sat( W_extract_h( ene_dmx ), 1 ), &dmx_gain_e );
     376       20720 :     dmx_gain_e = sub( dmx_gain_e, sub( tmp_1, tmp_2 ) );
     377       20720 :     dmx_gain = Sqrt16( dmx_gain, &dmx_gain_e );
     378             : 
     379             :     /* Smoothing */
     380       20720 :     IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 )
     381             :     {
     382       20703 :         dmx_gain_e = BASOP_Util_Add_MantExp( mult( 24576 /* 0.75f */, dmx_gain ), dmx_gain_e, mult( 8192 /* 0.25f */, last_dmx_gain ), last_dmx_gain_e, &dmx_gain );
     383             :         /* 10ms ramp */
     384       20703 :         tmp = L_shl( last_dmx_gain, last_dmx_gain_e );                                                                                                          // Q15
     385       20703 :         grad = extract_l( Mpy_32_16_r( L_sub( L_shl( dmx_gain, dmx_gain_e ), tmp ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ) ); /* Q15 */ /* slope between two consecutive gains, 480 samples length */
     386             : 
     387       20703 :         tmp_1 = 15 + 1;
     388       20703 :         move16();
     389     9958143 :         FOR( i = 0; i < ( input_frame >> 1 ); i++ )
     390             :         {
     391     9937440 :             stereo_dmx[0][i] = W_extract_l( W_shr( W_mult_32_32( stereo_dmx[0][i], L_add( tmp, mult0( i, grad ) ) ), tmp_1 ) ); // Qx
     392     9937440 :             move32();
     393     9937440 :             stereo_dmx[1][i] = W_extract_l( W_shr( W_mult_32_32( stereo_dmx[1][i], L_add( tmp, mult0( i, grad ) ) ), tmp_1 ) ); // Qx
     394     9937440 :             move32();
     395             :         }
     396       20703 :         tmp_1 = add( sub( 15, dmx_gain_e ), 1 );
     397     9958143 :         FOR( ; i < input_frame; i++ )
     398             :         {
     399     9937440 :             stereo_dmx[0][i] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[0][i], dmx_gain ), tmp_1 ) ); // Qx
     400     9937440 :             move32();
     401     9937440 :             stereo_dmx[1][i] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[1][i], dmx_gain ), tmp_1 ) ); // Qx
     402     9937440 :             move32();
     403             :         }
     404             :     }
     405             :     ELSE
     406             :     {
     407          17 :         tmp_1 = add( sub( 15, dmx_gain_e ), 1 );
     408       16337 :         FOR( j = 0; j < input_frame; j++ )
     409             :         {
     410       16320 :             stereo_dmx[0][j] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[0][j], dmx_gain ), tmp_1 ) ); // Qx
     411       16320 :             move32();
     412       16320 :             stereo_dmx[1][j] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[1][j], dmx_gain ), tmp_1 ) ); // Qx
     413       16320 :             move32();
     414             :         }
     415             :     }
     416       20720 :     st_ivas->hParamIsm->last_dmx_gain_fx = dmx_gain;
     417       20720 :     move16();
     418       20720 :     st_ivas->hParamIsm->last_dmx_gain_e = dmx_gain_e;
     419       20720 :     move16();
     420             : 
     421             :     /* Copy the stereo dmx to data variable */
     422       20720 :     Copy32( stereo_dmx[0], data[0], input_frame ); // Qx
     423       20720 :     Copy32( stereo_dmx[1], data[1], input_frame ); // Qx
     424             : 
     425       20720 :     pop_wmops();
     426             : 
     427       20720 :     return;
     428             : }
     429             : 
     430             : 
     431             : /*-------------------------------------------------------------------------*
     432             :  * ivas_param_ism_enc_open()
     433             :  *
     434             :  * Open Param ISM handle
     435             :  *-------------------------------------------------------------------------*/
     436             : 
     437         320 : ivas_error ivas_param_ism_enc_open_fx(
     438             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure     */
     439             : )
     440             : {
     441             :     Word16 i;
     442             :     IVAS_FB_CFG *fb_cfg;
     443             :     PARAM_ISM_CONFIG_HANDLE hParamIsm;
     444             :     Word16 max_bins;
     445             :     Word32 input_Fs;
     446             :     ivas_error error;
     447             : 
     448         320 :     error = IVAS_ERR_OK;
     449         320 :     move32();
     450             : 
     451             :     /* Assign memory to Param Object handle */
     452         320 :     if ( ( hParamIsm = (PARAM_ISM_CONFIG_HANDLE) malloc( sizeof( PARAM_ISM_CONFIG_DATA ) ) ) == NULL )
     453             :     {
     454           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM\n" ) );
     455             :     }
     456             : 
     457         320 :     input_Fs = st_ivas->hEncoderConfig->input_Fs;
     458         320 :     move32();
     459             : 
     460             : 
     461             :     /* set FB config. */
     462         320 :     IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, ISM_FORMAT, st_ivas->hEncoderConfig->nchan_inp, 0, 0, input_Fs, 0 ) ), IVAS_ERR_OK ) )
     463             :     {
     464           0 :         return error;
     465             :     }
     466             : 
     467             :     /* Allocate and initialize FB mixer handle */
     468         320 :     IF( NE_32( ( error = ivas_FB_mixer_open_fx( &( hParamIsm->hFbMixer ), input_Fs, fb_cfg, 0 ) ), IVAS_ERR_OK ) )
     469             :     {
     470           0 :         return error;
     471             :     }
     472             : 
     473         320 :     ivas_param_ism_config_fx( hParamIsm, st_ivas->hEncoderConfig->nchan_inp );
     474             : 
     475             :     /* Assign memories for Band and Block grouping  */
     476         320 :     hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
     477         320 :     move16();
     478             : 
     479         320 :     max_bins = extract_l( Mpy_32_32( input_Fs, 10737418 /*240/48000.Q31*/ ) ); // (int16_t) ( ( MDFT_FB_BANDS_240 * input_Fs ) / 48000 );
     480        4160 :     FOR( i = 0; i < ( hParamIsm->nbands + 1 ); i++ )
     481             :     {
     482        3840 :         hParamIsm->band_grouping[i] = CLDFB_TO_MDFT_FAC * Param_ISM_band_grouping[i];
     483        3840 :         move16();
     484        3840 :         IF( GT_16( i_mult( Param_ISM_band_grouping[i], CLDFB_TO_MDFT_FAC ), max_bins ) )
     485             :         {
     486         320 :             hParamIsm->band_grouping[i] = max_bins;
     487         320 :             move16();
     488             :         }
     489             :     }
     490             : 
     491         320 :     set16_fx( hParamIsm->noisy_speech_buffer, 0, PARAM_ISM_HYS_BUF_SIZE );
     492             : 
     493         320 :     st_ivas->hParamIsm = hParamIsm;
     494             : 
     495         320 :     return error;
     496             : }
     497             : 
     498             : 
     499             : /*-------------------------------------------------------------------------*
     500             :  * ivas_param_ism_enc_close()
     501             :  *
     502             :  * Close Param ISM encoder handle
     503             :  *-------------------------------------------------------------------------*/
     504             : 
     505         934 : void ivas_param_ism_enc_close_fx(
     506             :     PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle   */
     507             :     const Word32 input_Fs               /* i  : input sampling_rate       */
     508             : )
     509             : {
     510         934 :     test();
     511         934 :     IF( hParamIsm == NULL || *hParamIsm == NULL )
     512             :     {
     513         614 :         return;
     514             :     }
     515             : 
     516         320 :     ivas_FB_mixer_close_fx( &( *hParamIsm )->hFbMixer, input_Fs, 0 );
     517             : 
     518         320 :     free( ( *hParamIsm ) );
     519         320 :     ( *hParamIsm ) = NULL;
     520             : 
     521         320 :     return;
     522             : }
     523             : 
     524             : 
     525             : /*-------------------------------------------------------------------------*
     526             :  * ivas_param_ism_enc()
     527             :  *
     528             :  * Parametric ISM encoder
     529             :  *-------------------------------------------------------------------------*/
     530             : 
     531       20720 : void ivas_param_ism_enc_fx(
     532             :     Encoder_Struct *st_ivas,       /* i/o: IVAS encoder structure          */
     533             :     Word32 *data[MAX_NUM_OBJECTS], /* i  : input signal           q_pcm_in */
     534             :     const Word16 input_frame       /* i  : input frame length per channel  */
     535             : )
     536             : {
     537             :     Word16 i, j, ts, l_ts;
     538             :     Word16 nchan_ism;
     539             :     Word16 num_time_slots;
     540             :     Word16 q_p_fb_Buffer;
     541             :     Word32 *pcm_in[MAX_NUM_OBJECTS];
     542             :     Word32 fb_RealBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX];
     543             :     Word32 fb_ImagBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX];
     544             :     Word32 *p_fb_RealBuffer[MAX_NUM_OBJECTS];
     545             :     Word32 *p_fb_ImagBuffer[MAX_NUM_OBJECTS];
     546             :     Word64 reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX];
     547             :     PARAM_ISM_CONFIG_HANDLE hParamIsm;
     548             : 
     549       20720 :     nchan_ism = st_ivas->hEncoderConfig->nchan_ism;
     550       20720 :     move16();
     551       20720 :     hParamIsm = st_ivas->hParamIsm;
     552             : 
     553       20720 :     push_wmops( "ivas_param_ism_enc" );
     554             : 
     555       20720 :     l_ts = shr( input_frame, 2 ); /* input_frame / PARAM_ISM_MDFT_NO_SLOTS */
     556       20720 :     num_time_slots = PARAM_ISM_MDFT_NO_SLOTS;
     557       20720 :     move16();
     558             : 
     559       96850 :     FOR( i = 0; i < nchan_ism; i++ )
     560             :     {
     561       76130 :         pcm_in[i] = data[i];
     562             : 
     563       76130 :         set_zero_fx( fb_RealBuffer[i], DIRAC_NO_FB_BANDS_MAX );
     564       76130 :         set_zero_fx( fb_ImagBuffer[i], DIRAC_NO_FB_BANDS_MAX );
     565       76130 :         p_fb_RealBuffer[i] = &fb_RealBuffer[i][0];
     566       76130 :         p_fb_ImagBuffer[i] = &fb_ImagBuffer[i][0];
     567             :     }
     568             : 
     569       20720 :     Word16 gb = find_guarded_bits_fx( l_ts );
     570       20720 :     q_p_fb_Buffer = sub( st_ivas->q_data_fx, gb );
     571             : 
     572      103600 :     FOR( ts = 0; ts < num_time_slots; ts++ )
     573             :     {
     574       82880 :         ivas_fb_mixer_get_windowed_fr_fx( hParamIsm->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans, gb );
     575             : 
     576       82880 :         ivas_fb_mixer_update_prior_input_fx( hParamIsm->hFbMixer, pcm_in, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans );
     577             : 
     578      387400 :         FOR( i = 0; i < nchan_ism; i++ )
     579             :         {
     580      304520 :             pcm_in[i] += l_ts;
     581    73389320 :             FOR( j = 0; j < DIRAC_NO_FB_BANDS_MAX; j++ )
     582             :             {
     583    73084800 :                 reference_power_obj[i][ts][j] = W_shr( W_add( W_mult0_32_32( fb_RealBuffer[i][j], fb_RealBuffer[i][j] ), W_mult0_32_32( fb_ImagBuffer[i][j], fb_ImagBuffer[i][j] ) ), shl( q_p_fb_Buffer, 1 ) ); // Q0
     584    73084800 :                 move64();
     585             :             }
     586             :         }
     587             :     }
     588             : 
     589       20720 :     ivas_param_ism_enc_quantize_DOA_fx( nchan_ism, st_ivas->hIsmMetaData, hParamIsm );
     590             : 
     591       20720 :     ivas_param_ism_compute_obj_parameters_fx( nchan_ism, reference_power_obj, hParamIsm );
     592             : 
     593       20720 :     pop_wmops();
     594       20720 :     return;
     595             : }
     596             : 
     597             : 
     598             : /*-------------------------------------------------------------------*
     599             :  * ivas_param_ism_compute_noisy_speech_flag()
     600             :  *
     601             :  *
     602             :  *-------------------------------------------------------------------*/
     603             : 
     604       20720 : void ivas_param_ism_compute_noisy_speech_flag_fx(
     605             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure          */
     606             : )
     607             : {
     608             :     Word16 i;
     609             : 
     610             :     /* Move the Noisy speech buffer */
     611      207200 :     FOR( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ )
     612             :     {
     613      186480 :         st_ivas->hParamIsm->noisy_speech_buffer[i] = st_ivas->hParamIsm->noisy_speech_buffer[i + 1];
     614      186480 :         move16();
     615             :     }
     616             : 
     617             :     /* Set flag_noisy_speech to 0 for cases where object energies are not roughly equal */
     618       20720 :     IF( !st_ivas->hParamIsm->flag_equal_energy )
     619             :     {
     620       20719 :         st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
     621       20719 :         st_ivas->hParamIsm->flag_noisy_speech = 0;
     622       20719 :         move16();
     623       20719 :         move16();
     624             :     }
     625             :     ELSE
     626             :     {
     627             :         /* For the current frame, make a decision based on some core-coder flags */
     628           1 :         test();
     629           1 :         IF( st_ivas->hSCE[0]->hCoreCoder[0]->flag_noisy_speech_snr && st_ivas->hSCE[1]->hCoreCoder[0]->flag_noisy_speech_snr )
     630             :         {
     631           1 :             test();
     632           1 :             IF( st_ivas->hSCE[0]->hCoreCoder[0]->vad_flag || st_ivas->hSCE[1]->hCoreCoder[0]->vad_flag )
     633             :             {
     634           0 :                 st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
     635           0 :                 move16();
     636             :             }
     637             :             ELSE
     638             :             {
     639           1 :                 st_ivas->hParamIsm->noisy_speech_buffer[i] = 1;
     640           1 :                 move16();
     641             :             }
     642             :         }
     643             :         ELSE
     644             :         {
     645           0 :             st_ivas->hParamIsm->noisy_speech_buffer[i] = 0;
     646           0 :             move16();
     647             :         }
     648             : 
     649             :         /* Do a decision based on hysteresis */
     650           1 :         st_ivas->hParamIsm->flag_noisy_speech = 1;
     651           1 :         move16();
     652          11 :         FOR( i = 0; i < PARAM_ISM_HYS_BUF_SIZE; i++ )
     653             :         {
     654          10 :             test();
     655          10 :             st_ivas->hParamIsm->flag_noisy_speech = st_ivas->hParamIsm->flag_noisy_speech && st_ivas->hParamIsm->noisy_speech_buffer[i];
     656             :         }
     657             :     }
     658             : 
     659       20720 :     return;
     660             : }

Generated by: LCOV version 1.14