From c5d004986a37a13dc0b253cb6685dcf1c924a7c4 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 21 Feb 2024 12:16:15 +0530 Subject: [PATCH] Functions in ivas_stereo_icbwe_dec.c converted to fixed point. This commit includes stereo_icBWE_dec and functions converted to support 32 bit data types which includes GenSHBSynth, ScaleShapedSHB, Decimate_allpass_steep, interpolate_3_over_2_allpass, Interpolate_allpass_steep, deemph_32 --- lib_com/deemph.c | 25 + lib_com/ivas_prot_fx.h | 11 + lib_com/ivas_rom_com.c | 29 + lib_com/ivas_rom_com.h | 3 + lib_com/modif_fs.c | 199 +++++++ lib_com/prot_fx1.h | 5 + lib_com/prot_fx2.h | 70 ++- lib_com/swb_tbe_com.c | 357 ++++++++++++ lib_com/tools_fx.c | 29 + lib_dec/ivas_core_dec.c | 65 +++ lib_dec/ivas_stat_dec.h | 64 ++- lib_dec/ivas_stereo_ica_dec.c | 2 +- lib_dec/ivas_stereo_icbwe_dec.c | 946 ++++++++++++++++++++++++++++---- 13 files changed, 1661 insertions(+), 144 deletions(-) diff --git a/lib_com/deemph.c b/lib_com/deemph.c index a773bda5c..c5fa5da62 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -71,6 +71,31 @@ void deemph( return; } +void deemph_fx_32( + Word16 shift, /*scaled output*/ + Word32 *signal, /* i/o: signal Qx*/ + const Word16 mu, /* i : deemphasis factor Q15*/ + const int16_t L, /* i : vector size */ + Word32 *mem /* i/o: memory (y[-1]) Qx*/ +) +{ + int16_t i; + + signal[0] = L_add(signal[0] , Mpy_32_16_1( ( *mem ), mu )); + FOR ( i = 1; i < L; i++ ) + { + signal[i] = L_add(signal[i] , Mpy_32_16_1( signal[i - 1], mu )); + signal[i] = L_shl(signal[i], shift); + } + + *mem = signal[L - 1]; + move32(); + + return; +} + + + /*========================================================================*/ /* FUNCTION : deemph_fx() */ /*------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index be77c232a..b18dcbdd2 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1143,4 +1143,15 @@ void TonalMdctConceal_whiten_noise_shape_ivas_fx( Decoder_State *st, const Word16 L_frame, const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ); + +void stereo_icBWE_dec_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *synthRef_fx, /* i/o: Reference channel HB synthesis at output Fs */ + Word32 *synth_fx, /* o : Non reference channel HB synthesis at output Fs */ + const Word32 *fb_synth_ref, /* i : ref. high-band synthesis 16-20 kHz */ + const Word32 *voice_factors, /* i : voicing factors */ + const Word16 output_frame, /* i : frame length */ + Word16 *Q_syn + ); + #endif diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index f22049f8e..e553375ee 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -585,6 +585,13 @@ const float icbwe_gsMapping_tbl[16] = -0.1690688f, -0.0987095f, -0.0700000f, -0.0500000f, -0.0200000f, 0.0000000f, 0.0400000f, 0.0800000f }; +const Word16 pow_10_icbwe_gsMapping_tbl_fx[16] = //Q14 +{ + 164 ,733 ,1793 ,3195 ,4524 ,5875 ,7438 ,9155 ,11101 ,13053 ,13945 ,14602 ,15647 ,16384 , + 17965 ,19698 +}; + + const float icbwe_gsMappingDFT_tbl[128] = { -5.0000000f, -4.5000000f, -4.0000000f, -3.5000000f, -3.0000000f, -2.5000000f, -1.9000000f, -1.5474502f, @@ -605,6 +612,20 @@ const float icbwe_gsMappingDFT_tbl[128] = 0.0155180f, 0.0224511f, 0.0298570f, 0.0375954f, 0.0457853f, 0.0549424f, 0.0659733f, 0.0785186f }; +const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[128] = //Q14 +{ + 0 ,1 ,2 ,5 ,16 ,52 ,206 ,464 ,518 ,585 ,667 ,688 ,803 ,899 , + 1324 ,1349 ,1513 ,1534 ,1578 ,1625 ,1711 ,1756 ,1808 ,1879 ,1926 ,2001 ,2050 ,2130 , + 2191 ,2280 ,2366 ,2394 ,2456 ,2574 ,2643 ,2726 ,2796 ,2850 ,2869 ,2908 ,2962 ,2991 , + 3023 ,3051 ,3091 ,3130 ,3202 ,3233 ,3268 ,3342 ,3388 ,3429 ,3483 ,3519 ,3553 ,3595 , + 3651 ,3706 ,3738 ,3795 ,3844 ,3890 ,3946 ,3990 ,4028 ,4075 ,4119 ,4166 ,4214 ,4259 , + 4303 ,4350 ,4389 ,4441 ,4481 ,4540 ,4605 ,4684 ,4764 ,4854 ,4950 ,5068 ,5198 ,5348 , + 5519 ,5692 ,5881 ,6073 ,6273 ,6473 ,6676 ,6883 ,7124 ,7364 ,7616 ,7852 ,8097 ,8370 , + 8630 ,8916 ,9200 ,9496 ,9866 ,10252 ,10652 ,11052 ,11436 ,11813 ,12247 ,12697 ,13153 ,13611 , + 14072 ,14503 ,14936 ,15336 ,15702 ,16032 ,16384 ,16664 ,16980 ,17253 ,17550 ,17866 ,18206 ,18594 , + 19072 ,19631 +}; + /*----------------------------------------------------------------------------------* * TD Stereo ROM tables @@ -617,6 +638,14 @@ const float tdm_ratio_tabl[TDM_NQ+1] = 0.5523f, 0.6040f, 0.6545f, 0.7034f, 0.7500f, 0.7939f, 0.8346f, 0.8716f, 0.9045f, 0.9330f, 0.9568f, 0.9755f, 0.9891f, 1.0000f, 1.0000f, 1.0000f }; + +const Word16 tdm_ratio_tabl_fx[TDM_NQ+1] /*Q15*/= +{ + 0 ,0 ,357 ,803 ,1416 ,2195 ,3129 ,4207 ,5420 ,6753 ,8192 ,9719 ,11321 ,12976 , + 14670 ,16384 ,18097 ,19791 ,21446 ,23048 ,24575 ,26014 ,27347 ,28560 ,29638 ,30572 ,31351 ,31964 , + 32410 ,32767 ,32767 ,32767 , +}; + const float tdm_den_ratio_tabl[TDM_NQ+1] = /* 1.0f/(2*LR_ratio*LR_ratio-2*LR_ratio+1) */ { 1.0000f, 1.0000f, 1.0221f, 1.0501f, 1.0902f, 1.1429f, 1.2088f, 1.2884f, diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index ee235d947..846e9f9b6 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -95,13 +95,16 @@ extern const float ica_sincInterp6[]; *----------------------------------------------------------------------------------*/ extern const float icbwe_gsMapping_tbl[]; +extern const Word16 pow_10_icbwe_gsMapping_tbl_fx[]; extern const float icbwe_gsMappingDFT_tbl[]; +extern const Word16 pow_10_icbwe_gsMappingDFT_tbl_fx[]; /*----------------------------------------------------------------------------------* * TD Stereo ROM tables *----------------------------------------------------------------------------------*/ extern const float tdm_ratio_tabl[]; +extern const Word16 tdm_ratio_tabl_fx[]; extern const float tdm_den_ratio_tabl[]; extern const int16_t tdm_bit_allc_tbl[5][6]; diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index f927dd921..59753930a 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -525,7 +525,54 @@ void Interpolate_allpass_steep( return; } +#ifdef IVAS_FLOAT_FIXED +void Interpolate_allpass_steep_32( + const Word32 *in_fx, /* i : input array of size N Qx */ + Word32 *mem_fx, /* i/o: memory Qx */ + const int16_t N, /* i : number of input samples */ + Word32 *out_fx /* o : output array of size 2*N Qx */ +) +{ + int16_t n, k; + Word32 temp_fx[ALLPASSSECTIONS_STEEP - 1]; + + /* upper allpass filter chain */ + FOR( k = 0; k < N; k++ ) + { + temp_fx[0] = L_add(mem_fx[0] , Mpy_32_16_1( in_fx[k], AP2_STEEP_FX[0] )); + mem_fx[0] = L_sub(in_fx[k] , Mpy_32_16_1( temp_fx[0], AP2_STEEP_FX[0] )); + + /* for better performance, unroll this loop */ + FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) + { + temp_fx[n] = L_add(mem_fx[n] , Mpy_32_16_1( temp_fx[n - 1], AP2_STEEP_FX[n] )); + mem_fx[n] = L_sub(temp_fx[n - 1] , Mpy_32_16_1( temp_fx[n], AP2_STEEP_FX[n] )); + } + + out_fx[2 * k + 1] = L_add(mem_fx[ALLPASSSECTIONS_STEEP - 1] , Mpy_32_16_1( temp_fx[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] )); + mem_fx[ALLPASSSECTIONS_STEEP - 1] = L_sub(temp_fx[ALLPASSSECTIONS_STEEP - 2] , Mpy_32_16_1( out_fx[2 * k + 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] )); + } + /* lower allpass filter chain */ + FOR( k = 0; k < N; k++ ) + { + temp_fx[0] = L_add(mem_fx[ALLPASSSECTIONS_STEEP] , Mpy_32_16_1( in_fx[k], AP1_STEEP_FX[0] )); + mem_fx[ALLPASSSECTIONS_STEEP] = L_sub(in_fx[k] , Mpy_32_16_1( temp_fx[0], AP1_STEEP_FX[0] )); + + /* for better performance, unroll this loop */ + FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) + { + temp_fx[n] = L_add(mem_fx[ALLPASSSECTIONS_STEEP + n] , Mpy_32_16_1( temp_fx[n - 1], AP1_STEEP_FX[n] )); + mem_fx[ALLPASSSECTIONS_STEEP + n] = L_sub(temp_fx[n - 1] , Mpy_32_16_1( temp_fx[n], AP1_STEEP_FX[n] )); + } + + out_fx[2 * k] = L_add(mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] , Mpy_32_16_1( temp_fx[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] )); + mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub(temp_fx[ALLPASSSECTIONS_STEEP - 2] , Mpy_32_16_1( out_fx[2 * k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] )); + } + + return; +} +#endif /*-------------------------------------------------------------------* * Decimate_allpass_steep() * @@ -613,7 +660,78 @@ void Decimate_allpass_steep( return; } +#ifdef IVAS_FLOAT_FIXED +void Decimate_allpass_steep_fx32( + const Word32 *in, /* i : input array of size N Qx */ + Word32 *mem, /* i/o: memory Qx*/ + const Word16 N, /* i : number of input samples */ + Word32 *out /* o : output array of size N/2 Qx*/ +) +{ + Word16 n, k; + Word32 temp[ALLPASSSECTIONS_STEEP]; + + /* upper allpass filter chain */ + FOR( k = 0; k < N / 2; k++ ) + { + temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); + mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); + + temp[1] = L_add( mem[1], Mpy_32_16_1( temp[0], AP1_STEEP_FX[1] ) ); + mem[1] = L_sub( temp[0], Mpy_32_16_1( temp[1], AP1_STEEP_FX[1] ) ); + + out[k] = L_add( mem[ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + } + + /* lower allpass filter chain */ + temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); + mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); + + /* for better performance, unroll this loop */ + FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) + { + temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); + /*if ( fabs( temp[n] ) < 1e-12 ) + { + temp[n] = sign( temp[n] ) * 1e-12f; + }*/ + mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); + } + + temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + + mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + out[0] = L_add( out[0], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); + + FOR( k = 1; k < N / 2; k++ ) + { + temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[2 * k - 1], AP2_STEEP_FX[0] ) ); + mem[ALLPASSSECTIONS_STEEP] = L_sub( in[2 * k - 1], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); + /* for better performance, unroll this loop */ + FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ ) + { + temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); + /*if ( fabs( temp[n] ) < 1e-12 ) + { + temp[n] = sign( temp[n] ) * 1e-12f; + }*/ + mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n - 1] ) ); + } + + temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); + out[k] = L_add( out[k], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], 16384 ) ); + } + + /* z^(-1) */ + mem[2 * ALLPASSSECTIONS_STEEP] = in[N - 1]; + move32(); + + return; +} +#endif /*-------------------------------------------------------------------* * interpolate_3_over_2_allpass() * @@ -684,7 +802,88 @@ void interpolate_3_over_2_allpass( return; } +#ifdef IVAS_FLOAT_FIXED +void interpolate_3_over_2_allpass_32( + const Word32 *input, /* i : input signal Qx*/ + const int16_t len, /* i : number of input samples */ + Word32 *out, /* o : output signal Qx*/ + Word32 *mem /* i/o: memory Qx*/ +) +{ + int16_t i, loop_len; + Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */ + Word32 out1_buff[L_FRAME32k * 3]; + Word32 *out1; + Word32 mem_temp; + const Word16 *filt_coeff = allpass_poles_3_ov_2; + + out1 = out1_buff; + + FOR( i = 0; i < len; i++ ) + { + /* Upper branch */ + Vu[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[1] ), filt_coeff[0] ) ); + Vu[1] = L_add( mem[1], Mpy_32_16_1( ( Vu[0] - mem[2] ), filt_coeff[1] ) ); + mem[3] = L_add( mem[2], Mpy_32_16_1( ( Vu[1] - mem[3] ), filt_coeff[2] ) ); + + mem[1] = Vu[0]; + move32(); + mem[2] = Vu[1]; + move32(); + *out1++ = mem[3]; + move32(); + + /* Middle branch */ + Vm[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[4] ), filt_coeff[3] ) ); + Vm[1] = L_add( mem[4], Mpy_32_16_1( ( Vm[0] - mem[5] ), filt_coeff[4] ) ); + mem[6] = L_add( mem[5], Mpy_32_16_1( ( Vm[1] - mem[6] ), filt_coeff[5] ) ); + mem[4] = Vm[0]; + move32(); + mem[5] = Vm[1]; + move32(); + *out1++ = mem[6]; + move32(); + + /* Lower branch */ + Vl[0] = L_add( mem[0], Mpy_32_16_1( ( input[i] - mem[7] ), filt_coeff[6] ) ); + Vl[1] = L_add( mem[7], Mpy_32_16_1( ( Vl[0] - mem[8] ), filt_coeff[7] ) ); + mem[9] = L_add( mem[8], Mpy_32_16_1( ( Vl[1] - mem[9] ), filt_coeff[8] ) ); + + mem[0] = input[i]; + move32(); + mem[7] = Vl[0]; + move32(); + mem[8] = Vl[1]; + move32(); + *out1++ = mem[9]; + move32(); + } + + loop_len = shr( i_mult( len, 3 ), 1 ); + + /*decimate by 2 and LPF*/ + FOR( i = 0; i < loop_len; i++ ) + { + mem_temp = out1_buff[2 * i]; + move32(); + out[i] = L_add( Mpy_32_16_1( ( mem_temp + mem[10] ), 1550 ), Mpy_32_16_1( ( mem[11] + mem[14] ), -4965 ) ); + out[i] = L_add( out[i], Mpy_32_16_1( ( mem[12] + mem[13] ), 20125 ) ); + mem[10] = mem[11]; + move32(); + mem[11] = mem[12]; + move32(); + mem[12] = mem[13]; + move32(); + mem[13] = mem[14]; + move32(); + mem[14] = mem_temp; + move32(); + } + + return; +} +#endif /*-------------------------------------------------------------------* * decimate_2_over_3_allpass() * diff --git a/lib_com/prot_fx1.h b/lib_com/prot_fx1.h index fe129eed3..f1fa2fe2e 100644 --- a/lib_com/prot_fx1.h +++ b/lib_com/prot_fx1.h @@ -186,6 +186,11 @@ Word16 maximum_32_fx( /* o : index of the maximum value i const Word16 lvec, /* i : length of input vector */ Word32 *max_val /* o : maximum value in the input vector */ ); +Word16 maximum_abs_32_fx( /* o : index of the maximum value in the input vector */ + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word32 *max_val /* o : maximum value in the input vector */ +); Word16 Exp16Array( const Word16 n, /* (i): Array size */ const Word16 *sx /* (i): Data array */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 3e9039144..a1a1888ba 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -1396,6 +1396,14 @@ void deemph_fx( void E_UTIL_deemph2(Word16 shift, Word16 *x, const Word16 mu, const Word16 L, Word16 *mem); +void deemph_fx_32( + Word16 shift, /* i : scaled output */ + Word32 *signal, /* i/o: signal */ + const Word16 mu, /* i : deemphasis factor */ + const int16_t L, /* i : vector size */ + Word32 *mem /* i/o: memory (y[-1]) */ +); + //int_lsp.c void int_lsp_fx( const Word16 L_frame, /* i : length of the frame */ @@ -2610,6 +2618,14 @@ void GenSHBSynth_fx( Word16 *syn_dm_phase ); +void GenSHBSynth_fx_32( + const Word32 *input_synspeech, /* i : input synthesized speech */ + Word32 *shb_syn_speech_32k, /* o : output highband component */ + Word32 Hilbert_Mem[], /* i/o: memory */ + Word32 state_lsyn_filt_shb_local[], /* i/o: memory */ + const int16_t L_frame, /* i : ACELP frame length */ + int16_t *syn_dm_phase); + void ScaleShapedSHB_fx( const Word16 length, /* i : SHB overlap length */ Word16 *synSHB, /* i/o: synthesized shb signal */ @@ -2624,6 +2640,18 @@ void ScaleShapedSHB_fx( , Word16 prev_Q_bwe_syn2 ); +void ScaleShapedSHB_32( + const int16_t length, /* i : SHB overlap length */ + Word32 *synSHB_fx, /* i/o: synthesized shb signal Qx */ + Word32 *overlap_fx, /* i/o: buffer for overlap-add Qx */ + const Word16 *subgain_fx, /* i : subframe gain Q15 */ + const Word32 frame_gain_fx, /* i : frame gain */ + const Word16 *win_fx, /* i : window Q15 */ + const Word16 *subwin_fx, /* i : subframes window Q15 */ + Word16 *Q_inp, + Word16 *Q_new + ); + void ScaleShapedWB_fx( const Word16 length, /* i : SHB overlap length */ Word16* synSHB, /* i/o : synthesized shb signal */ @@ -8386,16 +8414,38 @@ void resampleCldfb_ivas_fx( ); void generate_masking_noise_dirac_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA */ - Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer */ - Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer */ - const Word16 slot_index, /* i : CLDFB slot index */ - const Word16 cna_flag, /* i : CNA flag for LB and HB */ - const Word16 fd_cng_flag, /* i : FD-CNG flag for HB */ - Word16 q_input, - Word16 *q_cldfb + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA */ + Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer */ + Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer */ + const Word16 slot_index, /* i : CLDFB slot index */ + const Word16 cna_flag, /* i : CNA flag for LB and HB */ + const Word16 fd_cng_flag, /* i : FD-CNG flag for HB */ + Word16 q_input, + Word16 *q_cldfb +); +//modif_fs/c + +void interpolate_3_over_2_allpass_32( + const Word32 *input, /* i : input signal */ + const int16_t len, /* i : number of input samples */ + Word32 *out, /* o : output signal */ + Word32 *mem /* i/o: memory */ +); + +void Decimate_allpass_steep_fx32( + const Word32 *in, /* i : input array of size N */ + Word32 *mem, /* i/o: memory */ + const Word16 N, /* i : number of input samples */ + Word32 *out /* o : output array of size N/2 */ +); + +void Interpolate_allpass_steep_32( + const Word32 *in_fx, /* i : input array of size N */ + Word32 *mem_fx, /* i/o: memory */ + const int16_t N, /* i : number of input samples */ + Word32 *out_fx /* o : output array of size 2*N */ ); #endif diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index 75e07f2b7..472498530 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -39,6 +39,8 @@ #include #include "cnst.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "rom_com.h" #include "wmc_auto.h" #include "ivas_prot.h" @@ -54,6 +56,7 @@ static void create_random_vector( float output[], const int16_t length, int16_t seed[] ); static void flip_spectrum( const float input[], float output[], const int16_t length ); static void Hilbert_transform( float tmp_R[], float tmp_I[], float *tmpi_R, float *tmpi_I, const int16_t length, const int16_t HB_stage_id ); +static void Hilbert_transform_fx_32(Word32 tmp_R[], Word32 tmp_I[], Word32 *tmpi_R, Word32 *tmpi_I, const Word16 length, const Word16 HB_stage_id); static void Estimate_mix_factors( const float *shb_res, const float *exc16kWhtnd, const float *White_exc16k, const float pow1, const float pow22, float *vf_modified, int16_t *vf_ind ); /*-------------------------------------------------------------------* @@ -236,6 +239,135 @@ void flip_and_downmix_generic( return; } +#ifdef IVAS_FLOAT_FIXED +void flip_and_downmix_generic_fx_32( + Word32 input[], /* i : input spectrum Qx*/ + Word32 output[], /* o : output spectrum Qx*/ + const Word16 length, /* i : length of spectra */ + Word32 mem1_ext[HILBERT_ORDER1], /* i/o: memory Qx*/ + Word32 mem2_ext[2*HILBERT_ORDER2], /* i/o: memory Qx*/ + Word32 mem3_ext[2*HILBERT_ORDER2], /* i/o: memory Qx*/ + Word16* phase_state /* i/o: Phase state in case frequency isn't multiple of 50 Hz */ +) +{ + Word16 i, j; + Word32 tmp[L_FRAME32k + HILBERT_ORDER1]; + Word32 tmpi_R[L_FRAME32k]; + Word32 tmpi_I[L_FRAME32k]; + Word32 tmpi2_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmpi2_I[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_R[L_FRAME32k + HILBERT_ORDER2]; + Word32 tmp_I[L_FRAME32k + HILBERT_ORDER2]; + + /*Word16 s_tmp[L_FRAME32k];*/ + /*Word16 factor;*/ + Word16 period; + Word16 local_negsin_table17[17] = { 0, -11793, -22005, -29268, -32609, -31580, + -26319, -17530, -6393, 6393, 17530, 26319, + 31580, 32609, 29268, 22005, 11793 + }; /* Q15 */ + Word16 local_cos_table17[17] = {32767, 30571, 24279, 14732, 3212, -8739, + -19519, -27683, -32137, -32137, -27683, + -19519, -8739, 3212, 14732, 24279, 30571 + }; /* Q15 */ + Word16 *local_negsin_table, *local_cos_table; + Word32 L_tmp; + + /* 1850 Hz downmix */ + period = 17; + move16(); + local_negsin_table = local_negsin_table17; + local_cos_table = local_cos_table17; + + + FOR (i = 0; i < length; i = i + 2 ) + { + input[i] = L_negate( input[i] ); + move16(); + } + + Copy32(input, tmp + HILBERT_ORDER1, length ); + Copy32( mem1_ext, tmp, HILBERT_ORDER1); + + /* Hilber transform stage - 0 - single precision */ + Hilbert_transform_fx_32( tmp, /* i: Real component of HB */ + tmp, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 0); /* i: HB transform stage */ + + + Copy32( mem2_ext, tmpi2_R, HILBERT_ORDER2 ); + Copy32( mem3_ext, tmpi2_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 1 */ + Hilbert_transform_fx_32( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmpi2_R, /* o: Real component of HB */ + tmpi2_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 1); /* i: HB transform stage */ + + Copy32( mem2_ext+HILBERT_ORDER2, tmp_R, HILBERT_ORDER2 ); + Copy32( mem3_ext+HILBERT_ORDER2, tmp_I, HILBERT_ORDER2 ); + + /* Hilber transform stage - 2 */ + Hilbert_transform_fx_32( tmpi2_R, /* i: Real component of HB */ + tmpi2_I, /* i: Imag component of HB */ + tmpi_R, /* o: Real component of HB */ + tmpi_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 2); /* i: HB transform stage */ + + Copy32( tmpi2_R + length, mem2_ext, HILBERT_ORDER2 ); + Copy32( tmpi2_I + length, mem3_ext, HILBERT_ORDER2 ); + + /* Hilber transform stage - 3 */ + Hilbert_transform_fx_32( tmpi_R, /* i: Real component of HB */ + tmpi_I, /* i: Imag component of HB */ + tmp_R, /* o: Real component of HB */ + tmp_I, /* o: Imag. component of HB */ + length, /* i: length of the spectra */ + 3); /* i: HB transform stage */ + + Copy32( tmp_R + length, mem2_ext+HILBERT_ORDER2, HILBERT_ORDER2 ); + Copy32( tmp_I + length, mem3_ext+HILBERT_ORDER2, HILBERT_ORDER2 ); + + if ( *phase_state >= period ) + { + *phase_state = 0; + move16(); + } + + i = 0; + move16(); + j = *phase_state; + move16(); + + WHILE ( i < length ) + { + WHILE ( ( j < period ) && ( i < length ) ) + { + L_tmp = Mult_32_16( tmp_R[i + 4], local_cos_table[j] ); /*//Qx+16 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + 4], local_negsin_table[j] ); /*Qx+16 */ + output[i] = L_tmp ; /*Qx */ + i++ ; + j++ ; + } + + if ( j >= period ) + { + j = 0; + move16(); + } + } + + *phase_state = j; + move16(); + return; +} +#endif /*---------------------------------------------- * Hilbert_transform() @@ -279,6 +411,64 @@ static void Hilbert_transform( return; } +static void Hilbert_transform_fx_32( + Word32 tmp_R[], /* i: Real component of HB */ + Word32 tmp_I[], /* i: Real component of HB */ + Word32 tmpi_R[], /* o: Real component of HB */ + Word32 tmpi_I[], /* o: Imag. component of HB */ + const Word16 length, /* i: input length */ + const Word16 HB_stage_id /* i: HB transform stage */ +) +{ + Word16 i, hb_filter_stage, offset; + Word32 L_tmp; + + hb_filter_stage = 2*HB_stage_id; + offset = 0; + move16(); + if( HB_stage_id == 0 ) + { + offset = 1; + move16(); + } + + test(); + test(); + IF (HB_stage_id == 0 || HB_stage_id == 2) + { + FOR ( i = 0; i < length; i++ ) + { + L_tmp = Mult_32_16( tmp_R[i + 4], Hilbert_coeffs_fx[hb_filter_stage][0 + offset] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2 + offset] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_R[i] , Hilbert_coeffs_fx[hb_filter_stage][4 + offset] );/*Qx+15 */ + tmpi_R[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + + L_tmp = Mult_32_16( tmp_I[i + 4 + offset], Hilbert_coeffs_fx[hb_filter_stage+1][0] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + 2 + offset], Hilbert_coeffs_fx[hb_filter_stage+1][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmp_I[i + offset] , Hilbert_coeffs_fx[hb_filter_stage+1][4] ); /*Qx+15 */ + tmpi_I[i] = L_shl( L_tmp, 1 ); + move32(); /*Qx+16 */ + } + } + ELSE IF (HB_stage_id == 1 || HB_stage_id == 3) + { + FOR ( i = 0; i < length; i++ ) + { + + L_tmp = Mult_32_16( tmpi_R[i + 2], Hilbert_coeffs_fx[hb_filter_stage][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmpi_R[i] , Hilbert_coeffs_fx[hb_filter_stage][4] ); /*Qx+15 */ + tmpi_R[i + 4] = L_sub( tmp_R[i], L_shl( L_tmp, 1 ) ); + move32();/*Qx+16 */ + + L_tmp = Mult_32_16( tmpi_I[i + 2], Hilbert_coeffs_fx[hb_filter_stage+1][2] ); /*Qx+15 */ + L_tmp = Madd_32_16( L_tmp, tmpi_I[i] , Hilbert_coeffs_fx[hb_filter_stage+1][4] ); /*Qx+15 */ + tmpi_I[i + 4] = L_sub( tmp_I[i], L_shl( L_tmp, 1 ) ); + move32(); /*Qx+16 */ + } + } +} + /*-------------------------------------------------------------------* * flip_spectrum() * @@ -1208,7 +1398,43 @@ void GenSHBSynth( return; } +#ifdef IVAS_FLOAT_FIXED +void GenSHBSynth_fx_32( + const Word32 *input_synspeech, /* i : input synthesized speech Qx*/ + Word32 *shb_syn_speech_32k, /* o : output highband component Qx*/ + Word32 Hilbert_Mem[], /* i/o: memory Qx*/ + Word32 state_lsyn_filt_shb_local[], /* i/o: memory Qx*/ + const int16_t L_frame, /* i : ACELP frame length */ + int16_t *syn_dm_phase ) +{ + Word32 speech_buf_32k[L_FRAME32k]; + int16_t i; + + Interpolate_allpass_steep_32( input_synspeech, state_lsyn_filt_shb_local, L_FRAME16k, speech_buf_32k ); + + IF( EQ_16( L_frame, L_FRAME ) ) + { + flip_and_downmix_generic_fx_32( speech_buf_32k, shb_syn_speech_32k, L_FRAME32k, Hilbert_Mem, Hilbert_Mem + HILBERT_ORDER1, Hilbert_Mem + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), syn_dm_phase ); + } + ELSE + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + // shb_syn_speech_32k[i] = ( ( i % 2 ) == 0 ) ? ( -speech_buf_32k[i] ) : ( speech_buf_32k[i] ); + IF( EQ_16( i % 2, 0 ) ) + { + shb_syn_speech_32k[i] = -speech_buf_32k[i]; + } + ELSE + { + shb_syn_speech_32k[i] = speech_buf_32k[i]; + } + } + } + return; +} +#endif /*-------------------------------------------------------------------* * ScaleShapedSHB() * @@ -1322,7 +1548,138 @@ void ScaleShapedSHB( return; } +#ifdef IVAS_FLOAT_FIXED +void ScaleShapedSHB_32( + const int16_t length, /* i : SHB overlap length */ + Word32 *synSHB_fx, /* i/o: synthesized shb signal Q_inp/Q_new */ + Word32 *overlap_fx, /* i/o: buffer for overlap-add Q_inp/Q_new */ + const Word16 *subgain_fx, /* i : subframe gain Q15 */ + const Word32 frame_gain_fx, /* i : frame gain Ql*/ + const Word16 *win_fx, /* i : window Q15 */ + const Word16 *subwin_fx, /* i : subframes window Q15 */ + Word16 *Q_inp, + Word16 *Q_new ) +{ + const Word16 *skip; + Word16 i, j, k, l_shb_lahead, l_frame; + Word16 join_length, num_join; + Word32 mod_syn_fx[L_FRAME16k + L_SHB_LAHEAD], L_tmp; + Word16 sum_gain_fx; + + /* initilaization */ + l_frame = L_FRAME16k; + l_shb_lahead = L_SHB_LAHEAD; + skip = skip_bands_SWB_TBE; + + IF( length == SHB_OVERLAP_LEN / 2 ) + { + skip = skip_bands_WB_TBE; + l_frame = L_FRAME16k / 4; + l_shb_lahead = L_SHB_LAHEAD / 4; + } + + /* apply gain for each subframe, and store noise output signal using overlap-add */ + set32_fx( mod_syn_fx, 0, l_frame + l_shb_lahead ); + + IF( length == SHB_OVERLAP_LEN / 2 ) + { + sum_gain_fx = 0; + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain_fx = mult_r( subwin_fx[2 * k + 2], subgain_fx[0] ); + mod_syn_fx[skip[0] + k] = Mpy_32_16_1( synSHB_fx[skip[0] + k], sum_gain_fx ); // Qx + mod_syn_fx[skip[0] + k + length / 2] = Mpy_32_16_1( synSHB_fx[skip[0] + k + length / 2], subgain_fx[0] ); // Qx + } + FOR( i = 1; i < NUM_SHB_SUBFR / 2; i++ ) + { + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[k + 1], subgain_fx[i] ); + sum_gain_fx = round_fx( L_mac0( L_tmp, subwin_fx[length - k - 1], subgain_fx[i - 1] ) ); + mod_syn_fx[skip[i] + k] = L_shl( Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ), 1 ); // Qx + } + } + FOR( k = 0; k < length / 2; k++ ) + { + sum_gain_fx = mult_r( subwin_fx[length - 2 * k - 2], subgain_fx[i - 1] ); + mod_syn_fx[skip[i] + k] = Mpy_32_16_1( synSHB_fx[skip[i] + k], sum_gain_fx ); // Qx + } + } + ELSE + { + num_join = NUM_SHB_SUBFR / NUM_SHB_SUBGAINS; + join_length = i_mult( num_join, length ); + j = 0; + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[k + 1], subgain_fx[0] ) ); // Qx + j++; + } + FOR( i = 0; i < NUM_SHB_SUBGAINS - 1; i++ ) + { + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[i * num_join] ); // Qx + j++; + } + + FOR( k = 0; k < length; k++ ) + { + L_tmp = L_mult0( subwin_fx[length - k - 1], subgain_fx[i * num_join] ); + mod_syn_fx[j] = L_shl( Mpy_32_16_1( synSHB_fx[j], round_fx( L_mac0( L_tmp, subwin_fx[k + 1], subgain_fx[( i + 1 ) * num_join] ) ) ), 1 ); // Qx + j++; + } + } + FOR( k = 0; k < join_length - length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ); // Qx + j++; + } + FOR( k = 0; k < length; k++ ) + { + mod_syn_fx[j] = Mpy_32_16_1( synSHB_fx[j], mult_r( subwin_fx[length - k - 1], subgain_fx[( NUM_SHB_SUBGAINS - 1 ) * num_join] ) ); // Qx + j++; + } + } + + Word16 norm_shift = norm_l( frame_gain_fx ); + IF( frame_gain_fx == 0 ) + { + norm_shift = 31; + } + + norm_shift = sub( norm_shift, 1 ); + *Q_new = add( *Q_inp, sub( norm_shift, 13 ) ); + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + overlap_fx[i] = L_shl( overlap_fx[i], *Q_new - *Q_inp ); + } + + FOR( i = 0; i < l_shb_lahead; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[i] ) ); // Qx + Qn + 18 - 1 - 31 + synSHB_fx[i] = L_add( synSHB_fx[i], overlap_fx[i] ); + synSHB_fx[i + l_shb_lahead] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Qx + Qn + 18 - 1 - 31 + } + + FOR( ; i < l_frame; i++ ) + { + synSHB_fx[i] = Mpy_32_32( mod_syn_fx[i], L_shl( frame_gain_fx, norm_shift ) ); // Qx + Qn + 18 - 1 - 31 + } + + FOR( ; i < l_frame + l_shb_lahead; i++ ) + { + synSHB_fx[i] = L_shl( synSHB_fx[i], *Q_new - *Q_inp ); + overlap_fx[i - l_frame] = Mpy_32_32( mod_syn_fx[i], Mpy_32_16_1( L_shl( frame_gain_fx, norm_shift ), win_fx[l_frame + l_shb_lahead - 1 - i] ) ); // Qx + Qn + 18 - 1 - 31 + } + + *Q_inp = *Q_new; + + return; +} +#endif /*-------------------------------------------------------------------* * non_linearity() * diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index e1c684abd..2093c7941 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -1044,6 +1044,35 @@ Word16 maximum_32_fx( /* o : index of the maximum value in the input ve return ind; } +Word16 maximum_abs_32_fx( /* o : index of the maximum abs value in the input vector */ + const Word32 *vec, /* i : input vector */ + const Word16 lvec, /* i : length of input vector */ + Word32 *max_val /* o : maximum value in the input vector */ +) +{ + Word16 j, ind; + Word32 tmp; + ind = 0; + move16(); + tmp = L_abs(vec[0]); + move16(); + + FOR ( j=1 ; jelement_mode >= IVAS_CPE_DFT ) { +#ifdef IVAS_FLOAT_FIXED + Word32 *hb_synth_0 = (Word32 *) malloc( sizeof( Word32 ) * L_FRAME48k ); + Word32 *hb_synth_1 = (Word32 *) malloc( sizeof( Word32 ) * L_FRAME48k ); + Word32 tmp_buffer_fx[L_FRAME48k]; + Word32 voice_factor_fx[NB_SUBFR16k]; + Word16 q = 16; + floatToFixed_arrL( hb_synth[0], hb_synth_0, q, L_FRAME48k ); + floatToFixed_arrL( hb_synth[1], hb_synth_1, q, L_FRAME48k ); + floatToFixed_arrL( tmp_buffer, tmp_buffer_fx, 16, L_FRAME48k ); + floatToFixed_arrL( voice_factors[0], voice_factor_fx, 16, NB_SUBFR16k ); + if ( hCPE->hStereoDft != NULL ) + { + floatToFixed_arrL( hCPE->hStereoDft->hb_stefi_sig, hCPE->hStereoDft->hb_stefi_sig_fx, q, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); + for ( int lp = 0; lp < 39; lp++ ) + { + hCPE->hStereoDft->side_gain_fx[lp] = (Word32) ( hCPE->hStereoDft->side_gain[lp] * ( 0x7fffffff ) ); + } + hCPE->hStereoDft->td_gain_fx[0] = 1; + } + if ( hCPE->hStereoDftDmx != NULL ) + { + + hCPE->hStereoDftDmx->targetGain_fx = (Word32) ( hCPE->hStereoDftDmx->targetGain * ( 1u << 29 ) ); + } + if ( hCPE->hStereoTCA != NULL ) + { + + hCPE->hStereoTCA->targetGain_fx = (Word32) ( hCPE->hStereoTCA->targetGain * ( 1u << 29 ) ); + } + if ( hCPE->hStereoICBWE != NULL ) + { + floatToFixed_arrL( hCPE->hStereoICBWE->nlExc16k, hCPE->hStereoICBWE->nlExc16k_fx, 18, L_FRAME16k ); + floatToFixed_arrL( hCPE->hStereoICBWE->mixExc16k, hCPE->hStereoICBWE->mixExc16k_fx, 18, L_FRAME16k ); + floatToFixed_arrL( hCPE->hStereoICBWE->lpSHBRef, hCPE->hStereoICBWE->lpSHBRef_fx, 20, LPC_SHB_ORDER + 1 ); + floatToFixed_arr( hCPE->hStereoICBWE->gshapeRef, hCPE->hStereoICBWE->gshapeRef_fx, 15, NUM_SHB_SUBFR ); + hCPE->hStereoICBWE->gFrameRef_fx = (Word32) ( hCPE->hStereoICBWE->gFrameRef * ( 1u << 19 ) ); + } + + stereo_icBWE_dec_fx( hCPE, hb_synth_0, hb_synth_1, tmp_buffer_fx /*fb_synth_ref*/, voice_factor_fx, output_frame, &q ); + + + fixedToFloat_arrL( hb_synth_0, hb_synth[0], q, L_FRAME48k ); + fixedToFloat_arrL( hb_synth_1, hb_synth[1], q, L_FRAME48k ); + + + if ( hCPE->hStereoDft != NULL ) + { + + fixedToFloat_arrL( hCPE->hStereoDft->hb_stefi_sig_fx, hCPE->hStereoDft->hb_stefi_sig, 16, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); + hCPE->hStereoDft->hb_nrg_subr[0] = (float) hCPE->hStereoDft->hb_nrg_subr_fx[0] / ( 1u << hCPE->hStereoDft->Q_nrg_subr ); + hCPE->hStereoDft->hb_nrg_subr[1] = (float) hCPE->hStereoDft->hb_nrg_subr_fx[1] / ( 1u << hCPE->hStereoDft->Q_nrg_subr ); + hCPE->hStereoDft->hb_nrg[0] = (float) hCPE->hStereoDft->hb_nrg_fx[0] / ( 1u << ( hCPE->hStereoDft->Q_nrg_subr + 9 ) ); + + if ( hCPE->hStereoDft->td_gain_fx[0] == 0 ) + { + hCPE->hStereoDft->td_gain[0] = 0; + } + } + + + free( hb_synth_0 ); + free( hb_synth_1 ); +#else stereo_icBWE_dec( hCPE, hb_synth[0], hb_synth[1], tmp_buffer /*fb_synth_ref*/, voice_factors[0], output_frame ); +#endif } if ( st->element_mode == EVS_MONO ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index c6db3a731..f8d4f0ac6 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -136,6 +136,9 @@ typedef struct stereo_dft_dec_data_struct /*Stereo parameters*/ float side_gain[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; +#ifdef IVAS_FLOAT_FIXED + Word32 side_gain_fx[STEREO_DFT_DEC_DFT_NB * STEREO_DFT_BAND_MAX]; +#endif int16_t side_gain_flag_1; int16_t side_gain_flag_2; int16_t side_gain_index_previous[STEREO_DFT_BAND_MAX]; @@ -227,7 +230,15 @@ typedef struct stereo_dft_dec_data_struct float td_gain[STEREO_DFT_CORE_HIST_MAX]; #ifdef IVAS_FLOAT_FIXED Word32 td_gain_fx[STEREO_DFT_CORE_HIST_MAX]; - Word32 hb_stefi_sig_fx[L_FRAME48k + NS2SA(48000, STEREO_DFT_TD_STEFI_DELAY_NS)]; +#endif + +#ifdef IVAS_FLOAT_FIXED + Word32 hb_stefi_sig_fx[L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS )]; + Word32 hb_nrg_fx[STEREO_DFT_CORE_HIST_MAX]; + Word32 hb_nrg_subr_fx[STEREO_DFT_NBDIV]; + + Word16 Q_nrg_subr; + Word16 prev_Q_stefi_sig; #endif /* stereo DTX */ @@ -389,11 +400,11 @@ typedef struct stereo_tca_dec_data_structure int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ int16_t indx_ica_gD; /* ICA target gain */ float targetGain; /* gain norm applied on target (or right) channel in current frame */ + float prevTargetGain; /* gain norm applied on target (or right) channel in previous frame */ #ifdef IVAS_FLOAT_FIXED - Word16 targetGain_fx; // Q14 + Word32 targetGain_fx; // Q29 Word16 prevTargetGain_fx; // Q14 #endif - float prevTargetGain; /* gain norm applied on target (or right) channel in previous frame */ int16_t corrLagStats; /* corr lag stats in current frame */ int16_t prevCorrLagStats; /* corr lag stats in previous frame */ @@ -435,44 +446,69 @@ typedef struct stereo_icbwe_dec_data_structure float mem_syn_shb_nonref[L_SHB_LAHEAD]; float mem_lpc_shbsynth_nonref[LPC_SHB_ORDER]; float mem_syn_shb_ola_nonref[L_SHB_LAHEAD]; - #ifdef IVAS_FLOAT_FIXED - /* unscaled & scaled SHB synthesis memory */ Word32 mem_syn_shb_nonref_fx[L_SHB_LAHEAD]; - Word32 mem_lpc_shbsynth_nonref_fx[LPC_SHB_ORDER]; // Q10 + Word32 mem_lpc_shbsynth_nonref_fx[LPC_SHB_ORDER]; Word32 mem_syn_shb_ola_nonref_fx[L_SHB_LAHEAD]; + + Word16 prev_Q_syn_shb_nonref; + Word16 prev_Q_lpc_shbsynth; + Word16 prev_Q_syn_shb_ola; + #endif + /* inter-channel BWE spectral shape adj. */ float prevSpecMapping; float memShbSpecMapping; + float prevgsMapping; + #ifdef IVAS_FLOAT_FIXED - Word32 prevSpecMapping_fx; - Word32 prevgsMapping_fx; - Word32 memShbSpecMapping_fx; // Q24 + Word16 prevSpecMapping_fx; + Word32 memShbSpecMapping_fx; + Word16 prevgsMapping_fx; + + Word16 prev_Q_memshbspec; #endif - float prevgsMapping; float memShbHilbert_nonref[HILBERT_MEM_SIZE]; float memShbInterp_nonref[2 * ALLPASSSECTIONS_STEEP + 1]; float memShb_fsout_nonref[INTERP_3_2_MEM_LEN]; - int16_t syn_dm_phase_nonref; - #ifdef IVAS_FLOAT_FIXED Word32 memShbHilbert_nonref_fx[HILBERT_MEM_SIZE]; Word32 memShbInterp_nonref_fx[2 * ALLPASSSECTIONS_STEEP + 1]; Word32 memShb_fsout_nonref_fx[INTERP_3_2_MEM_LEN]; - Word32 icbweM2Ref_prev_fx; + + Word16 prev_Q_gen_syn; + Word16 prev_Q_hilb; + Word16 prev_Q_interp; + Word16 prev_Q_fsout; + #endif + int16_t syn_dm_phase_nonref; float icbweM2Ref_prev; - +#ifdef IVAS_FLOAT_FIXED + Word16 icbweM2Ref_prev_fx; +#endif float nlExc16k[L_FRAME16k]; float mixExc16k[L_FRAME16k]; +#ifdef IVAS_FLOAT_FIXED + Word32 nlExc16k_fx[L_FRAME16k]; + Word32 mixExc16k_fx[L_FRAME16k]; +#endif float shbSynthRef[L_FRAME16k]; int16_t MSFlag; float lpSHBRef[LPC_SHB_ORDER + 1]; float gshapeRef[NUM_SHB_SUBFR]; +#ifdef IVAS_FLOAT_FIXED + Word32 lpSHBRef_fx[LPC_SHB_ORDER + 1]; + Word16 gshapeRef_fx[NUM_SHB_SUBFR]; +#endif + float gFrameRef; +#ifdef IVAS_FLOAT_FIXED + Word32 gFrameRef_fx; +#endif } STEREO_ICBWE_DEC_DATA, *STEREO_ICBWE_DEC_HANDLE; diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec.c index 45631f80d..0818d678b 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec.c @@ -370,7 +370,7 @@ void stereo_tca_init_dec_fx( hStereoTCA->indx_ica_NCShift = 0; hStereoTCA->indx_ica_gD = 0; hStereoTCA->targetGain = 1.0f; /* TODO: Remove float init*/ - hStereoTCA->targetGain_fx = ONE_IN_Q14; + hStereoTCA->targetGain_fx = ONE_IN_Q29; hStereoTCA->prevTargetGain_fx = ONE_IN_Q14; hStereoTCA->prevTargetGain = 1.0f; /* TODO: Remove float init*/ diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 6ab45d8a9..5a1f71cf1 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -37,13 +37,15 @@ #include "cnst.h" #include "ivas_cnst.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" -#include "prot_fx2.h" -#include "prot_fx1.h" + + /*-------------------------------------------------------------------* * ic_bwe_dec_reset() @@ -59,63 +61,41 @@ static void ic_bwe_dec_reset( set_f( hStereoICBWE->mem_syn_shb_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ set_f( hStereoICBWE->mem_lpc_shbsynth_nonref, 0, LPC_SHB_ORDER ); set_f( hStereoICBWE->mem_syn_shb_ola_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - - /* inter-channel BWE SP and GSP mem reset */ - hStereoICBWE->memShbSpecMapping = 0; - - set_f( hStereoICBWE->memShbHilbert_nonref, 0, HILBERT_MEM_SIZE ); - set_f( hStereoICBWE->memShbInterp_nonref, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set_f( hStereoICBWE->memShb_fsout_nonref, 0, INTERP_3_2_MEM_LEN ); - hStereoICBWE->syn_dm_phase_nonref = 0; - - return; -} - -/*-------------------------------------------------------------------* - * ic_bwe_dec_reset_fx() - * - * core switching reset of IC BWE memory - *-------------------------------------------------------------------*/ - #ifdef IVAS_FLOAT_FIXED -static void ic_bwe_dec_reset_fx( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ -) -{ - /* unscaled & scaled SHB synthesis memory */ -#if 1 /*TODO: remove the float reset later*/ - set_f( hStereoICBWE->mem_syn_shb_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - set_f( hStereoICBWE->mem_lpc_shbsynth_nonref, 0, LPC_SHB_ORDER ); - set_f( hStereoICBWE->mem_syn_shb_ola_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ -#endif - - /* unscaled & scaled SHB synthesis memory */ - set32_fx( hStereoICBWE->mem_syn_shb_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ // Q9 or Q15 + set32_fx( hStereoICBWE->mem_syn_shb_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); set32_fx( hStereoICBWE->mem_syn_shb_ola_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + hStereoICBWE->prev_Q_lpc_shbsynth = 31; + hStereoICBWE->prev_Q_syn_shb_nonref = 31; + hStereoICBWE->prev_Q_syn_shb_ola = 31; + +#endif /* inter-channel BWE SP and GSP mem reset */ -#if 1 /*TODO: remove float reset later*/ hStereoICBWE->memShbSpecMapping = 0; -#endif +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->memShbSpecMapping_fx = 0; + hStereoICBWE->prev_Q_memshbspec = 31; - hStereoICBWE->memShbSpecMapping_fx = 0; // Q24 : max value 66.61324 +#endif -#if 1 /*TODO: remove float reset later*/ set_f( hStereoICBWE->memShbHilbert_nonref, 0, HILBERT_MEM_SIZE ); set_f( hStereoICBWE->memShbInterp_nonref, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); set_f( hStereoICBWE->memShb_fsout_nonref, 0, INTERP_3_2_MEM_LEN ); -#endif - - hStereoICBWE->syn_dm_phase_nonref = 0; - +#ifdef IVAS_FLOAT_FIXED set32_fx( hStereoICBWE->memShbHilbert_nonref_fx, 0, HILBERT_MEM_SIZE ); set32_fx( hStereoICBWE->memShbInterp_nonref_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); set32_fx( hStereoICBWE->memShb_fsout_nonref_fx, 0, INTERP_3_2_MEM_LEN ); + hStereoICBWE->prev_Q_hilb = 31; + hStereoICBWE->prev_Q_interp = 31; + hStereoICBWE->prev_Q_fsout = 31; +#endif + hStereoICBWE->syn_dm_phase_nonref = 0; + return; } -#endif + /*-------------------------------------------------------------------* * stereo_icBWE_dec() @@ -237,22 +217,13 @@ void stereo_icBWE_dec( /* core switching reset */ if ( st->last_core != ACELP_CORE || st->bwidth == WB ) { -#ifdef IVAS_FLOAT_FIXED - ic_bwe_dec_reset_fx( hStereoICBWE ); -#else ic_bwe_dec_reset( hStereoICBWE ); -#endif if ( st->last_core != ACELP_CORE ) { hStereoICBWE->prevSpecMapping = 0.0f; hStereoICBWE->prevgsMapping = 1.0f; hStereoICBWE->icbweM2Ref_prev = 1.0f; - -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevSpecMapping_fx = 0; - hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; -#endif } if ( st->bwidth == WB ) @@ -265,23 +236,13 @@ void stereo_icBWE_dec( hStereoICBWE->prevSpecMapping = 0.0f; hStereoICBWE->prevgsMapping = 1.0f; hStereoICBWE->icbweM2Ref_prev = 1.0f; - -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevSpecMapping_fx = 0; - hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; -#endif } else if ( st->element_mode == IVAS_CPE_DFT ) { hStereoICBWE->refChanIndx_bwe = L_CH_INDX; hStereoICBWE->prevSpecMapping = 0.0f; - prevgsMapping = hStereoICBWE->prevgsMapping; - -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevSpecMapping_fx = 0; - hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); -#endif + prevgsMapping = hStereoICBWE->prevgsMapping; temp1 = hStereoDft->side_gain[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1]; icbweM2Ref = 1.f + temp1; gsMapping = 1.f - temp1; @@ -302,10 +263,6 @@ void stereo_icBWE_dec( } hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; hStereoICBWE->prevgsMapping = gsMapping; - -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); -#endif } return; @@ -362,11 +319,6 @@ void stereo_icBWE_dec( hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevSpecMapping_fx = float_to_fix( hStereoICBWE->prevSpecMapping, Q31 ); - hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); -#endif - specMapping = hStereoICBWE->prevSpecMapping; gsMapping = hStereoICBWE->prevgsMapping; @@ -412,11 +364,6 @@ void stereo_icBWE_dec( mvr2r( hStereoICBWE->mem_syn_shb_nonref, shb_synth_nonref, L_SHB_LAHEAD ); syn_filt( hStereoICBWE->lpSHBRef, LPC_SHB_ORDER, excSHB_nonref, shb_synth_nonref + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref, 1 ); -#ifdef IVAS_FLOAT_FIXED - Word16 q_mem_lpc_shbsynth_nonref = Q_factor_arr( hStereoICBWE->mem_lpc_shbsynth_nonref, LPC_SHB_ORDER ); - floatToFixed_arrL( hStereoICBWE->mem_lpc_shbsynth_nonref, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, q_mem_lpc_shbsynth_nonref, LPC_SHB_ORDER ); -#endif - prev_pow = sum2_f( shb_synth_nonref, L_SHB_LAHEAD + 10 ); curr_pow = sum2_f( shb_synth_nonref + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 ); @@ -439,27 +386,12 @@ void stereo_icBWE_dec( temp = ( i - 19 ) / 10.0f; shb_synth_nonref[i] *= ( temp * 1.0f + ( 1.0f - temp ) * scale ); } - /* spec and gs adjustment */ deemph( shb_synth_nonref + L_SHB_LAHEAD, specMapping, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping ) ); mvr2r( shb_synth_nonref + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); - // dbgwrite_txt(&(hStereoICBWE->memShbSpecMapping), 1, "shbspecmap.txt", NULL); - -#ifdef IVAS_FLOAT_FIXED - Word16 q_mem_syn_shb_nonref = Q_factor_arr( hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); - floatToFixed_arrL( hStereoICBWE->mem_syn_shb_nonref, hStereoICBWE->mem_syn_shb_nonref_fx, q_mem_syn_shb_nonref, L_SHB_LAHEAD ); // Q10 - hStereoICBWE->memShbSpecMapping_fx = float_to_fix( hStereoICBWE->memShbSpecMapping, Q20 ); // need to check this again -#endif - - ScaleShapedSHB( SHB_OVERLAP_LEN, shb_synth_nonref, hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->gshapeRef, ( hStereoICBWE->gFrameRef * gsMapping * 0.9f ), window_shb, subwin_shb ); -#ifdef IVAS_FLOAT_FIXED - Word16 q_mem_syn_shb_ola_nonref = Q_factor_arr( hStereoICBWE->mem_syn_shb_ola_nonref, L_SHB_LAHEAD ); - floatToFixed_arrL( hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->mem_syn_shb_ola_nonref_fx, q_mem_syn_shb_ola_nonref, L_SHB_LAHEAD ); -#endif - if ( st->extl == FB_TBE ) { v_multc( fb_synth_ref, gsMapping, fb_synth_nonref, L_FRAME48k ); @@ -467,14 +399,6 @@ void stereo_icBWE_dec( /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth( shb_synth_nonref, error, hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbInterp_nonref, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); - -#ifdef IVAS_FLOAT_FIXED - Word16 q_memShbInterp_nonref = Q_factor_arr( hStereoICBWE->memShbInterp_nonref, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - Word16 q_memShbHilbert_nonref = Q_factor_arr( hStereoICBWE->memShbHilbert_nonref, HILBERT_MEM_SIZE ); - - floatToFixed_arrL( hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbHilbert_nonref_fx, q_memShbHilbert_nonref, HILBERT_MEM_SIZE ); - floatToFixed_arrL( hStereoICBWE->memShbInterp_nonref, hStereoICBWE->memShbInterp_nonref_fx, q_memShbInterp_nonref, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); -#endif } else { @@ -517,17 +441,9 @@ void stereo_icBWE_dec( } hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; -#ifdef IVAS_FLOAT_FIXED - ic_bwe_dec_reset_fx( hStereoICBWE ); -#else ic_bwe_dec_reset( hStereoICBWE ); -#endif hStereoICBWE->prevSpecMapping = 0.0f; -#ifdef IVAS_FLOAT_FIXED - hStereoICBWE->prevSpecMapping_fx = 0; -#endif - return; } @@ -545,10 +461,6 @@ void stereo_icBWE_dec( Decimate_allpass_steep( error, hStereoICBWE->memShb_fsout_nonref, L_FRAME32k, synth ); } -#ifdef IVAS_FLOAT_FIXED - Word16 q_memShb_fsout_nonref = Q_factor_arr( hStereoICBWE->memShb_fsout_nonref, INTERP_3_2_MEM_LEN ); - floatToFixed_arrL( hStereoICBWE->memShb_fsout_nonref, hStereoICBWE->memShb_fsout_nonref_fx, q_memShb_fsout_nonref, INTERP_3_2_MEM_LEN ); -#endif if ( st->extl == FB_TBE && st->output_Fs == 48000 ) { @@ -594,6 +506,798 @@ void stereo_icBWE_dec( return; } +#ifdef IVAS_FLOAT_FIXED + +static Word16 FindScale( + Word32 *buff, + Word16 len, + Word16 Q_buff, + Word16 Q_prev ) +{ + Word32 maxVal; + Word16 norm_shift, Q_out; + + maximum_abs_32_fx( buff, len, &maxVal ); + norm_shift = norm_l( maxVal ); + IF( EQ_32( maxVal, 0 ) ) + { + norm_shift = 31; + } + + Q_out = min( Q_prev, add( Q_buff, norm_shift ) ); + + return Q_out; +} + + +void stereo_icBWE_dec_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *synthRef_fx, /* i/o: Reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ + Word32 *synth_fx, /* o : Non reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ + const Word32 *fb_synth_ref_fx, /* i : ref. high-band synthesis 16-20 kHz Qx */ + const Word32 *voice_factors_fx, /* i : voicing factors */ + const Word16 output_frame, /* i : frame length */ + Word16 *Q_syn /* i : Q of synth and synthRef buffers */ +) +{ + int16_t i, j, k, nbSubFr; + Decoder_State *st; /* i/o: decoder state structure, primary channel */ + int16_t spIndx, gsIndx; + Word32 excSHB_nonref_fx[L_FRAME16k]; + Word32 shb_synth_nonref_fx[L_FRAME16k + L_SHB_LAHEAD]; + Word32 error_fx[L_FRAME32k]; + Word32 nlMixFac_fx[NB_SUBFR16k]; + Word16 specMapping_fx; + Word32 fb_synth_nonref_fx[L_FRAME48k]; + Word32 prev_pow_fx, curr_pow_fx, maxVal1, maxVal; + Word16 scale_fx, e_scale_fx; + Word16 alpha_fx, winSlope_fx, winLen_fx; + Word16 prevgsMapping_fx; + Word16 temp1_fx, temp2_fx; + Word16 icbweM2Ref_fx, ratio_L_fx; + Word16 gsMapping_fx; + Word32 hb_nrg_fx, hb_nrg2_fx; + Word16 Q_syn_shb; + Word16 shift_prev_pow, synthRef_shift; + Word32 L_tmp; + Word16 tmp; + + STEREO_DFT_DEC_DATA_HANDLE hStereoDft = hCPE->hStereoDft; + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + st = hCPE->hCoreCoder[0]; + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) && GT_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + hCPE->hStereoDft->core_hist[0] = st->core; + move16(); + + return; + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) ) + { + + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + IF( LE_32( st->core_brate, SID_2k40 ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * TD high band stereo filling * + * -------------------------------------------------------------------*/ + + /* update buffers for TD stereo filling */ + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + hb_nrg_fx = 0; + move32(); + hb_nrg2_fx = 0; + move32(); + maximum_abs_32_fx( synthRef_fx, output_frame, &maxVal ); + synthRef_shift = norm_l( maxVal ); + IF( EQ_32( maxVal, 0 ) ) + { + synthRef_shift = 31; + move16(); + } + synthRef_shift = sub( synthRef_shift, shr( add( find_guarded_bits_fx( output_frame ), 1 ), 1 ) ); + test(); + IF( EQ_16( st->core, ACELP_CORE ) || EQ_16( st->last_core, ACELP_CORE ) ) + { + FOR( i = 0; i < output_frame / 2; i++ ) + { + // needed to be adjusted for q + L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); + hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); // 2*(Qx + SynthRef_shift) - 31 + } + + hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2_fx; + move32(); + hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); + hb_nrg2_fx = 0; + move32(); + + FOR( ; i < output_frame; i++ ) + { + L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); + hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + + hCPE->hStereoDft->hb_nrg_subr_fx[1] = hb_nrg2_fx; // 2*(Qx + SynthRef_shift) - 31 + hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); + + Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + } + ELSE + { + set32_fx( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, 0, output_frame ); + } + hCPE->hStereoDft->hb_nrg_subr_fx[0] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[0], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 // 2 * (Qx + SynthRef_shift) - 31 - 15 + hCPE->hStereoDft->hb_nrg_subr_fx[1] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[1], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 + hCPE->hStereoDft->Q_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); + hCPE->hStereoDft->hb_nrg_fx[0] = hb_nrg_fx; // 2 * (Qx + SynthRef_shift) - 31 + move32(); + hCPE->hStereoDft->td_gain_fx[0] = 0; + move32(); + hCPE->hStereoDft->core_hist[0] = st->core; + move16(); + } + + /*--------------------------------------------------------------------* + * IC-BWE * + * -------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( NE_16( st->core, ACELP_CORE ) || EQ_16( st->extl, -1 ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( hCPE->hCoreCoder[0]->tdm_LRTD_flag, 0 ) ) ) + { + return; + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && LE_32( st->core_brate, SID_2k40 ) ) + { + Copy32( synthRef_fx, synth_fx, output_frame ); + return; + } + + + set32_fx( fb_synth_nonref_fx, 0, L_FRAME48k ); + + /* core switching reset */ + test(); + IF( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->bwidth, (Word16) WB ) ) + { + ic_bwe_dec_reset( hStereoICBWE ); + + IF( NE_16( st->last_core, ACELP_CORE ) ) + { + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + hStereoICBWE->prevgsMapping_fx = 16384; + move16(); + hStereoICBWE->icbweM2Ref_prev_fx = 16384; + move16(); + } + + IF( EQ_16( st->bwidth, WB ) ) + { + /* copy to outputHB and reset hb_synth values */ + Copy32( synthRef_fx, synth_fx, output_frame ); + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + hStereoICBWE->prevgsMapping_fx = 16384; + move16(); + hStereoICBWE->icbweM2Ref_prev_fx = 16384; + move16(); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + move16(); + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + + prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; + move16(); + temp1_fx = shr( extract_h( hStereoDft->side_gain_fx[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1] ), 1 ); + icbweM2Ref_fx = add( 16384, temp1_fx ); + gsMapping_fx = sub( 16384, temp1_fx ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); //(int16_t)((SHB_OVERLAP_LEN * st->output_Fs) / 16000); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); // Q15 + Q14 + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), ( hStereoICBWE->icbweM2Ref_prev_fx ) ); // Q15 + Q14; + tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + L_tmp = L_mult0( alpha_fx, gsMapping_fx ); + L_tmp = L_mac0( L_tmp, ( sub( 32767, alpha_fx ) ), ( prevgsMapping_fx ) ); + tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 + synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); + } + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + hStereoICBWE->prevgsMapping_fx = gsMapping_fx; + move16(); + + *Q_syn = sub( *Q_syn, 1 ); + } + + return; + } + } + + IF( EQ_16( st->bfi, 0 ) ) + { + hStereoICBWE->refChanIndx_bwe = get_next_indice( st, STEREO_ICBWE_REFBITS ); + IF( EQ_16( st->flag_ACELP16k, 1 ) ) + { + spIndx = get_next_indice( st, STEREO_ICBWE_SPBITS ); + } + ELSE + { + spIndx = 3; + } + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS ); + } + ELSE + { + gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS_DFT ); + } + + /* Store indices in case of frame loss */ + hStereoICBWE->prev_spIndx = spIndx; + hStereoICBWE->prev_gsIndx = gsIndx; + } + ELSE /*bfi*/ + { + /* Retrieve last decoded indices */ + spIndx = hStereoICBWE->prev_spIndx; + gsIndx = hStereoICBWE->prev_gsIndx; + hStereoICBWE->refChanIndx_bwe = hStereoICBWE->prev_refChanIndx_bwe; + } + + /* IC-BWE parameter de-quant */ + /* sp Mapping */ + hStereoICBWE->prevSpecMapping_fx = usdequant_fx( spIndx, -19661, 3277 ); // Q15 + + /* gs Mapping */ + prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMapping_tbl_fx[gsIndx]; + } + ELSE + { + hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMappingDFT_tbl_fx[gsIndx]; + } + + // hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); + + specMapping_fx = hStereoICBWE->prevSpecMapping_fx; // Q15 + move16(); + gsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 + move16(); + + test(); + test(); + IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) + { + Copy32( voice_factors_fx, nlMixFac_fx, NB_SUBFR16k ); + IF( hCPE->hStereoDftDmx != NULL ) + { + test(); + IF( LT_32( hCPE->hStereoDftDmx->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoDftDmx->targetGain_fx, 1073741824 ) ) + { + v_multc_fixed_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); + } + } + ELSE + { + test(); + IF( LT_32( hCPE->hStereoTCA->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoTCA->targetGain_fx, 1073741824 ) ) + { + v_multc_fixed_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); + } + } + + // nbSubFr = ( st->flag_ACELP16k == 0 ) ? NB_SUBFR : NB_SUBFR16k; + IF( EQ_16( st->flag_ACELP16k, 0 ) ) + { + nbSubFr = NB_SUBFR; + } + ELSE + { + nbSubFr = NB_SUBFR16k; + } + k = 0; + move16(); + FOR( i = 0; i < nbSubFr; i++ ) + { + IF( EQ_16( hCPE->hCoreCoder[0]->coder_type, UNVOICED ) || EQ_16( hStereoICBWE->MSFlag, 1 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 32767; + move16(); + } + ELSE + { + tmp = 0; + move16(); + temp1_fx = Sqrt16( extract_l( L_shr( nlMixFac_fx[i], 1 ) ), &tmp ); + IF( LT_16( tmp, 0 ) ) + { + temp1_fx = shl( temp1_fx, tmp ); + } + tmp = 0; + move16(); + temp2_fx = Sqrt16( sub( 32767, extract_l( L_shr( nlMixFac_fx[i], 1 ) ) ), &tmp ); + IF( LT_16( tmp, 0 ) ) + { + temp2_fx = shl( temp2_fx, tmp ); + } + } + + FOR( j = 0; j < L_FRAME16k / nbSubFr; j++ ) + { + excSHB_nonref_fx[k] = L_add( Mpy_32_16_1( hStereoICBWE->nlExc16k_fx[k], temp1_fx ), Mpy_32_16_1( hStereoICBWE->mixExc16k_fx[k], temp2_fx ) ); // Q18 + move32(); + k++; + } + } + + /* LP synthesis */ + Q_syn_shb = 31; + move16(); + + Q_syn_shb = FindScale( hStereoICBWE->mem_syn_shb_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_syn_shb_nonref, Q_syn_shb ); + Q_syn_shb = FindScale( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 20, Q_syn_shb ); + Q_syn_shb = FindScale( excSHB_nonref_fx, L_FRAME16k, 18, Q_syn_shb ); + Q_syn_shb = FindScale( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_lpc_shbsynth, Q_syn_shb ); + + Q_syn_shb = sub( Q_syn_shb, 3 ); // gaurded bits + + Scale_sig32( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, sub( Q_syn_shb, 20 ) ); + Scale_sig32( excSHB_nonref_fx, L_FRAME16k, sub( Q_syn_shb, 18 ) ); + Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( Q_syn_shb, hStereoICBWE->prev_Q_lpc_shbsynth ) ); + Scale_sig32( hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD, sub( Q_syn_shb, hStereoICBWE->prev_Q_syn_shb_nonref ) ); + + + Copy32( hStereoICBWE->mem_syn_shb_nonref_fx, shb_synth_nonref_fx, L_SHB_LAHEAD ); + + E_UTIL_synthesis_fx( 0, hStereoICBWE->lpSHBRef_fx, excSHB_nonref_fx, shb_synth_nonref_fx + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); + + hStereoICBWE->prev_Q_lpc_shbsynth = Q_syn_shb; + move16(); + + maximum_abs_32_fx( shb_synth_nonref_fx, L_SHB_LAHEAD + 10 + L_SHB_LAHEAD + 10, &maxVal1 ); // Qsyn_shb + + shift_prev_pow = sub( norm_l( maxVal1 ), find_guarded_bits_fx( L_SHB_LAHEAD + 10 ) ); + + prev_pow_fx = 0; + move32(); + curr_pow_fx = 0; + move32(); + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + L_tmp = L_shl( shb_synth_nonref_fx[i], shift_prev_pow ); + prev_pow_fx = L_add( prev_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + L_tmp = L_shl( shb_synth_nonref_fx[L_SHB_LAHEAD + 10 + i], shift_prev_pow ); + curr_pow_fx = L_add( curr_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + + IF( EQ_32( prev_pow_fx, 0 ) ) + { + e_scale_fx = 0; + move16(); + scale_fx = 0; + move16(); + } + ELSE + { + e_scale_fx = 0; + move16(); + scale_fx = BASOP_Util_Divide3232_Scale( curr_pow_fx, prev_pow_fx, &e_scale_fx ); + scale_fx = Sqrt16( scale_fx, &e_scale_fx ); + } + IF( LT_16( e_scale_fx, 0 ) ) + { + scale_fx = shl( scale_fx, e_scale_fx ); + e_scale_fx = 0; + move16(); + } + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], scale_fx ); + } + tmp = 3276; + move16(); + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + IF( EQ_16( e_scale_fx, 0 ) ) + { + temp1_fx = 32767; + move16(); + } + ELSE + { + temp1_fx = shl( 1, sub( 15, e_scale_fx ) ); + move16(); + } + L_tmp = L_mult0( tmp, temp1_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, tmp ), scale_fx ); + shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], shl( round_fx( L_tmp ), 1 ) ); + IF( LT_16( tmp, 29492 ) ) + { + tmp = add( tmp, 3276 ); + } + } + + /* spec and gs adjustment */ + Q_syn_shb = sub( Q_syn_shb, e_scale_fx ); + Scale_sig32( shb_synth_nonref_fx + L_SHB_LAHEAD + 10, L_FRAME16k - 10, -e_scale_fx ); + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + temp1_fx = norm_l( hStereoICBWE->memShbSpecMapping_fx ); + IF( EQ_32( hStereoICBWE->memShbSpecMapping_fx, 0 ) ) + { + temp1_fx = 31; + move16(); + } + temp1_fx = add( temp1_fx, hStereoICBWE->prev_Q_memshbspec ); + tmp = min( temp1_fx, tmp ); + + tmp = sub( tmp, 9 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); + hStereoICBWE->memShbSpecMapping_fx = L_shl( hStereoICBWE->memShbSpecMapping_fx, tmp - hStereoICBWE->prev_Q_memshbspec ); + + hStereoICBWE->prev_Q_memshbspec = tmp; + move16(); + Q_syn_shb = tmp; + move16(); + + deemph_fx_32( 0, shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); + hStereoICBWE->prev_Q_memshbspec = Q_syn_shb; + move16(); + Copy32( shb_synth_nonref_fx + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD ); + hStereoICBWE->prev_Q_syn_shb_nonref = Q_syn_shb; + move16(); + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, hStereoICBWE->prev_Q_syn_shb_ola, tmp ); + + tmp = sub( tmp, 3 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); + Scale_sig32( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, tmp - hStereoICBWE->prev_Q_syn_shb_ola ); + + + ScaleShapedSHB_32( SHB_OVERLAP_LEN, shb_synth_nonref_fx, hStereoICBWE->mem_syn_shb_ola_nonref_fx, hStereoICBWE->gshapeRef_fx, ( Mpy_32_16_1( hStereoICBWE->gFrameRef_fx, mult_r( gsMapping_fx, 29492 ) ) ), window_shb_fx, subwin_shb_fx, &tmp, &temp1_fx ); + + hStereoICBWE->prev_Q_syn_shb_ola = tmp; + move16(); + Q_syn_shb = tmp; + move16(); + + IF( EQ_16( st->extl, FB_TBE ) ) + { + v_multc_fixed_16( fb_synth_ref_fx, gsMapping_fx, fb_synth_nonref_fx, L_FRAME48k ); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, hStereoICBWE->prev_Q_hilb, tmp ); + tmp = FindScale( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, hStereoICBWE->prev_Q_interp, tmp ); + + tmp = sub( tmp, 3 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, sub( tmp, hStereoICBWE->prev_Q_hilb ) ); + Scale_sig32( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, sub( tmp, hStereoICBWE->prev_Q_interp ) ); + + hStereoICBWE->prev_Q_hilb = tmp; + move16(); + hStereoICBWE->prev_Q_interp = tmp; + move16(); + + Q_syn_shb = tmp; + move16(); + + GenSHBSynth_fx_32( shb_synth_nonref_fx, error_fx, hStereoICBWE->memShbHilbert_nonref_fx, hStereoICBWE->memShbInterp_nonref_fx, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); + } + ELSE + { + Copy32( synthRef_fx, synth_fx, output_frame ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + move16(); + + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + ratio_L_fx = 16384; + move16(); + } + ELSE + { + ratio_L_fx = tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx]; + move16(); + } + + icbweM2Ref_fx = gsMapping_fx; + move16(); + IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) + { + + IF( GE_16( ratio_L_fx, 3276 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + ELSE + { + IF( LE_16( ratio_L_fx, 29490 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( tmp < 4096 ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + + } + } + + icbweM2Ref_fx = max( gsMapping_fx, icbweM2Ref_fx ); + + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + L_tmp = L_mult0( alpha_fx, gsMapping_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), prevgsMapping_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); + } + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + + ic_bwe_dec_reset( hStereoICBWE ); + hStereoICBWE->prevSpecMapping_fx = 0; + + *Q_syn = sub( *Q_syn, 1 ); + + return; + } + + /* resample to output FS */ + + + IF( EQ_32( st->output_Fs, 48000 ) ) + { + tmp = 31; + move16(); + tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); + tmp = sub( tmp, 4 ); + + Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hStereoICBWE->memShb_fsout_nonref_fx ); + hStereoICBWE->prev_Q_fsout = tmp; + move16(); + } + ELSE IF( EQ_32( st->output_Fs, 32000 ) ) + { + Copy32( error_fx, synth_fx, L_FRAME32k ); + } + ELSE IF( EQ_32( st->output_Fs, 16000 ) ) + { + tmp = 31; + move16(); + tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); + tmp = sub( tmp, 4 ); + + Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); + Decimate_allpass_steep_fx32( error_fx, hStereoICBWE->memShb_fsout_nonref_fx, L_FRAME32k, synth_fx ); + hStereoICBWE->prev_Q_fsout = tmp; + move16(); + } + + Scale_sig32( synth_fx, L_FRAME48k, sub( *Q_syn, add( 1, tmp ) ) ); + + *Q_syn = sub( *Q_syn, 1 ); + + test(); + IF( EQ_16( st->extl, FB_TBE ) && EQ_32( st->output_Fs, 48000 ) ) + { + v_add_fixed( fb_synth_nonref_fx, synth_fx, synth_fx, L_FRAME48k, 0 ); + } + + /* copy to outputHB and reset hb_synth values */ + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + ratio_L_fx = 16384; + move16(); + } + ELSE + { + ratio_L_fx = tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx]; + move16(); + } + + icbweM2Ref_fx = gsMapping_fx; + move16(); + IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) + { + IF( GE_16( ratio_L_fx, 3276 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp1_fx, sub( temp2_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + ELSE + { + IF( LE_16( ratio_L_fx, 29490 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + + } + } + + icbweM2Ref_fx = max( gsMapping_fx, icbweM2Ref_fx ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + move16(); + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + } + + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + + return; +} +#endif /*-------------------------------------------------------------------* * stereo_icBWE_decproc() @@ -1265,17 +1969,21 @@ void stereo_icBWE_init_dec( hStereoICBWE->prevSpecMapping = 0; hStereoICBWE->prevgsMapping = 1.0f; +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->prevgsMapping_fx = 16384; +#endif + hStereoICBWE->icbweM2Ref_prev = 1.0f; +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->icbweM2Ref_prev_fx = 16384; +#endif + hStereoICBWE->prev_spIndx = 0; hStereoICBWE->prev_gsIndx = 0; -#ifdef IVAS_FLOAT_FIXED - ic_bwe_dec_reset_fx( hStereoICBWE ); -#else ic_bwe_dec_reset( hStereoICBWE ); -#endif - return; } @@ -1314,13 +2022,13 @@ void stereo_icBWE_init_dec_fx( #endif hStereoICBWE->prevSpecMapping_fx = 0; - hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; - hStereoICBWE->icbweM2Ref_prev_fx = ONE_IN_Q30; + hStereoICBWE->prevgsMapping_fx = 16384; + hStereoICBWE->icbweM2Ref_prev_fx = 16384; hStereoICBWE->prev_spIndx = 0; hStereoICBWE->prev_gsIndx = 0; - ic_bwe_dec_reset_fx( hStereoICBWE ); + ic_bwe_dec_reset( hStereoICBWE ); return; } -- GitLab