LCOV - code coverage report
Current view: top level - lib_enc - ivas_enc_cov_handler_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 221 252 87.7 %
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 <stdint.h>
      34             : #include "options.h"
      35             : #include "prot_fx.h"
      36             : #include "ivas_rom_com.h"
      37             : #include "wmc_auto.h"
      38             : #include "ivas_prot_fx.h"
      39             : 
      40             : /*------------------------------------------------------------------------------------------*
      41             :  * Local constants
      42             :  *------------------------------------------------------------------------------------------*/
      43             : 
      44             : #define MIN_POOL_SIZE           24
      45             : #define MIN_POOL_SIZE_DTX       40
      46             : #define MAX_UPDATE_RATE_Q31     ( 1717986944 )
      47             : #define MAX_UPDATE_RATE_DTX_Q31 ( 858993472 )
      48             : 
      49             : 
      50             : /*------------------------------------------------------------------------------------------*
      51             :  * Local functions declarations
      52             :  *------------------------------------------------------------------------------------------*/
      53             : 
      54             : static void ivas_band_cov_fx( Word32 **ppIn_FR_real, Word32 **ppIn_FR_imag, Word16 q_In_FR, const Word16 num_chans, const Word16 num_bins, Word16 stride, Word32 **pFb_bin_to_band, const Word16 *pFb_start_bin_per_band, const Word16 *pFb_active_bins_per_band, const Word16 start_band, const Word16 end_band, Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], Word16 *q_cov_real[IVAS_SPAR_MAX_CH], const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] );
      55             : 
      56             : /*-------------------------------------------------------------------------
      57             :  * ivas_spar_covar_enc_open_fx()
      58             :  *
      59             :  * Allocate and initialize SPAR Covar. encoder handle
      60             :  *------------------------------------------------------------------------*/
      61             : 
      62        1606 : ivas_error ivas_spar_covar_enc_open_fx(
      63             :     ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle                  */
      64             :     ivas_filterbank_t *pFb,                 /* i/o: FB handle                                                   */
      65             :     const Word32 input_Fs,                  /* i  : input sampling rate                                 Q0*/
      66             :     const Word16 nchan_inp,                 /* i  : number of input channels                    Q0*/
      67             :     const COV_SMOOTHING_TYPE smooth_mode,   /* i  : Smooth covariance for SPAR or MC    */
      68             :     const Word32 ivas_total_brate           /* i  : IVAS total bitrate                                  Q0*/
      69             : )
      70             : {
      71             :     ivas_enc_cov_handler_state_t *hCovState;
      72             :     ivas_cov_smooth_cfg_t cov_smooth_cfg;
      73             :     ivas_error error;
      74             : 
      75        1606 :     error = IVAS_ERR_OK;
      76        1606 :     move32();
      77             : 
      78        1606 :     IF( ( hCovState = (ivas_enc_cov_handler_state_t *) malloc( sizeof( ivas_enc_cov_handler_state_t ) ) ) == NULL )
      79             :     {
      80           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder" );
      81             :     }
      82             : 
      83        1606 :     cov_smooth_cfg.max_bands = IVAS_MAX_NUM_BANDS;
      84        1606 :     move16();
      85        1606 :     cov_smooth_cfg.max_update_rate_fx = MAX_UPDATE_RATE_Q31;
      86        1606 :     move32();
      87        1606 :     cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE;
      88        1606 :     move16();
      89        1606 :     IF( EQ_32( smooth_mode, COV_SMOOTH_MC ) )
      90             :     {
      91          48 :         cov_smooth_cfg.max_update_rate_fx = ONE_IN_Q31; // Q31
      92          48 :         move32();
      93          48 :         cov_smooth_cfg.min_pool_size = 20; // Q0
      94          48 :         move16();
      95             :     }
      96             : 
      97        1606 :     IF( NE_32( ( error = ivas_spar_covar_smooth_enc_open_fx( &hCovState->pCov_state, &cov_smooth_cfg, pFb, nchan_inp, smooth_mode, ivas_total_brate ) ), IVAS_ERR_OK ) )
      98             :     {
      99           0 :         return error;
     100             :     }
     101             : 
     102        1606 :     cov_smooth_cfg.max_update_rate_fx = MAX_UPDATE_RATE_DTX_Q31;
     103        1606 :     move32();
     104        1606 :     cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE_DTX;
     105        1606 :     move16();
     106             : 
     107        1606 :     IF( NE_32( ( error = ivas_spar_covar_smooth_enc_open_fx( &hCovState->pCov_dtx_state, &cov_smooth_cfg, pFb, nchan_inp, smooth_mode, ivas_total_brate ) ), IVAS_ERR_OK ) )
     108             :     {
     109           0 :         return error;
     110             :     }
     111             : 
     112        1606 :     hCovState->num_bins = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
     113        1606 :     hCovState->prior_dtx_present = 0;
     114        1606 :     move16();
     115             : 
     116        1606 :     set_zero_fx( hCovState->bb_var_lt_fx, FOA_CHANNELS );
     117        1606 :     hCovState->prior_var_flag = -1;
     118        1606 :     move16();
     119             : 
     120        1606 :     *hCovEnc = hCovState;
     121             : 
     122        1606 :     return error;
     123             : }
     124             : 
     125             : 
     126             : /*-------------------------------------------------------------------------
     127             :  * ivas_spar_covar_enc_close_fx()
     128             :  *
     129             :  * Deallocate SPAR Covar. encoder handle
     130             :  *------------------------------------------------------------------------*/
     131             : 
     132        1606 : void ivas_spar_covar_enc_close_fx(
     133             :     ivas_enc_cov_handler_state_t **hCovEnc, /* i/o: SPAR Covar. encoder handle    */
     134             :     const Word16 nchan_inp                  /* i  : number of input channels      Q0*/
     135             : )
     136             : {
     137             :     ivas_enc_cov_handler_state_t *hCovState;
     138             : 
     139        1606 :     test();
     140        1606 :     IF( hCovEnc == NULL || *hCovEnc == NULL )
     141             :     {
     142           0 :         return;
     143             :     }
     144             : 
     145        1606 :     hCovState = *hCovEnc;
     146             : 
     147        1606 :     ivas_spar_covar_smooth_enc_close_fx( &hCovState->pCov_state, nchan_inp );
     148             : 
     149        1606 :     ivas_spar_covar_smooth_enc_close_fx( &hCovState->pCov_dtx_state, nchan_inp );
     150             : 
     151        1606 :     free( *hCovEnc );
     152        1606 :     *hCovEnc = NULL;
     153             : 
     154        1606 :     return;
     155             : }
     156             : 
     157             : 
     158             : /*-----------------------------------------------------------------------------------------*
     159             :  * Function ivas_spar_get_activeW_flag_fx()
     160             :  *
     161             :  *
     162             :  *-----------------------------------------------------------------------------------------*/
     163             : 
     164       72649 : static Word16 ivas_spar_get_activeW_flag_fx(
     165             :     ivas_enc_cov_handler_state_t *hCovEnc,
     166             :     Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],     /* q_cov_real */
     167             :     Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */
     168             :     Word16 *q_cov_real[IVAS_SPAR_MAX_CH],
     169             :     const Word16 dtx_vad,         /* Q0 */
     170             :     const Word16 nchan_inp,       /* Q0 */
     171             :     const Word16 nchan_transport, /* Q0 */
     172             :     Word16 *res_ind,              /* Q0 */
     173             :     const Word16 *dmx_order       /* Q0 */
     174             : )
     175             : {
     176             :     Word16 b, ch, num_bands, num_chs, activeW_flag;
     177             :     Word32 bb_var[FOA_CHANNELS], sm_fact, side_ch_var, en_ratio;
     178             :     Word64 bb_var_64bit[FOA_CHANNELS];
     179             :     Word16 q_shift;
     180             :     Word16 q_bb_var[FOA_CHANNELS];
     181             :     Word32 L_tmp, L_tmp1;
     182             :     Word16 exp_diff, q_com, guard_bits;
     183             : 
     184       72649 :     num_chs = s_min( nchan_inp, FOA_CHANNELS );                   /* Q0 */
     185       72649 :     num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); /* Q0 */
     186             : 
     187       72649 :     set_zero_fx( bb_var, FOA_CHANNELS );
     188       72649 :     set_s( q_bb_var, Q31, FOA_CHANNELS );
     189      363245 :     FOR( ch = 0; ch < FOA_CHANNELS; ch++ )
     190             :     {
     191      290596 :         bb_var_64bit[ch] = 0;
     192      290596 :         move64();
     193             :     }
     194             : 
     195       72649 :     IF( EQ_16( dtx_vad, 1 ) )
     196             :     {
     197      355795 :         FOR( ch = 0; ch < num_chs; ch++ )
     198             :         {
     199     3700268 :             FOR( b = 0; b < num_bands; b++ )
     200             :             {
     201     3415632 :                 bb_var_64bit[ch] = W_add_nosat( bb_var_64bit[ch], W_deposit32_l( cov_real[ch][ch][b] ) ); // q_cov_real[ch][ch]
     202     3415632 :                 move64();
     203     3415632 :                 q_bb_var[ch] = q_cov_real[ch][ch];
     204     3415632 :                 move16();
     205             :             }
     206             :         }
     207             :     }
     208             :     ELSE
     209             :     {
     210        7450 :         FOR( ch = 0; ch < num_chs; ch++ )
     211             :         {
     212       77480 :             FOR( b = 0; b < num_bands; b++ )
     213             :             {
     214       71520 :                 bb_var_64bit[ch] = W_add_nosat( bb_var_64bit[ch], W_deposit32_l( cov_dtx_real[ch][ch][b] ) ); // q_cov_real[ch][ch]
     215       71520 :                 move64();
     216       71520 :                 q_bb_var[ch] = q_cov_real[ch][ch];
     217       71520 :                 move16();
     218             :             }
     219             :         }
     220             :     }
     221             : 
     222      363245 :     FOR( ch = 0; ch < num_chs; ch++ )
     223             :     {
     224      290596 :         q_shift = Q31;
     225      290596 :         move16();
     226      290596 :         q_shift = W_norm( bb_var_64bit[ch] );
     227      290596 :         bb_var[ch] = W_extract_l( W_shl_nosat( bb_var_64bit[ch], sub( q_shift, 32 ) ) ); /* q_bb_var[ch] + sub( q_shift, 32 ) */
     228      290596 :         move32();
     229      290596 :         q_bb_var[ch] = add( q_bb_var[ch], sub( q_shift, 32 ) );
     230      290596 :         move16();
     231             :     }
     232             : 
     233       72649 :     IF( EQ_16( hCovEnc->prior_var_flag, -1 ) )
     234             :     {
     235      363245 :         FOR( ch = 0; ch < num_chs; ch++ )
     236             :         {
     237      290596 :             hCovEnc->bb_var_lt_fx[ch] = bb_var[ch]; // q_bb_var[ch]
     238      290596 :             move32();
     239             :         }
     240             :     }
     241             :     ELSE
     242             :     {
     243           0 :         sm_fact = ONE_IN_Q30; // Q31
     244           0 :         move32();
     245           0 :         FOR( ch = 0; ch < num_chs; ch++ )
     246             :         {
     247           0 :             L_tmp = Mpy_32_32( sm_fact, hCovEnc->bb_var_lt_fx[ch] );        // (Q31, q_bb_var[ch]) -> q_bb_var[ch]
     248           0 :             L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, sm_fact ), bb_var[ch] ); // (Q31, q_bb_var[ch]) -> q_bb_var[ch]
     249           0 :             hCovEnc->bb_var_lt_fx[ch] = L_add( L_tmp, L_tmp1 );             // q_bb_var[ch]
     250           0 :             move32();
     251             :         }
     252             :     }
     253             : 
     254       72649 :     side_ch_var = L_deposit_l( EPSILLON_FX ); // Note: To handle divide-by-0 asserts
     255       72649 :     guard_bits = find_guarded_bits_fx( L_deposit_l( sub( num_chs, nchan_transport ) ) );
     256       72649 :     q_com = Q20;
     257       72649 :     move16();
     258      185468 :     FOR( ch = nchan_transport; ch < num_chs; ch++ )
     259             :     {
     260      112819 :         q_com = s_min( q_com, q_bb_var[dmx_order[ch]] );
     261             :     }
     262      185468 :     FOR( ch = nchan_transport; ch < num_chs; ch++ )
     263             :     {
     264      112819 :         side_ch_var = L_add( side_ch_var, L_shr( L_shl( hCovEnc->bb_var_lt_fx[dmx_order[ch]], sub( q_com, q_bb_var[dmx_order[ch]] ) ), guard_bits ) ); // Q(q_com - guard_bits)
     265             :     }
     266             : 
     267       72649 :     IF( LT_32( side_ch_var, L_shl( L_mult0( IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH_Q0, IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH_Q0 ), sub( q_com, guard_bits ) ) ) ) // LHS Q(q_com - guard_bits) :: RHS Q(q_com - guard_bits)
     268             :     {
     269        2437 :         activeW_flag = 0;
     270        2437 :         move16();
     271             :     }
     272             :     ELSE
     273             :     {
     274       70212 :         L_tmp = BASOP_Util_Divide3232_Scale_newton( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff );        // (Q31 - exp_diff)
     275       70212 :         en_ratio = L_shl_sat( L_tmp, exp_diff );                                                               // Q31
     276       70212 :         IF( LT_32( en_ratio, Mpy_32_32( IVAS_SPAR_DYN_ACTIVEW_THRESH_FX, IVAS_SPAR_DYN_ACTIVEW_THRESH_FX ) ) ) // LHS Q31 :: RHS Q31
     277             :         {
     278           0 :             activeW_flag = 1;
     279           0 :             move16();
     280             :         }
     281             :         ELSE
     282             :         {
     283       70212 :             activeW_flag = 0;
     284       70212 :             move16();
     285             :         }
     286             :     }
     287             : 
     288       72649 :     IF( activeW_flag )
     289             :     {
     290           0 :         *res_ind = 0;
     291           0 :         move16();
     292           0 :         IF( EQ_16( nchan_transport, 2 ) )
     293             :         {
     294             :             Word16 max_idx;
     295             :             Word32 max_val;
     296           0 :             max_idx = nchan_transport; /* Q0 */
     297           0 :             move16();
     298           0 :             max_val = hCovEnc->bb_var_lt_fx[max_idx]; // q_bb_var[max_idx]
     299           0 :             move32();
     300           0 :             FOR( ch = nchan_transport; ch < num_chs; ch++ ){
     301           0 :                 IF( GT_32( hCovEnc->bb_var_lt_fx[ch], max_val ) ){
     302           0 :                     max_idx = ch;
     303           0 :             move16();
     304           0 :             max_val = hCovEnc->bb_var_lt_fx[ch];
     305           0 :             move32();
     306             :         }
     307             :     }
     308           0 :     *res_ind = max_idx; /* Q0 */
     309           0 :     move16();
     310             : }
     311           0 : ELSE IF( EQ_16( nchan_transport, 3 ) )
     312             : {
     313           0 :     *res_ind = dmx_order[nchan_transport]; /* Q0 */
     314           0 :     move16();
     315             : }
     316             : }
     317             : 
     318       72649 : return activeW_flag;
     319             : }
     320             : 
     321             : 
     322             : /*-----------------------------------------------------------------------------------------*
     323             :  * Function ivas_enc_cov_handler_process_fx()
     324             :  *
     325             :  * Encoder covariance handler process call
     326             :  *-----------------------------------------------------------------------------------------*/
     327             : 
     328      160660 : void ivas_enc_cov_handler_process_fx(
     329             :     ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle      */
     330             :     Word32 **ppIn_FR_real,                 /* q_ppIn_FR */
     331             :     Word32 **ppIn_FR_imag,                 /* q_ppIn_FR */
     332             :     Word16 q_ppIn_FR,
     333             :     Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */
     334             :     Word16 *q_cov_real[IVAS_SPAR_MAX_CH],
     335             :     Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_dtx_real */
     336             :     Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH],
     337             :     ivas_filterbank_t *pFb,                    /* i/o: FB handle                       */
     338             :     const Word16 start_band,                   /* Q0 */
     339             :     const Word16 end_band,                     /* Q0 */
     340             :     const Word16 num_ch,                       /* Q0 */
     341             :     const Word16 dtx_vad,                      /* Q0 */
     342             :     const Word16 transient_det[2],             /* Q0 */
     343             :     const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], /* Q0 */
     344             :     Word16 *res_ind,                           /* Q0 */
     345             :     const Word16 *remix_order,                 /* Q0 */
     346             :     Word16 *dyn_active_w_flag,                 /* Q0 */
     347             :     const Word16 nchan_transport,              /* Q0 */
     348             :     const Word16 is_sba                        /* Q0 */
     349             : )
     350             : {
     351             :     Word16 i, j;
     352             :     Word16 dtx_cov_flag;
     353             :     Word16 cov_real_zero[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
     354             :     Word16 k;
     355             : 
     356      160660 :     IF( EQ_16( dtx_vad, 1 ) )
     357             :     {
     358      154137 :         dtx_cov_flag = 0;
     359      154137 :         move16();
     360             :     }
     361             :     ELSE
     362             :     {
     363        6523 :         dtx_cov_flag = 1;
     364        6523 :         move16();
     365             :     }
     366             : 
     367      160660 :     ivas_band_cov_fx( ppIn_FR_real, ppIn_FR_imag, q_ppIn_FR, num_ch, hCovEnc->num_bins,
     368      160660 :                       pFb->fb_bin_to_band.short_stride,
     369      160660 :                       pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx, // Q22
     370      160660 :                       pFb->fb_bin_to_band.p_short_stride_start_bin_per_band,
     371      160660 :                       pFb->fb_bin_to_band.p_short_stride_num_bins_per_band,
     372             :                       start_band, end_band, cov_real, q_cov_real, HOA_md_ind );
     373             : 
     374      899180 :     FOR( i = 0; i < num_ch; i++ )
     375             :     {
     376      738520 :         set_s( cov_real_zero[i], 1, num_ch );
     377             :     }
     378             :     // Check if a particular band array is zero
     379      899180 :     FOR( i = 0; i < num_ch; i++ )
     380             :     {
     381     4647620 :         FOR( j = 0; j < num_ch; j++ )
     382             :         {
     383     6409440 :             FOR( k = start_band; k < end_band; k++ )
     384             :             {
     385     6200625 :                 IF( cov_real[i][j][k] != 0 )
     386             :                 {
     387     3700285 :                     cov_real_zero[i][j] = 0;
     388     3700285 :                     move16();
     389     3700285 :                     BREAK;
     390             :                 }
     391             :             }
     392             :         }
     393             :     }
     394             :     // Set q_cov_real to Q31 for the zero band array
     395      899180 :     FOR( i = 0; i < num_ch; i++ )
     396             :     {
     397     4647620 :         FOR( j = 0; j < num_ch; j++ )
     398             :         {
     399     3909100 :             IF( EQ_16( cov_real_zero[i][j], 1 ) )
     400             :             {
     401      208815 :                 q_cov_real[i][j] = Q31;
     402      208815 :                 move16();
     403             :             }
     404             :         }
     405             :     }
     406             : 
     407      160660 :     IF( is_sba )
     408             :     {
     409      157500 :         *res_ind = 0;
     410      157500 :         move16();
     411      157500 :         IF( GT_16( nchan_transport, 1 ) && LE_16( nchan_transport, sub( FOA_CHANNELS, 1 ) ) )
     412             :         {
     413       72649 :             *dyn_active_w_flag = ivas_spar_get_activeW_flag_fx( hCovEnc, cov_real, cov_real, q_cov_real, dtx_vad, num_ch, nchan_transport, res_ind, remix_order ); /* Q0 */
     414             :         }
     415             :         ELSE
     416             :         {
     417       84851 :             *dyn_active_w_flag = 0;
     418       84851 :             move16();
     419             :         }
     420             :     }
     421             : 
     422      899180 :     FOR( i = 0; i < num_ch; i++ )
     423             :     {
     424     4647620 :         FOR( j = 0; j < num_ch; j++ )
     425             :         {
     426     3909100 :             Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */
     427     3909100 :             q_cov_dtx_real[i][j] = q_cov_real[i][j];
     428     3909100 :             move16();
     429             :         }
     430             :     }
     431             : 
     432      160660 :     ivas_cov_smooth_process_fx( hCovEnc->pCov_state, cov_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_real );
     433             : 
     434      160660 :     IF( dtx_cov_flag == 0 )
     435             :     {
     436      872885 :         FOR( i = 0; i < num_ch; i++ )
     437             :         {
     438     4561400 :             FOR( j = 0; j < num_ch; j++ )
     439             :             {
     440     3842652 :                 Copy32( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], pFb->filterbank_num_bands ); /* q_cov_real */
     441    49553516 :                 FOR( k = 0; k < pFb->filterbank_num_bands; k++ )
     442             :                 {
     443    45710864 :                     hCovEnc->pCov_dtx_state->q_prior_cov_real_per_band[i][j][k] = hCovEnc->pCov_state->q_cov_real_per_band[i][j][k];
     444    45710864 :                     move16();
     445             :                 }
     446     3842652 :                 Copy32( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */
     447     3842652 :                 Copy( hCovEnc->pCov_state->q_cov_real_per_band[i][j], hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j], pFb->filterbank_num_bands );
     448             :             }
     449             :         }
     450      154137 :         hCovEnc->prior_dtx_present = 1;
     451      154137 :         move16();
     452             :     }
     453             :     ELSE
     454             :     {
     455        6523 :         IF( transient_det[0] == 0 && transient_det[1] == 0 )
     456             :         {
     457        5517 :             ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_dtx_real );
     458        5517 :             hCovEnc->prior_dtx_present = 1;
     459        5517 :             move16();
     460             :         }
     461             :         ELSE
     462             :         {
     463        1006 :             IF( hCovEnc->prior_dtx_present == 0 )
     464             :             {
     465          48 :                 ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_dtx_real );
     466          48 :                 hCovEnc->prior_dtx_present = 1;
     467          48 :                 move16();
     468             :             }
     469             :             ELSE
     470             :             {
     471        3766 :                 FOR( i = 0; i < num_ch; i++ )
     472             :                 {
     473       11992 :                     FOR( j = 0; j < num_ch; j++ )
     474             :                     {
     475        9184 :                         Copy32( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); /* q_cov_real */
     476      116320 :                         FOR( k = 0; k < pFb->filterbank_num_bands; k++ )
     477             :                         {
     478      107136 :                             hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j][k] = hCovEnc->pCov_dtx_state->q_prior_cov_real_per_band[i][j][k];
     479      107136 :                             move16();
     480             :                         }
     481             :                     }
     482             :                 }
     483         958 :                 hCovEnc->prior_dtx_present = 1;
     484         958 :                 move16();
     485             :             }
     486             :         }
     487             :     }
     488             : 
     489      160660 :     return;
     490             : }
     491             : 
     492             : 
     493      160660 : static void ivas_band_cov_fx(
     494             :     Word32 **ppIn_FR_real, /* q_In_FR */
     495             :     Word32 **ppIn_FR_imag, /* q_In_FR */
     496             :     Word16 q_In_FR,
     497             :     const Word16 num_chans,                               /* Q0 */
     498             :     const Word16 num_bins,                                /* Q0 */
     499             :     Word16 stride,                                        /* Q0 */
     500             :     Word32 **pFb_bin_to_band,                             /* Q22 */
     501             :     const Word16 *pFb_start_bin_per_band,                 /* Q0 */
     502             :     const Word16 *pFb_active_bins_per_band,               /* Q0 */
     503             :     const Word16 start_band,                              /* Q0 */
     504             :     const Word16 end_band,                                /* Q0 */
     505             :     Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /* q_cov_real */
     506             :     Word16 *q_cov_real[IVAS_SPAR_MAX_CH],
     507             :     const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] /* Q0 */
     508             : )
     509             : {
     510             :     Word16 i, j, k;
     511             :     Word32 pV_re[L_FRAME48k];
     512             :     Word64 pV_re_64bit[L_FRAME48k];
     513             :     Word64 cov_real_64bit[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
     514             :     Word16 q_shift, q_shift_tmp;
     515             :     Word16 m, start_bin, active_bins;
     516             :     Word16 num_blocks;
     517             : 
     518      160660 :     num_blocks = idiv1616( num_bins, stride ); /* Q0 */
     519      899180 :     FOR( i = 0; i < num_chans; i++ )
     520             :     {
     521     3062330 :         FOR( j = i; j < num_chans; j++ )
     522             :         {
     523     2323810 :             Word16 i1 = HOA_md_ind[i]; /* Q0 */
     524     2323810 :             Word16 j1 = HOA_md_ind[j]; /* Q0 */
     525     2323810 :             move16();
     526     2323810 :             move16();
     527             : 
     528  1907818210 :             FOR( k = 0; k < num_bins; k++ )
     529             :             {
     530  1905494400 :                 pV_re_64bit[k] = W_add( W_mult0_32_32( ppIn_FR_real[i1][k], ppIn_FR_real[j1][k] ),
     531  1905494400 :                                         W_mult0_32_32( ppIn_FR_imag[i1][k], ppIn_FR_imag[j1][k] ) ); //(q_In_FR[i1], q_In_FR[j1]) -> (q_In_FR[i1] + q_In_FR[j1])
     532  1905494400 :                 move64();
     533             :             }
     534             : 
     535     2323810 :             q_shift = 31;
     536     2323810 :             move16();
     537  1907818210 :             FOR( k = 0; k < num_bins; k++ )
     538             :             {
     539  1905494400 :                 q_shift_tmp = W_norm( pV_re_64bit[k] );
     540  1905494400 :                 if ( pV_re_64bit[k] != 0 )
     541             :                 {
     542  1801818687 :                     q_shift = s_min( q_shift, q_shift_tmp );
     543             :                 }
     544             :             }
     545     2323810 :             q_shift_tmp = sub( q_shift, 32 );
     546  1907818210 :             FOR( k = 0; k < num_bins; k++ )
     547             :             {
     548  1905494400 :                 pV_re[k] = W_extract_l( W_shl_nosat( pV_re_64bit[k], q_shift_tmp ) ); //(q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32)
     549  1905494400 :                 move32();
     550             :                 /* perform rounding towards lower value for negative results */
     551  1905494400 :                 if ( pV_re[k] < 0 )
     552             :                 {
     553   621752643 :                     pV_re[k] = L_add( pV_re[k], 1 );
     554             :                 }
     555             :             }
     556             : 
     557    29947530 :             FOR( k = start_band; k < end_band; k++ )
     558             :             {
     559             :                 Word64 temp;
     560    27623720 :                 const Word32 *p_bin_to_band = pFb_bin_to_band[k]; // Q22
     561             :                 Word32 *cov_ptr;
     562             :                 Word16 blk;
     563             : 
     564    27623720 :                 temp = 0;
     565    27623720 :                 move64();
     566    27623720 :                 start_bin = pFb_start_bin_per_band[k]; /* Q0 */
     567    27623720 :                 move16();
     568    27623720 :                 active_bins = pFb_active_bins_per_band[k]; /* Q0 */
     569    27623720 :                 move16();
     570             : 
     571    27623720 :                 cov_ptr = &pV_re[start_bin];
     572    27623720 :                 move16();
     573   138118600 :                 FOR( blk = 0; blk < num_blocks; blk++ )
     574             :                 {
     575             :                     /* optional: add temporal weight here */
     576  2129723680 :                     FOR( m = 0; m < active_bins; m++ )
     577             :                     {
     578  2019228800 :                         temp = W_add( temp, W_mult0_32_32( cov_ptr[m], p_bin_to_band[m] ) ); // ((q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32), Q22) -> (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10)
     579             :                     }
     580   110494880 :                     cov_ptr += stride;
     581   110494880 :                     move16();
     582             :                 }
     583             :                 // What basop to add below????
     584    27623720 :                 cov_real_64bit[i][j][k] = temp * (Word64) ( num_blocks ); // (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) - guard_bits
     585    27623720 :                 move64();
     586    27623720 :                 move64(); // conservative estimation of a 64 bit multiplication
     587             :             }
     588     2323810 :             q_cov_real[i][j] = add( add( q_In_FR, q_In_FR ), sub( q_shift, Q10 ) );
     589     2323810 :             move16();
     590             :         }
     591             :     }
     592             : 
     593      899180 :     FOR( i = 0; i < num_chans; i++ )
     594             :     {
     595     3062330 :         FOR( j = i; j < num_chans; j++ )
     596             :         {
     597     2323810 :             q_shift = 31;
     598     2323810 :             move16();
     599    29947530 :             FOR( k = start_band; k < end_band; k++ )
     600             :             {
     601    27623720 :                 q_shift_tmp = W_norm( cov_real_64bit[i][j][k] );
     602    27623720 :                 if ( cov_real_64bit[i][j][k] != 0 )
     603             :                 {
     604    26257256 :                     q_shift = s_min( q_shift, q_shift_tmp );
     605             :                 }
     606             :             }
     607     2323810 :             q_shift_tmp = sub( q_shift, 32 );
     608    29947530 :             FOR( k = start_band; k < end_band; k++ )
     609             :             {
     610    27623720 :                 cov_real[i][j][k] = W_extract_l( W_shl_nosat( cov_real_64bit[i][j][k], q_shift_tmp ) ); /* q_cov_real[i][j] + q_shift - 32 */
     611    27623720 :                 move32();
     612             :             }
     613     2323810 :             q_cov_real[i][j] = add( q_cov_real[i][j], q_shift_tmp );
     614     2323810 :             move16();
     615             :         }
     616             :     }
     617             : 
     618      899180 :     FOR( i = 0; i < num_chans; i++ )
     619             :     {
     620     2323810 :         FOR( j = 0; j < i; j++ )
     621             :         {
     622    20446770 :             FOR( k = start_band; k < end_band; k++ )
     623             :             {
     624    18861480 :                 cov_real[i][j][k] = cov_real[j][i][k]; // q_cov_real[i][j]
     625    18861480 :                 move32();
     626             :             }
     627     1585290 :             q_cov_real[i][j] = q_cov_real[j][i];
     628     1585290 :             move16();
     629             :         }
     630             :     }
     631             : 
     632      160660 :     return;
     633             : }

Generated by: LCOV version 1.14