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 @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 249 260 95.8 %
Date: 2025-06-27 02:59:36 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                                1073741824 // Q31
      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       35429 : 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       35429 :     Word32 inverse_input_fs_by_16k = 0;
      99       35429 :     move32();
     100             :     Word64 tmp64;
     101       35429 :     Word16 d = 0, shift = 0;
     102       35429 :     move16();
     103       35429 :     move16();
     104             : 
     105       35429 :     IF( EQ_32( input_Fs, 32000 ) )
     106             :     {
     107       12808 :         *td_itd_32 = *td_itd = extract_l( L_shr_r( itd, q_itd ) );
     108       12808 :         move16();
     109       12808 :         move16();
     110             :     }
     111             :     ELSE
     112             :     {
     113       22621 :         assert( ( input_Fs % 16000 ) == 0 && "sampling frequency should be divisible by 16000" );
     114       22621 :         IF( itd == 0 )
     115             :         {
     116       12654 :             *td_itd_32 = *td_itd = 0;
     117       12654 :             move16();
     118       12654 :             move16();
     119             :         }
     120             :         ELSE
     121             :         {
     122        9967 :             SWITCH( input_Fs )
     123             :             {
     124        3481 :                 case 16000:
     125        3481 :                     inverse_input_fs_by_16k = 1073741824; // Q30 /* This is in Q30, because 2147483648 cannot be represnt in Word32*/
     126        3481 :                     move32();
     127        3481 :                     d = 1; // Q0
     128        3481 :                     move16();
     129        3481 :                     shift = 1;
     130        3481 :                     move16();
     131        3481 :                     BREAK;
     132           0 :                 case 32000:
     133           0 :                     inverse_input_fs_by_16k = 1073741824; // Q31
     134           0 :                     move32();
     135           0 :                     d = 2; // Q0
     136           0 :                     move16();
     137           0 :                     BREAK;
     138        6486 :                 case 48000:
     139        6486 :                     inverse_input_fs_by_16k = 715827883; // Q31
     140        6486 :                     move32();
     141        6486 :                     d = 3; // Q0
     142        6486 :                     move16();
     143        6486 :                     if ( itd < 0 )
     144             :                     {
     145        4247 :                         inverse_input_fs_by_16k = 715827882; /* Reducing the precision by 1 to handle multiplication of negative case*/
     146        4247 :                         move32();
     147             :                     }
     148        6486 :                     BREAK;
     149           0 :                 default:
     150           0 :                     assert( 0 );
     151             :             }
     152        9967 :             tmp64 = W_add( W_mult0_32_32( itd, inverse_input_fs_by_16k ), W_shl( FLR_FX, sub( q_itd, shift ) ) ); // Q: q_itd - shift + 31
     153        9967 :             *td_itd_32 = shl( extract_l( W_extract_l( W_shr( tmp64, add( sub( q_itd, shift ), Q31 ) ) ) ), 1 );   // Q0
     154        9967 :             move16();
     155             : 
     156        9967 :             *td_itd = i_mult( shr( *td_itd_32, 1 ), d ); // Q0
     157        9967 :             move16();
     158             :         }
     159             :     }
     160             : 
     161       35429 :     return;
     162             : }
     163             : 
     164             : /*---------------------------------------------------------------
     165             :  * stereo_td_channel_extrapolate()
     166             :  *
     167             :  *
     168             :  * ---------------------------------------------------------------*/
     169             : 
     170       15678 : static void stereo_td_channel_extrapolate_fx(
     171             :     Encoder_State **sts,
     172             :     const Word16 dft_ovl,
     173             :     const Word16 shift_mem[], // q_shift
     174             :     Word16 q_shift,
     175             :     Word16 shift_input[], // q_shift
     176             :     const Word16 input_frame,
     177             :     const Word16 itd_shift,
     178             :     const Word16 lagging_channel,
     179             :     Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory  q_input_mem   */
     180             :     Word16 *q_input_mem,
     181             :     Word16 *q_new_shift )
     182             : {
     183             :     Word16 leading_channel, i, size_ovl, pred_ovlp;
     184             :     Word16 g, nsr, g_lpc;
     185             :     Word32 dot_lead_lag_1, dot_lead_lead_1, dot_lag_lag_1;
     186             :     Word64 dot_lead_lag, dot_lead_lead, dot_lag_lag;
     187             :     Word16 q_dot_lead_lag, q_dot_lead_lead, q_dot_lag_lag;
     188             :     Word16 window[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT], mem_zero[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER];
     189             :     Word16 residual[STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * L_FRAME48k ) / L_FRAME32k];
     190             :     Word16 r_h[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     191             :     Word16 r_l[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     192             :     Word16 Q_r;
     193             :     Word16 A[STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1];
     194             :     Word16 shift_combined[L_FRAME48k + L_FRAME48k];
     195             :     // Word16 q_shift_combined;
     196             :     Word16 flag;
     197             :     Word16 pitch_lag;
     198             :     Word16 res_shift;
     199             :     Word16 pitch0, tmp, tmp_e;
     200             :     Word32 L_tmp;
     201             :     // shift_mem and shift_input are of same Q q_shift//
     202       15678 :     set16_fx( shift_combined, 0, add( L_FRAME48k, L_FRAME48k ) );
     203       15678 :     set16_fx( residual, 0, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + ( STEREO_DFT_ITD_MAX * input_frame ) / L_FRAME32k );
     204             : 
     205       15678 :     leading_channel = s_and( add( lagging_channel, 1 ), 1 );
     206       15678 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     207             :     {
     208       12105 :         size_ovl = dft_ovl;
     209       12105 :         pitch0 = sts[0]->pitch[0];
     210             :     }
     211             :     ELSE
     212             :     {
     213        3573 :         size_ovl = input_frame;
     214        3573 :         pitch0 = sts[lagging_channel]->pitch[0];
     215             :     }
     216       15678 :     move16();
     217       15678 :     move16();
     218             : 
     219       15678 :     pred_ovlp = idiv1616( input_frame, 10 );
     220             : 
     221             :     /*get pitch lag from previous frame */
     222             :     // pitch_lag = (int16_t) ( pitch0 * ( (float) input_frame / L_FRAME ) );
     223       15678 :     tmp = BASOP_Util_Divide3232_Scale( input_frame, L_FRAME, &tmp_e );
     224       15678 :     L_tmp = L_mult0( pitch0, tmp );
     225       15678 :     pitch_lag = extract_l( L_shr( L_tmp, sub( 15, tmp_e ) ) ); /* Q0 */
     226             : 
     227             :     /* compute the parameters g, nsr and g_lpc */
     228       15678 :     dot_lead_lag = EPSILON_FX;
     229       15678 :     dot_lead_lead = EPSILON_FX;
     230       15678 :     dot_lag_lag = EPSILON_FX;
     231       15678 :     dot_lead_lag_1 = EPSILON_FX;
     232       15678 :     dot_lead_lead_1 = EPSILON_FX;
     233       15678 :     dot_lag_lag_1 = EPSILON_FX;
     234       15678 :     move64();
     235       15678 :     move64();
     236       15678 :     move64();
     237       15678 :     move32();
     238       15678 :     move32();
     239       15678 :     move32();
     240     5878958 :     FOR( i = 0; i < size_ovl; i++ )
     241             :     {
     242     5863280 :         shift_combined[i] = shift_mem[i]; // q_shift
     243     5863280 :         move16();
     244             :         // q_shift_combined = q_shift;
     245     5863280 :         dot_lead_lag = W_mac0_16_16( dot_lead_lag, input_mem[leading_channel][i], shift_mem[i] );
     246     5863280 :         dot_lead_lead = W_mac0_16_16( dot_lead_lead, input_mem[leading_channel][i], input_mem[leading_channel][i] );
     247     5863280 :         dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_mem[i], shift_mem[i] );
     248             :     }
     249    10365666 :     FOR( i = 0; i < input_frame - itd_shift; i++ )
     250             :     {
     251    10349988 :         shift_combined[i + size_ovl] = shift_input[i]; // q_shift
     252    10349988 :         move16();
     253    10349988 :         dot_lead_lag = W_mac0_16_16( dot_lead_lag, sts[leading_channel]->input_fx[i], shift_input[i] );
     254    10349988 :         dot_lead_lead = W_mac0_16_16( dot_lead_lead, sts[leading_channel]->input_fx[i], sts[leading_channel]->input_fx[i] );
     255    10349988 :         dot_lag_lag = W_mac0_16_16( dot_lag_lag, shift_input[i], shift_input[i] );
     256             :     }
     257       15678 :     q_dot_lead_lag = q_shift + q_input_mem[leading_channel]; // q_input_mem = q_input
     258       15678 :     q_dot_lead_lead = q_input_mem[leading_channel] + q_input_mem[leading_channel];
     259       15678 :     q_dot_lag_lag = add( q_shift, q_shift );
     260             : 
     261             : 
     262       15678 :     q_dot_lead_lag = sub( add( q_dot_lead_lag, W_norm( dot_lead_lag ) ), 32 );
     263       15678 :     q_dot_lead_lead = sub( add( q_dot_lead_lead, W_norm( dot_lead_lead ) ), 32 );
     264       15678 :     q_dot_lag_lag = sub( add( q_dot_lag_lag, W_norm( dot_lag_lag ) ), 32 );
     265       15678 :     dot_lead_lag_1 = W_extract_h( W_shl( dot_lead_lag, W_norm( dot_lead_lag ) ) );
     266       15678 :     dot_lead_lead_1 = W_extract_h( W_shl( dot_lead_lead, W_norm( dot_lead_lead ) ) );
     267       15678 :     dot_lag_lag_1 = W_extract_h( W_shl( dot_lag_lag, W_norm( dot_lag_lag ) ) );
     268             : 
     269             : 
     270             :     Word16 g_e, f, f_e, g_lpc_e, nsr_e;
     271       15678 :     g = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lead_lead_1, &g_e );
     272       15678 :     g_e = add( g_e, sub( q_dot_lead_lead, q_dot_lead_lag ) );
     273             : 
     274       15678 :     f = BASOP_Util_Divide3232_Scale( dot_lead_lag_1, dot_lag_lag_1, &f_e );
     275       15678 :     f_e = add( f_e, sub( q_dot_lag_lag, q_dot_lead_lag ) );
     276             : 
     277       15678 :     nsr = mult( g, f );
     278       15678 :     nsr_e = BASOP_Util_Add_MantExp( ONE_IN_Q14, 1, negate( nsr ), add( g_e, f_e ), &nsr );
     279       15678 :     IF( g_e > 0 )
     280             :     {
     281        2932 :         g = check_bounds_s_fx( g, negate( shl( 1, sub( 15, g_e ) ) ), shl( ONE_HALF, sub( 1, g_e ) ) );
     282             :     }
     283       15678 :     IF( nsr_e > 0 )
     284             :     {
     285           0 :         nsr = check_bounds_s_fx( nsr, 0, shl( 1, sub( 15, nsr_e ) ) );
     286             :     }
     287       15678 :     g = shl( g, sub( g_e, 1 ) ); // q14
     288       15678 :     nsr = shl( nsr, nsr_e );     // Q15
     289       15678 :     g_lpc_e = 0;
     290       15678 :     move16();
     291       15678 :     g_lpc = Sqrt16( nsr, &g_lpc_e );
     292       15678 :     g_lpc = shl( g_lpc, sub( g_lpc_e, 1 ) ); // Q14
     293             :     /* rectangular window */
     294       15678 :     set16_fx( window, 32767, STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT );
     295       15678 :     set16_zero_fx( mem_zero, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER );
     296             : 
     297             :     /* get the LPC filter */
     298       15678 :     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 );
     299             :     /* Ensure R[0] isn't zero when entering Levinson-Durbin */
     300       15678 :     r_l[0] = s_max( r_l[0], 1 );
     301       15678 :     move16();
     302      188136 :     FOR( i = 0; i <= STEREO_DFT_CHANNEL_EXTR_LPC_ORDER; i++ )
     303             :     {
     304      172458 :         L_tmp = Mpy_32( r_h[i], r_l[i], wac_swb_h_fx[i], wac_swb_l_fx[i] );
     305      172458 :         L_Extract( L_tmp, &r_h[i], &r_l[i] );
     306             :     }
     307       15678 :     r_l[0] = s_max( r_l[0], 1 );
     308       15678 :     move16();
     309       15678 :     flag = E_LPC_lev_dur( r_h, r_l, A, NULL, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER, NULL );
     310       15678 :     Copy_Scale_sig( A, A, STEREO_DFT_CHANNEL_EXTR_LPC_ORDER + 1, sub( norm_s( A[0] ), 2 ) );
     311       15678 :     IF( EQ_16( flag, 1 ) )
     312             :     {
     313           0 :         g_lpc = 0;
     314           0 :         move16();
     315             :     }
     316             :     ELSE
     317             :     {
     318             :         /* get the residual */
     319       15678 :         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 );
     320             : 
     321             :         /* extend the residual */
     322             :         /* to prevent out of bound reading */
     323       15678 :         IF( LT_16( pitch_lag, PIT_MAX ) )
     324             :         {
     325        9598 :             res_shift = pitch_lag;
     326        9598 :             move16();
     327             :         }
     328             :         ELSE
     329             :         {
     330        6080 :             res_shift = itd_shift;
     331        6080 :             move16();
     332             :         }
     333             : 
     334      653210 :         FOR( i = STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT; i < STEREO_DFT_CHANNEL_EXTR_LPC_VEC_LIMIT + itd_shift; i++ )
     335             :         {
     336      637532 :             residual[i] = residual[i - res_shift];
     337      637532 :             move16();
     338             :         }
     339             : 
     340             :         /* perform sythesis */
     341       15678 :         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 );
     342             :     }
     343             : 
     344       15678 :     Copy( shift_combined + size_ovl, shift_input, input_frame ); // q_shift
     345             : 
     346       15678 :     Word16 offset = sub( input_frame, itd_shift );
     347       15678 :     Word16 offset_pred_ovlp = sub( offset, pred_ovlp );
     348             : 
     349      653210 :     FOR( i = offset; i < input_frame; i++ )
     350             :     {
     351      637532 :         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
     352      637532 :         move16();
     353             :     }
     354       15678 :     Word16 q_temp = sub( q_shift, 2 );
     355             : 
     356             :     /* smooth transition (currently done by blending over linearly, could be replaced by something more elaborate.) */
     357       15678 :     Word16 e_shift = 0;
     358       15678 :     move16();
     359     1114430 :     FOR( i = offset_pred_ovlp; i < offset; i++ )
     360             :     {
     361             :         /*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;*/
     362     1098752 :         L_tmp = L_shr( L_mult0( shift_input[i], sub( offset, i ) ), 1 );                                                                           // q_shift - 1
     363     1098752 :         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
     364             : 
     365     1098752 :         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
     366     1098752 :         move16();
     367     1098752 :         shift_input[i] = shr( shift_input[i], sub( add( sub( 14, e_shift ), q_shift ), q_temp ) ); // q_temp
     368     1098752 :         move16();
     369             :     }
     370             : 
     371             :     // scaling whole buffer to q_temp//
     372     9266914 :     FOR( i = 0; i < offset_pred_ovlp; i++ )
     373             :     {
     374     9251236 :         shift_input[i] = shr( shift_input[i], sub( q_shift, q_temp ) );
     375     9251236 :         move16();
     376             :     }
     377             : 
     378       15678 :     *q_new_shift = q_temp;
     379       15678 :     move16();
     380       15678 :     return;
     381             : }
     382             : 
     383             : /*---------------------------------------------------------------
     384             :  * stereo_td_itd()
     385             :  *
     386             :  *
     387             :  * ---------------------------------------------------------------*/
     388             : 
     389       74349 : void stereo_td_itd_fx(
     390             :     ITD_DATA *hITD,                                         /* i/o: ITD data structure                    */
     391             :     Word16 input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o  : ITD memory (only used in DFT Stereo)  q_input_mem_itd*/
     392             :     Word16 *q_input_mem_itd,
     393             :     const Word16 hybrid_itd_flag,    /* i  : flag for hybrid TD/FD ITD processing  */
     394             :     const Word16 dft_ovl,            /* i  : size of DFT overlap                   */
     395             :     Encoder_State **sts,             /* i/o: Encoder state structure               */
     396             :     const Word16 input_frame,        /* i  : input frame length                    */
     397             :     Word16 *input_mem[CPE_CHANNELS], /* i/o: input buffer memory       q_input_mem            */
     398             :     Word16 *q_input_mem )
     399             : {
     400             :     Word16 i, ch, n;
     401             :     Word16 size_ovl, k_offset;
     402             :     Word16 shift[2];
     403             :     Word16 itd, itd_max;
     404             :     Word16 shift_input[L_FRAME48k];
     405             :     Word16 shift_mem[L_FRAME48k];
     406             :     Word16 q_shift_mem;
     407             :     Word16 *mdct_mem[CPE_CHANNELS];
     408             :     // Word16 q_mdct_mem[CPE_CHANNELS];
     409             :     Word16 q_shift, q_new_shift;
     410             : 
     411       74349 :     k_offset = STEREO_DFT_OFFSET;
     412       74349 :     move16();
     413       74349 :     set16_fx( shift_input, 0, input_frame );
     414             : 
     415       74349 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) )
     416             :     {
     417       44070 :         FOR( n = 0; n < CPE_CHANNELS; n++ )
     418             :         {
     419       29380 :             mdct_mem[n] = sts[n]->old_input_signal_fx;
     420       29380 :             move16();
     421             :             // q_mdct_mem[n] = sts[n]->q_old_inp;
     422             :         }
     423             :     }
     424       74349 :     IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     425             :     {
     426             :         /* Update the parameters */
     427      119318 :         FOR( i = 0; i < k_offset; i++ )
     428             :         {
     429       59659 :             hITD->deltaItd_fx[i] = hITD->deltaItd_fx[i + 1];
     430       59659 :             move32();
     431       59659 :             hITD->td_itd[i] = hITD->td_itd[i + 1];
     432       59659 :             move16();
     433       59659 :             hITD->td_itd_32k[i] = hITD->td_itd_32k[i + 1];
     434       59659 :             move16();
     435             :         }
     436             :     }
     437             :     /*reset TD ITDs in case of hybrid itd_max change - turn hybrid ITD off*/
     438       74349 :     test();
     439       74349 :     IF( EQ_16( hITD->hybrid_itd_max, -1 ) && EQ_16( hybrid_itd_flag, 0 ) )
     440             :     {
     441          16 :         hITD->td_itd[k_offset] = 0;
     442          16 :         move16();
     443          16 :         hITD->td_itd_32k[k_offset] = 0;
     444          16 :         move16();
     445             :     }
     446       74349 :     IF( EQ_16( hybrid_itd_flag, 0 ) )
     447             :     {
     448       38920 :         return;
     449             :     }
     450       35429 :     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 );
     451             : 
     452             :     /* initializations*/
     453             :     {
     454       35429 :         size_ovl = dft_ovl;
     455       35429 :         move16();
     456             : 
     457       35429 :         itd_max = shr( input_frame, 2 );
     458       35429 :         Word16 comp_flag1 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[k_offset], Q16 ) ), itd_max ) );
     459       35429 :         Word16 comp_flag2 = extract_l( LE_16( extract_l( L_shr( hITD->itd_fx[sub( k_offset, 1 )], Q16 ) ), itd_max ) );
     460       35429 :         assert( ( comp_flag1 ) && "ITD value is too high!" );
     461       35429 :         assert( ( comp_flag2 ) && "ITD value is too high!" );
     462             : 
     463       35429 :         itd = hITD->td_itd[k_offset];
     464             : 
     465             :         /*Time shift with current ITD*/
     466       35429 :         IF( LT_16( itd, 0 ) )
     467             :         {
     468       10441 :             shift[1] = 0;
     469       10441 :             move16();
     470       10441 :             shift[0] = negate( itd );
     471       10441 :             move16();
     472       10441 :             ch = 0;
     473       10441 :             move16();
     474             :         }
     475             :         ELSE
     476             :         {
     477       24988 :             shift[1] = itd;
     478       24988 :             move16();
     479       24988 :             shift[0] = 0;
     480       24988 :             move16();
     481       24988 :             ch = 1;
     482       24988 :             move16();
     483             :         }
     484             : 
     485             :         /* extrapolate lagging channel */
     486       35429 :         IF( GT_16( shift[ch], 0 ) )
     487             :         {
     488       15678 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     489             :             {
     490             :                 /* store last part of signal before extrapolation */
     491       36315 :                 FOR( n = 0; n < CPE_CHANNELS; n++ )
     492             :                 {
     493       24210 :                     Copy( sts[n]->input_fx + input_frame - dft_ovl, input_mem_itd[n], dft_ovl );
     494       24210 :                     q_input_mem_itd[n] = sts[n]->q_inp;
     495       24210 :                     move16();
     496             :                 }
     497             : 
     498             :                 /*shift past part*/
     499       12105 :                 Copy( input_mem[ch] + shift[ch], shift_mem, sub( size_ovl, shift[ch] ) );
     500       12105 :                 Copy( sts[ch]->input_fx, shift_mem + size_ovl - shift[ch], shift[ch] );
     501       12105 :                 q_shift_mem = sts[ch]->q_inp;
     502       12105 :                 move16();
     503             :             }
     504             :             ELSE
     505             :             {
     506             :                 /*shift past part*/
     507        3573 :                 Copy( mdct_mem[ch] + shift[ch], shift_mem, input_frame - shift[ch] );
     508        3573 :                 Copy( sts[ch]->input_fx, shift_mem + input_frame - shift[ch], shift[ch] );
     509        3573 :                 q_shift_mem = sts[ch]->q_inp;
     510        3573 :                 move16();
     511             :             }
     512             :             /*shift current part*/
     513       15678 :             Copy( sts[ch]->input_fx + shift[ch], shift_input, sub( input_frame, shift[ch] ) );
     514             : 
     515       15678 :             q_shift = sts[ch]->q_inp;
     516       15678 :             move16();
     517             :             // q_shift is shift for both shift_mem and shift_inp//
     518             :             // both channels input maintain same q//
     519       15678 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     520             :             {
     521             :                 /*Extrapolate current frame*/
     522       12105 :                 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 );
     523             :             }
     524             :             ELSE
     525             :             {
     526             :                 /*Extrapolate current frame*/
     527        3573 :                 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 );
     528             :             }
     529             : 
     530             :             /* write back the extrapolated signal into sts[ch]->input */
     531       15678 :             Copy( shift_input, sts[ch]->input_fx, input_frame );
     532       15678 :             sts[ch]->q_inp = q_new_shift;
     533       15678 :             move16();
     534       15678 :             Copy_Scale_sig_16_32_no_sat( sts[ch]->input_fx, sts[ch]->input32_fx, input_frame, sub( sts[ch]->q_inp32, sts[ch]->q_inp ) );
     535             : 
     536       15678 :             IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) )
     537             :             {
     538             :                 // here shift_mem has same as input_mem, no need to update q //
     539       12105 :                 Copy( shift_mem, input_mem[ch], size_ovl );
     540             :             }
     541             :             ELSE
     542             :             {
     543        3573 :                 Copy( shift_mem, mdct_mem[ch], input_frame );
     544        3573 :                 sts[ch]->q_old_inp = q_new_shift;
     545        3573 :                 move16();
     546        3573 :                 Scale_sig( mdct_mem[ch], input_frame, sub( sts[ch]->q_inp, q_shift_mem ) ); // Q(sts[ch]->q_inp)
     547        3573 :                 Copy_Scale_sig_16_32_no_sat( shift_mem, sts[ch]->old_input_signal32_fx, input_frame, sub( sts[ch]->q_old_inp32, q_shift_mem ) );
     548             :             }
     549             :         }
     550             :     }
     551             : 
     552       35429 :     return;
     553             : }
     554             : 
     555             : /*---------------------------------------------------------------
     556             :  * stereo_td_itd_mdct_stereo()
     557             :  *
     558             :  * Time-domain ITD in MDCT stereo
     559             :  * ---------------------------------------------------------------*/
     560      346785 : void stereo_td_itd_mdct_stereo_fx(
     561             :     CPE_ENC_HANDLE hCPE,           /* i/o: CPE encoder handle     */
     562             :     const Word16 vad_flag_dtx[],   /* i  : VAD dtx flags          */
     563             :     const Word16 vad_hover_flag[], /* i  : VAD hangover flags     */
     564             :     const Word16 input_frame       /* i  : frame length           */
     565             : )
     566             : {
     567             :     Word16 i;
     568             :     Word32 bin_nrgL_fx[STEREO_DFT_N_32k_ENC];
     569             :     Word16 bin_nrgL_e[STEREO_DFT_N_32k_ENC];
     570             :     Word32 bin_nrgR_fx[STEREO_DFT_N_32k_ENC];
     571             :     Word16 bin_nrgR_e[STEREO_DFT_N_32k_ENC];
     572             :     Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
     573             :     Word16 DFT_e[CPE_CHANNELS];
     574             :     Word16 DFT_tmp_e[CPE_CHANNELS][STEREO_DFT_N_MAX_ENC];
     575             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct;
     576             : 
     577      346785 :     test();
     578      346785 :     IF( hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL )
     579             :     {
     580       14690 :         hStereoMdct = hCPE->hStereoMdct;
     581             : 
     582       14690 :         hCPE->hStereoMdct->hItd->td_itd_32k[STEREO_DFT_OFFSET] = 0;
     583       14690 :         move16();
     584       14690 :         hStereoMdct->hItd->td_itd[STEREO_DFT_OFFSET] = 0;
     585       14690 :         move16();
     586             : 
     587             :         /* Update the parameters */
     588       29380 :         FOR( i = 0; i < STEREO_DFT_OFFSET; i++ )
     589             :         {
     590       14690 :             hStereoMdct->hItd->deltaItd_fx[i] = hStereoMdct->hItd->deltaItd_fx[i + 1];
     591       14690 :             move32();
     592       14690 :             hStereoMdct->hItd->td_itd[i] = hStereoMdct->hItd->td_itd[i + 1];
     593       14690 :             move16();
     594       14690 :             hStereoMdct->hItd->td_itd_32k[i] = hStereoMdct->hItd->td_itd_32k[i + 1];
     595       14690 :             move16();
     596             :         }
     597             : 
     598       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 );
     599             : 
     600    28219490 :         FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ )
     601             :         {
     602    28204800 :             DFT_tmp_e[0][i] = DFT_e[0];
     603    28204800 :             move16();
     604    28204800 :             DFT_tmp_e[1][i] = DFT_e[1];
     605    28204800 :             move16();
     606             :         }
     607             : 
     608             :         /*call ITD function*/
     609       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 );
     610             : 
     611             :         /* Time Domain ITD compensation using extrapolation */
     612       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 );
     613             :     }
     614             : 
     615      346785 :     return;
     616             : }

Generated by: LCOV version 1.14