LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_dft_td_itd_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 242 247 98.0 %
Date: 2025-05-03 01:55:50 Functions: 4 4 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 <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "rom_com.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_stat_enc.h"
      42             : #include "ivas_cnst.h"
      43             : #include "wmc_auto.h"
      44             : #include "ivas_prot_fx.h"
      45             : 
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * Local constants
      49             :  *-------------------------------------------------------------------*/
      50             : 
      51             : #define STEREO_DFT_CHANNEL_EXTR_LPC_ORDER     10
      52             : #define STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT 320
      53             : #define FLR_FX                                16384 // Q15
      54             : #define ONE_HALF                              24576 // Q14
      55             : const Word16 wac_swb_h_fx[LPC_SHB_ORDER + 1] = {    // Q15
      56             :     32767,
      57             :     32758,
      58             :     32731,
      59             :     32686,
      60             :     32622,
      61             :     32541,
      62             :     32442,
      63             :     32325,
      64             :     32191,
      65             :     32039,
      66             :     31870
      67             : };
      68             : 
      69             : const Word16 wac_swb_l_fx[LPC_SHB_ORDER + 1] = { // Q15
      70             :     32767,
      71             :     29696,
      72             :     20864,
      73             :     7872,
      74             :     25856,
      75             :     12800,
      76             :     5952,
      77             :     10560,
      78             :     256,
      79             :     15040,
      80             :     30336
      81             : };
      82             : /*---------------------------------------------------------------
      83             :  * stereo_td_get_td_itd()
      84             :  *
      85             :  *
      86             :  * ---------------------------------------------------------------*/
      87             : 
      88       35397 : static void stereo_td_get_td_itd_fx(
      89             :     Word16 *td_itd,    /* o  : td_itd in samples at sampling frequency */
      90             :     Word16 *td_itd_32, /* o  : td_itd in samples at 32kHz              */
      91             :     const Word32 itd,  /* i  : itd in samples at sampling frequency  q_itd  */
      92             :     Word16 q_itd,
      93             :     const Word32 input_Fs /* i  : sampling frequency                      */
      94             : )
      95             : {
      96             :     /* *td_itd is the closest integer to itd that transforms into an integer value *
      97             :      * under the transform x -> (32000/fs) x.                                      */
      98             :     Word16 d, d_e;
      99             : 
     100       35397 :     IF( EQ_32( input_Fs, 32000 ) )
     101             :     {
     102       12815 :         *td_itd_32 = *td_itd = extract_l( L_shr_r( itd, q_itd ) );
     103       12815 :         move16();
     104       12815 :         move16();
     105             :     }
     106             :     ELSE
     107             :     {
     108       22582 :         assert( ( input_Fs % 16000 ) == 0 && "sampling frequency should be divisible by 16000" );
     109             :         Word16 temp_div, temp_e, temp_add;
     110       22582 :         d = BASOP_Util_Divide3232_Scale( input_Fs, 16000, &d_e );
     111       22582 :         temp_div = BASOP_Util_Divide3232_Scale( itd, L_deposit_h( d ), &temp_e );
     112       22582 :         temp_e = add( temp_e, sub( sub( 31, q_itd ), d_e ) ); // e+(e1-e2)//
     113       22582 :         temp_add = add_sat( temp_div, shr_sat( FLR_FX, temp_e ) );
     114             : 
     115       22582 :         IF( itd != 0 )
     116             :         {
     117        9975 :             *td_itd_32 = extract_l( L_shl( L_shr( L_add( temp_add, EPSILON_FX ), sub( 15, temp_e ) ), 1 ) );
     118             :         }
     119             :         ELSE
     120             :         {
     121       12607 :             *td_itd_32 = shl( shr( temp_add, sub( 15, temp_e ) ), 1 );
     122             :         }
     123       22582 :         move16();
     124             : 
     125       22582 :         *td_itd = i_mult( shr( *td_itd_32, 1 ), shr( d, sub( 15, d_e ) ) );
     126       22582 :         move16();
     127             :     }
     128             : 
     129       35397 :     return;
     130             : }
     131             : 
     132             : /*---------------------------------------------------------------
     133             :  * stereo_td_channel_extrapolate()
     134             :  *
     135             :  *
     136             :  * ---------------------------------------------------------------*/
     137             : 
     138       15669 : static void stereo_td_channel_extrapolate_fx(
     139             :     Encoder_State **sts,
     140             :     const Word16 dft_ovl,
     141             :     const Word16 shift_mem[], // q_shift
     142             :     Word16 q_shift,
     143             :     Word16 shift_input[], // q_shift
     144             :     const Word16 input_frame,
     145             :     const Word16 itd_shift,
     146             :     const Word16 lagging_channel,
     147             :     Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory  q_input_mem   */
     148             :     Word16 *q_input_mem,
     149             :     Word16 *q_new_shift )
     150             : {
     151             :     Word16 leading_channel, i, size_ovl, pred_ovlp;
     152             :     Word16 g, nsr, g_lpc;
     153             :     Word32 dot_lead_lag_1, dot_lead_lead_1, dot_lag_lag_1;
     154             :     Word64 dot_lead_lag, dot_lead_lead, dot_lag_lag;
     155             :     Word16 q_dot_lead_lag, q_dot_lead_lead, q_dot_lag_lag;
     156             :     Word16 window[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT], mem_zero[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER];
     157             :     Word16 residual[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * L_FRAME48k ) / L_FRAME32k];
     158             :     Word16 r_h[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     159             :     Word16 r_l[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     160             :     Word16 Q_r;
     161             :     Word16 A[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     162             :     Word16 shift_combined[L_FRAME48k + L_FRAME48k];
     163             :     // Word16 q_shift_combined;
     164             :     Word16 flag;
     165             :     Word16 pitch_lag;
     166             :     Word16 res_shift;
     167             :     Word16 pitch0, tmp, tmp_e;
     168             :     Word32 L_tmp;
     169             :     // shift_mem and shift_input are of same Q q_shift//
     170       15669 :     set16_fx( shift_combined, 0, add( L_FRAME48k, L_FRAME48k ) );
     171       15669 :     set16_fx( residual, 0, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * input_frame ) / L_FRAME32k );
     172             : 
     173       15669 :     leading_channel = s_and( add( lagging_channel, 1 ), 1 );
     174       15669 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     175             :     {
     176       12128 :         size_ovl = dft_ovl;
     177       12128 :         pitch0 = sts[0]->pitch[0];
     178             :     }
     179             :     ELSE
     180             :     {
     181        3541 :         size_ovl = input_frame;
     182        3541 :         pitch0 = sts[lagging_channel]->pitch[0];
     183             :     }
     184       15669 :     move16();
     185       15669 :     move16();
     186             : 
     187       15669 :     pred_ovlp = idiv1616( input_frame, 10 );
     188             : 
     189             :     /*get pitch lag from previous frame */
     190             :     // pitch_lag = (int16_t) ( pitch0 * ( (float) input_frame / L_FRAME ) );
     191       15669 :     tmp = BASOP_Util_Divide3232_Scale( input_frame, L_FRAME, &tmp_e );
     192       15669 :     L_tmp = L_mult0( pitch0, tmp );
     193       15669 :     pitch_lag = extract_l( L_shr( L_tmp, sub( 15, tmp_e ) ) ); /* Q0 */
     194             : 
     195             :     /* compute the parameters g, nsr and g_lpc */
     196       15669 :     dot_lead_lag = EPSILON_FX;
     197       15669 :     dot_lead_lead = EPSILON_FX;
     198       15669 :     dot_lag_lag = EPSILON_FX;
     199       15669 :     dot_lead_lag_1 = EPSILON_FX;
     200       15669 :     dot_lead_lead_1 = EPSILON_FX;
     201       15669 :     dot_lag_lag_1 = EPSILON_FX;
     202       15669 :     move64();
     203       15669 :     move64();
     204       15669 :     move64();
     205       15669 :     move32();
     206       15669 :     move32();
     207       15669 :     move32();
     208     5872949 :     FOR( i = 0; i < size_ovl; i++ )
     209             :     {
     210     5857280 :         shift_combined[i] = shift_mem[i]; // q_shift
     211     5857280 :         move16();
     212             :         // q_shift_combined = q_shift;
     213     5857280 :         dot_lead_lag = W_mac0_16_16( dot_lead_lag, input_mem[leading_channel][i], shift_mem[i] );
     214     5857280 :         dot_lead_lead = W_mac0_16_16( dot_lead_lead, input_mem[leading_channel][i], input_mem[leading_channel][i] );
     215     5857280 :         dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_mem[i], shift_mem[i] );
     216             :     }
     217    10376555 :     FOR( i = 0; i < input_frame - itd_shift; i++ )
     218             :     {
     219    10360886 :         shift_combined[i + size_ovl] = shift_input[i]; // q_shift
     220    10360886 :         move16();
     221    10360886 :         dot_lead_lag = W_mac0_16_16( dot_lead_lag, sts[leading_channel]->input_fx[i], shift_input[i] );
     222    10360886 :         dot_lead_lead = W_mac0_16_16( dot_lead_lead, sts[leading_channel]->input_fx[i], sts[leading_channel]->input_fx[i] );
     223    10360886 :         dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_input[i], shift_input[i] );
     224             :     }
     225       15669 :     q_dot_lead_lag = q_shift + q_input_mem[leading_channel]; // q_input_mem = q_input
     226       15669 :     q_dot_lead_lead = q_input_mem[leading_channel] + q_input_mem[leading_channel];
     227       15669 :     q_dot_lag_lag = add( q_shift, q_shift );
     228             : 
     229             : 
     230       15669 :     q_dot_lead_lag = sub( add( q_dot_lead_lag, W_norm( dot_lead_lag ) ), 32 );
     231       15669 :     q_dot_lead_lead = sub( add( q_dot_lead_lead, W_norm( dot_lead_lead ) ), 32 );
     232       15669 :     q_dot_lag_lag = sub( add( q_dot_lag_lag, W_norm( dot_lag_lag ) ), 32 );
     233       15669 :     dot_lead_lag_1 = W_extract_h( W_shl( dot_lead_lag, W_norm( dot_lead_lag ) ) );
     234       15669 :     dot_lead_lead_1 = W_extract_h( W_shl( dot_lead_lead, W_norm( dot_lead_lead ) ) );
     235       15669 :     dot_lag_lag_1 = W_extract_h( W_shl( dot_lag_lag, W_norm( dot_lag_lag ) ) );
     236             : 
     237             : 
     238             :     Word16 g_e, f, f_e, g_lpc_e, nsr_e;
     239       15669 :     g = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lead_lead_1, &g_e );
     240       15669 :     g_e = add( g_e, sub( q_dot_lead_lead, q_dot_lead_lag ) );
     241             : 
     242       15669 :     f = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lag_lag_1, &f_e );
     243       15669 :     f_e = add( f_e, sub( q_dot_lag_lag, q_dot_lead_lag ) );
     244             : 
     245       15669 :     nsr = mult( g, f );
     246       15669 :     nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), add( g_e, f_e ), &nsr );
     247       15669 :     IF( g_e > 0 )
     248             :     {
     249        2944 :         g = check_bounds_s_fx( g, negate( shl( 1, sub( 15, g_e ) ) ), shl( ONE_HALF, sub( 1, g_e ) ) );
     250             :     }
     251       15669 :     IF( nsr_e > 0 )
     252             :     {
     253           0 :         nsr = check_bounds_s_fx( nsr, 0, shl( 1, sub( 15, nsr_e ) ) );
     254             :     }
     255       15669 :     g = shl( g, sub( g_e, 1 ) ); // q14
     256       15669 :     nsr = shl( nsr, nsr_e );     // Q15
     257       15669 :     g_lpc_e = 0;
     258       15669 :     move16();
     259       15669 :     g_lpc = Sqrt16( nsr, &g_lpc_e );
     260       15669 :     g_lpc = shl( g_lpc, sub( g_lpc_e, 1 ) ); // Q14
     261             :     /* rectangular window */
     262       15669 :     set16_fx( window, 32767, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT );
     263       15669 :     set16_zero_fx( mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
     264             : 
     265             :     /* get the LPC filter */
     266       15669 :     autocorr_ivas_fx( shift_combined + input_frame + size_ovl - itd_shift - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, q_shift, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, r_h, r_l, &Q_r, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, window, 0, 0, 0 );
     267             :     /* Ensure R[0] isn't zero when entering Levinson-Durbin */
     268       15669 :     r_l[0] = s_max( r_l[0], 1 );
     269       15669 :     move16();
     270      188028 :     FOR( i = 0; i <= STEREO_DFT_CHANNEL_EXTR_LPC_ORDER; i++ )
     271             :     {
     272      172359 :         L_tmp = Mpy_32( r_h[i], r_l[i], wac_swb_h_fx[i], wac_swb_l_fx[i] );
     273      172359 :         L_Extract( L_tmp, &r_h[i], &r_l[i] );
     274             :     }
     275       15669 :     r_l[0] = s_max( r_l[0], 1 );
     276       15669 :     move16();
     277       15669 :     flag = E_LPC_lev_dur( r_h, r_l, A, NULL, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, NULL );
     278       15669 :     Copy_Scale_sig( A, A, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1, sub( norm_s( A[0] ), 2 ) );
     279       15669 :     IF( EQ_16( flag, 1 ) )
     280             :     {
     281           0 :         g_lpc = 0;
     282           0 :         move16();
     283             :     }
     284             :     ELSE
     285             :     {
     286             :         /* get the residual */
     287       15669 :         fir_fx( shift_combined + input_frame + size_ovl - itd_shift - STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, A, residual, mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, 0, 3 );
     288             : 
     289             :         /* extend the residual */
     290             :         /* to prevent out of bound reading */
     291       15669 :         IF( LT_16( pitch_lag, PIT_MAX ) )
     292             :         {
     293        9569 :             res_shift = pitch_lag;
     294        9569 :             move16();
     295             :         }
     296             :         ELSE
     297             :         {
     298        6100 :             res_shift = itd_shift;
     299        6100 :             move16();
     300             :         }
     301             : 
     302      658623 :         FOR( i = STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT; i < STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift; i++ )
     303             :         {
     304      642954 :             residual[i] = residual[i - res_shift];
     305      642954 :             move16();
     306             :         }
     307             : 
     308             :         /* perform sythesis */
     309       15669 :         E_UTIL_synthesis( 0, A, residual, shift_combined + sub( add( input_frame, size_ovl ), add( STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT, itd_shift ) ), STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift, mem_zero, 0, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
     310             :     }
     311             : 
     312       15669 :     Copy( shift_combined + size_ovl, shift_input, input_frame ); // q_shift
     313             : 
     314       15669 :     Word16 offset = sub( input_frame, itd_shift );
     315       15669 :     Word16 offset_pred_ovlp = sub( offset, pred_ovlp );
     316             : 
     317      658623 :     FOR( i = offset; i < input_frame; i++ )
     318             :     {
     319      642954 :         shift_input[i] = extract_h( L_mac0( L_mult0( g_lpc, shift_input[i] ), g, sts[leading_channel]->input_fx[i] ) ); // Q = 14 + q_shift - 16
     320      642954 :         move16();
     321             :     }
     322       15669 :     Word16 q_temp = sub( q_shift, 2 );
     323             : 
     324             :     /* smooth transition (currently done by blending over linearly, could be replaced by something more elaborate.) */
     325       15669 :     Word16 e_shift = 0;
     326       15669 :     move16();
     327     1116053 :     FOR( i = offset_pred_ovlp; i < offset; i++ )
     328             :     {
     329             :         /*shift_input[i] = ( i - input_frame + itd_shift + pred_ovlp ) * ( ( g_lpc * shift_input[i] ) + ( g * sts[leading_channel]->input[i] ) ) / pred_ovlp + ( input_frame - itd_shift - i ) * shift_input[i] / pred_ovlp;*/
     330     1100384 :         L_tmp = L_shr( L_mult0( shift_input[i], sub( offset, i ) ), 1 );                                                                           // q_shift - 1
     331     1100384 :         L_tmp = Madd_32_16( L_tmp, L_mac0( L_mult0( g_lpc, shift_input[i] ), g, sts[leading_channel]->input_fx[i] ), sub( i, offset_pred_ovlp ) ); // q_shift - 1
     332             : 
     333     1100384 :         shift_input[i] = BASOP_Util_Divide3232_Scale( L_tmp, pred_ovlp, &e_shift ); // Q=15-e_shift+q_shift-1 = 14-e_shift+q_shift
     334     1100384 :         move16();
     335     1100384 :         shift_input[i] = shr( shift_input[i], sub( add( sub( 14, e_shift ), q_shift ), q_temp ) ); // q_temp
     336     1100384 :         move16();
     337             :     }
     338             : 
     339             :     // scaling whole buffer to q_temp//
     340     9276171 :     FOR( i = 0; i < offset_pred_ovlp; i++ )
     341             :     {
     342     9260502 :         shift_input[i] = shr( shift_input[i], sub( q_shift, q_temp ) );
     343     9260502 :         move16();
     344             :     }
     345             : 
     346       15669 :     *q_new_shift = q_temp;
     347       15669 :     move16();
     348       15669 :     return;
     349             : }
     350             : 
     351             : /*---------------------------------------------------------------
     352             :  * stereo_td_itd()
     353             :  *
     354             :  *
     355             :  * ---------------------------------------------------------------*/
     356             : 
     357       74333 : void stereo_td_itd_fx(
     358             :     ITD_DATA *hITD,                                         /* i/o: ITD data structure                    */
     359             :     Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o  : ITD memory (only used in DFT Stereo)  q_input_mem_itd*/
     360             :     Word16 *q_input_mem_itd,
     361             :     const Word16 hybrid_itd_flag,    /* i  : flag for hybrid TD/FD ITD processing  */
     362             :     const Word16 dft_ovl,            /* i  : size of DFT overlap                   */
     363             :     Encoder_State **sts,             /* i/o: Encoder state structure               */
     364             :     const Word16 input_frame,        /* i  : input frame length                    */
     365             :     Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory       q_input_mem            */
     366             :     Word16 *q_input_mem )
     367             : {
     368             :     Word16 i, ch, n;
     369             :     Word16 size_ovl, k_offset;
     370             :     Word16 shift[2];
     371             :     Word16 itd, itd_max;
     372             :     Word16 shift_input[L_FRAME48k];
     373             :     Word16 shift_mem[L_FRAME48k];
     374             :     Word16 q_shift_mem;
     375             :     Word16 *mdct_mem[CPE_CHANNELS];
     376             :     // Word16 q_mdct_mem[CPE_CHANNELS];
     377             :     Word16 q_shift, q_new_shift;
     378             : 
     379       74333 :     k_offset = STEREO_DFT_OFFSET;
     380       74333 :     move16();
     381       74333 :     set16_fx( shift_input, 0, input_frame );
     382             : 
     383       74333 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) )
     384             :     {
     385       44070 :         FOR( n = 0; n < CPE_CHANNELS; n++ )
     386             :         {
     387       29380 :             mdct_mem[n] = sts[n]->old_input_signal_fx;
     388       29380 :             move16();
     389             :             // q_mdct_mem[n] = sts[n]->q_old_inp;
     390             :         }
     391             :     }
     392       74333 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     393             :     {
     394             :         /* Update the parameters */
     395      119286 :         FOR( i = 0; i < k_offset; i++ )
     396             :         {
     397       59643 :             hITD->deltaItd_fx[i] = hITD->deltaItd_fx[i + 1];
     398       59643 :             move32();
     399       59643 :             hITD->td_itd[i] = hITD->td_itd[i + 1];
     400       59643 :             move16();
     401       59643 :             hITD->td_itd_32k[i] = hITD->td_itd_32k[i + 1];
     402       59643 :             move16();
     403             :         }
     404             :     }
     405             :     /*reset TD ITDs in case of hybrid itd_max change - turn hybrid ITD off*/
     406       74333 :     test();
     407       74333 :     IF( EQ_16( hITD->hybrid_itd_max, -1 ) && EQ_16( hybrid_itd_flag, 0 ) )
     408             :     {
     409          21 :         hITD->td_itd[k_offset] = 0;
     410          21 :         move16();
     411          21 :         hITD->td_itd_32k[k_offset] = 0;
     412          21 :         move16();
     413             :     }
     414       74333 :     IF( EQ_16( hybrid_itd_flag, 0 ) )
     415             :     {
     416       38936 :         return;
     417             :     }
     418       35397 :     stereo_td_get_td_itd_fx( &( hITD->td_itd[k_offset] ), &( hITD->td_itd_32k[k_offset] ), hITD->itd_fx[k_offset], Q16, sts[0]->input_Fs );
     419             : 
     420             :     /* initializations*/
     421             :     {
     422       35397 :         size_ovl = dft_ovl;
     423       35397 :         move16();
     424             : 
     425       35397 :         itd_max = shr( input_frame, 2 );
     426       35397 :         Word16 comp_flag1 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ) );
     427       35397 :         Word16 comp_flag2 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ) );
     428       35397 :         assert( ( comp_flag1 ) && "ITD value is too high!" );
     429       35397 :         assert( ( comp_flag2 ) && "ITD value is too high!" );
     430             : 
     431       35397 :         itd = hITD->td_itd[k_offset];
     432             : 
     433             :         /*Time shift with current ITD*/
     434       35397 :         IF( LT_16( itd, 0 ) )
     435             :         {
     436       10414 :             shift[1] = 0;
     437       10414 :             move16();
     438       10414 :             shift[0] = negate( itd );
     439       10414 :             move16();
     440       10414 :             ch = 0;
     441       10414 :             move16();
     442             :         }
     443             :         ELSE
     444             :         {
     445       24983 :             shift[1] = itd;
     446       24983 :             move16();
     447       24983 :             shift[0] = 0;
     448       24983 :             move16();
     449       24983 :             ch = 1;
     450       24983 :             move16();
     451             :         }
     452             : 
     453             :         /* extrapolate lagging channel */
     454       35397 :         IF( GT_16( shift[ch], 0 ) )
     455             :         {
     456       15669 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     457             :             {
     458             :                 /* store last part of signal before extrapolation */
     459       36384 :                 FOR( n = 0; n < CPE_CHANNELS; n++ )
     460             :                 {
     461       24256 :                     Copy( sts[n]->input_fx + input_frame - dft_ovl, input_mem_itd[n], dft_ovl );
     462       24256 :                     q_input_mem_itd[n] = sts[n]->q_inp;
     463       24256 :                     move16();
     464             :                 }
     465             : 
     466             :                 /*shift past part*/
     467       12128 :                 Copy( input_mem[ch] + shift[ch], shift_mem, sub( size_ovl, shift[ch] ) );
     468       12128 :                 Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] );
     469       12128 :                 q_shift_mem = sts[ch]->q_inp;
     470       12128 :                 move16();
     471             :             }
     472             :             ELSE
     473             :             {
     474             :                 /*shift past part*/
     475        3541 :                 Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] );
     476        3541 :                 Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] );
     477        3541 :                 q_shift_mem = sts[ch]->q_inp;
     478        3541 :                 move16();
     479             :             }
     480             :             /*shift current part*/
     481       15669 :             Copy( sts[ch]->input_fx + shift[ch], shift_input, sub( input_frame, shift[ch] ) );
     482             : 
     483       15669 :             q_shift = sts[ch]->q_inp;
     484       15669 :             move16();
     485             :             // q_shift is shift for both shift_mem and shift_inp//
     486             :             // both channels input maintain same q//
     487       15669 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     488             :             {
     489             :                 /*Extrapolate current frame*/
     490       12128 :                 stereo_td_channel_extrapolate_fx( sts, dft_ovl, shift_mem, q_shift, shift_input, input_frame, shift[ch], ch, input_mem, q_input_mem, &q_new_shift );
     491             :             }
     492             :             ELSE
     493             :             {
     494             :                 /*Extrapolate current frame*/
     495        3541 :                 stereo_td_channel_extrapolate_fx( sts, 0, shift_mem, q_shift, shift_input, input_frame, shift[ch], ch, mdct_mem, q_input_mem, &q_new_shift );
     496             :             }
     497             : 
     498             :             /* write back the extrapolated signal into sts[ch]->input */
     499       15669 :             Copy( shift_input, sts[ch]->input_fx, input_frame );
     500       15669 :             sts[ch]->q_inp = q_new_shift;
     501       15669 :             move16();
     502             :             /*sts[ch]->q_old_inp = q_new_shift;
     503             :             move16();*/
     504       15669 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     505             :             {
     506             :                 // here shift_mem has same as input_mem, no need to update q //
     507       12128 :                 Copy( shift_mem, input_mem[ch], size_ovl );
     508             :             }
     509             :             ELSE
     510             :             {
     511        3541 :                 Copy( shift_mem, mdct_mem[ch], input_frame );
     512        3541 :                 sts[ch]->q_old_inp = q_new_shift;
     513        3541 :                 move16();
     514        3541 :                 Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp)
     515             :             }
     516             :         }
     517             :     }
     518             : 
     519       35397 :     return;
     520             : }
     521             : 
     522             : /*---------------------------------------------------------------
     523             :  * stereo_td_itd_mdct_stereo()
     524             :  *
     525             :  * Time-domain ITD in MDCT stereo
     526             :  * ---------------------------------------------------------------*/
     527      346785 : void stereo_td_itd_mdct_stereo_fx(
     528             :     CPE_ENC_HANDLE hCPE,           /* i/o: CPE encoder handle     */
     529             :     const Word16 vad_flag_dtx[],   /* i  : VAD dtx flags          */
     530             :     const Word16 vad_hover_flag[], /* i  : VAD hangover flags     */
     531             :     const Word16 input_frame       /* i  : frame length           */
     532             : )
     533             : {
     534             :     Word16 i, n, q_com;
     535             :     Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC];
     536             :     Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC];
     537             :     Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC];
     538             :     Word16 bin_nrgR_e[STEREO_DFT_N_32k_ENC];
     539             :     Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
     540             :     Word16 DFT_e[CPE_CHANNELS];
     541             :     Word16 DFT_tmp_e[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
     542             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct;
     543             : 
     544      346785 :     test();
     545      346785 :     IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL )
     546             :     {
     547       14690 :         hStereoMdct = hCPE->hStereoMdct;
     548             : 
     549       14690 :         hCPE->hStereoMdct->hItd->td_itd_32k[STEREO_DFT_OFFSET] = 0;
     550       14690 :         move16();
     551       14690 :         hStereoMdct->hItd->td_itd[STEREO_DFT_OFFSET] = 0;
     552       14690 :         move16();
     553             : 
     554             :         /* Update the parameters */
     555       29380 :         FOR( i = 0; i < STEREO_DFT_OFFSET; i++ )
     556             :         {
     557       14690 :             hStereoMdct->hItd->deltaItd_fx[i] = hStereoMdct->hItd->deltaItd_fx[i + 1];
     558       14690 :             move32();
     559       14690 :             hStereoMdct->hItd->td_itd[i] = hStereoMdct->hItd->td_itd[i + 1];
     560       14690 :             move16();
     561       14690 :             hStereoMdct->hItd->td_itd_32k[i] = hStereoMdct->hItd->td_itd_32k[i + 1];
     562       14690 :             move16();
     563             :         }
     564             : 
     565       14690 :         stereo_dft_enc_analyze_fx( hCPE->hCoreCoder, CPE_CHANNELS, input_frame, NULL, hStereoMdct, DFT_fx, DFT_e, hCPE->input_mem_fx, hCPE->q_input_mem );
     566             : 
     567    28219490 :         FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ )
     568             :         {
     569    28204800 :             DFT_tmp_e[0][i] = DFT_e[0];
     570    28204800 :             move16();
     571    28204800 :             DFT_tmp_e[1][i] = DFT_e[1];
     572    28204800 :             move16();
     573             :         }
     574             : 
     575             :         /*call ITD function*/
     576       14690 :         stereo_dft_enc_compute_itd_fx( hCPE, DFT_fx[0], DFT_tmp_e[0], DFT_fx[1], DFT_tmp_e[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_e, bin_nrgR_fx, bin_nrgR_e );
     577             : 
     578       14690 :         q_com = MAX_16;
     579       14690 :         move16();
     580             : 
     581       44070 :         FOR( n = 0; n < CPE_CHANNELS; n++ )
     582             :         {
     583       29380 :             q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->input_fx, input_frame ), hCPE->hCoreCoder[n]->q_inp ) );
     584       29380 :             q_com = s_min( q_com, add( norm_arr( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame ), hCPE->hCoreCoder[n]->q_old_inp ) );
     585       29380 :             q_com = s_min( q_com, add( norm_arr( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl ), hCPE->q_input_mem[n] ) );
     586             : 
     587       29380 :             if ( EQ_16( q_com, Q15 ) )
     588             :             {
     589           0 :                 q_com = 0;
     590           0 :                 move16();
     591             :             }
     592             :         }
     593             : 
     594       44070 :         FOR( n = 0; n < CPE_CHANNELS; n++ )
     595             :         {
     596       29380 :             scale_sig( hCPE->hCoreCoder[n]->input_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_inp ) );
     597       29380 :             hCPE->hCoreCoder[n]->q_inp = q_com;
     598       29380 :             move16();
     599             : 
     600       29380 :             scale_sig( hCPE->hCoreCoder[n]->old_input_signal_fx, input_frame, sub( q_com, hCPE->hCoreCoder[n]->q_old_inp ) );
     601       29380 :             hCPE->hCoreCoder[n]->q_old_inp = q_com;
     602       29380 :             move16();
     603             : 
     604       29380 :             scale_sig( hCPE->input_mem_fx[n], hStereoMdct->hDft_ana->dft_ovl, sub( q_com, hCPE->q_input_mem[n] ) );
     605       29380 :             hCPE->q_input_mem[n] = q_com;
     606       29380 :             move16();
     607             :         }
     608             : 
     609             :         /* Time Domain ITD compensation using extrapolation */
     610       14690 :         stereo_td_itd_fx( hStereoMdct->hItd, NULL, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem );
     611             :     }
     612             : 
     613      346785 :     return;
     614             : }

Generated by: LCOV version 1.14