From 6053fc6948c5836a890069d2c5cb5a8f8169d67b Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 9 Jan 2024 18:12:52 +0530 Subject: [PATCH] stereo_dft_dec_core_switching module converted to fixed [x] stereo_dft_dec_core_switching module and few related sub functions updated for fixed point. --- lib_com/fft_fx.c | 131 +++++ lib_com/ivas_prot.h | 3 + lib_com/ivas_prot_fx.h | 33 ++ lib_com/ivas_rom_com_fx.c | 51 ++ lib_com/ivas_rom_com_fx.h | 3 + lib_com/lerp.c | 131 +++++ lib_com/prot_fx2.h | 43 +- lib_com/tools_fx.c | 19 +- lib_dec/core_dec_init.c | 8 + lib_dec/dec_acelp_tcx_main.c | 8 + lib_dec/ivas_core_dec.c | 116 +++++ lib_dec/ivas_cpe_dec.c | 38 ++ lib_dec/ivas_post_proc.c | 442 ++++++++++++++++- lib_dec/ivas_rom_dec.c | 95 ++++ lib_dec/ivas_rom_dec.h | 13 + lib_dec/ivas_sba_dirac_stereo_dec.c | 116 +++++ lib_dec/ivas_stat_dec.h | 41 ++ lib_dec/ivas_stereo_dft_dec.c | 723 ++++++++++++++++++++++++++++ lib_dec/ivas_stereo_esf_dec.c | 88 ++++ lib_dec/ivas_tcx_core_dec.c | 6 + lib_dec/stat_dec.h | 8 + 21 files changed, 2110 insertions(+), 6 deletions(-) diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c index 55611f0b1..f07807794 100644 --- a/lib_com/fft_fx.c +++ b/lib_com/fft_fx.c @@ -5325,6 +5325,137 @@ void fft_fx( return; } +void rfft_fx( + Word32 *x, /* i/o: values */ + const Word16 *w, /* i : window */ + const Word16 length, /* i : length of fft */ + const Word16 isign /* i : sign */ +) +{ + Word16 i, sizeOfFft2, sizeOfFft4; + Word32 tmp, t1, t2, t3, t4; + Word16 s1, s2; + + sizeOfFft2 = length >> 1; + sizeOfFft4 = length >> 2; + SWITCH( sizeOfFft2 ) + { + case 80: + s1 = 409; + s2 = -409; + BREAK; + case 128: + s1 = 256; + s2 = -256; + BREAK; + case 160: + s1 = 204; + s2 = -204; + BREAK; + case 320: + s1 = 102; + s2 = -102; + BREAK; + case 480: + s1 = 68; + s2 = -68; + BREAK; + default: + s1 = -1; + s2 = -1; + printf( "Configuration not supported" ); + assert( 0 ); + } + + SWITCH ( isign ) + { + + case -1: + + fft_fx( x, x + 1, sizeOfFft2, 2 ); + + tmp = L_add(x[0], x[1]); + x[1] = L_sub(x[0], x[1]); + x[0] = tmp; + + FOR ( i = 1; i <= sizeOfFft4; i++ ) + { + t1 = L_sub(x[2 * i], x[length - 2 * i]); + t2 = L_add(x[2 * i + 1], x[length - 2 * i + 1]); + t3 = L_sub(Mpy_32_16_1(t1, w[i]), Mpy_32_16_1(t2, w[i + sizeOfFft4])); + t4 = L_add(Mpy_32_16_1(t1, w[i + sizeOfFft4]), Mpy_32_16_1(t2, w[i])); + t1 = L_add(x[2 * i], x[length - 2 * i]); + t2 = L_sub(x[2 * i + 1], x[length - 2 * i + 1]); + + x[2 * i] = Mpy_32_16_1(L_sub(t1, t3), 16384); + x[2 * i + 1] = Mpy_32_16_1(L_sub(t2, t4), 16384); + x[length - 2 * i] = Mpy_32_16_1(L_add(t1, t3), 16384); + x[length - 2 * i + 1] = Mpy_32_16_1(L_negate(L_add(t2, t4)), 16384); + } + + BREAK; + + case +1: + + tmp = Mpy_32_16_1( L_add( x[0], x[1] ), 16384); + x[1] = Mpy_32_16_1( L_sub( x[1], x[0] ), 16384); + x[0] = tmp; + + FOR ( i = 1; i <= sizeOfFft4; i++ ) + { + t1 = L_sub(x[2 * i], x[length - 2 * i]); + t2 = L_add(x[2 * i + 1], x[length - 2 * i + 1]); + t3 = L_add(Mpy_32_16_1(t1, w[i]), Mpy_32_16_1(t2, w[i + sizeOfFft4])); + t4 = L_sub(Mpy_32_16_1(t2, w[i]), Mpy_32_16_1(t1, w[i + sizeOfFft4])); + t1 = L_add(x[2 * i], x[length - 2 * i]); + t2 = L_sub(x[2 * i + 1], x[length - 2 * i + 1]); + + x[2 * i] = Mpy_32_16_1(L_sub( t1, t3 ), 16384); + x[2 * i + 1] = Mpy_32_16_1( L_sub( t4, t2 ), 16384); + x[length - 2 * i] = Mpy_32_16_1(L_add( t1, t3 ), 16384); + x[length - 2 * i + 1] = Mpy_32_16_1(L_add( t2, t4 ), 16384); + } + + fft_fx( x, x + 1, sizeOfFft2, 2 ); + + FOR ( i = 0; i < length; i += 2 ) + { + x[i] = Mpy_32_16_1(x[i], s1); + x[i + 1] = Mpy_32_16_1(x[i+1], s2); + } + + BREAK; + } + + return; +} + +Word16 find_guarded_bits_fx( Word32 n ) +{ + return n <= 1 ? 0 : n <= 2 ? 1 + : n <= 4 ? 2 + : n <= 8 ? 3 + : n <= 16 ? 4 + : n <= 32 ? 5 + : n <= 64 ? 6 + : n <= 128 ? 7 + : n <= 256 ? 8 + : n <= 512 ? 9 + : n <= 1024 ? 10 + : 11; +} + +Word16 L_norm_arr( Word32 *arr, Word16 size ) +{ + Word16 q = 31; + FOR( int i = 0; i < size; i++ ) + if ( arr[i] != 0 ) + { + q = s_min( q, norm_l( arr[i] ) ); + } + return q; +} + #if 0 /* Functions are already in fixed point and available in fft.c file */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3d72e00d6..4ffd9190a 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1484,6 +1484,9 @@ void stereo_dft_dec_core_switching( void init_basic_allpass( basic_allpass_t *ap, /* i/o: basic allpass structure */ const float *gains, /* i : allpass filter gains */ +#ifdef IVAS_FLOAT_FIXED + const Word32 *gains_fx, +#endif const int16_t *delays /* i : allpass filter delays */ ); diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 737bb9470..97c0a37dc 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -234,4 +234,37 @@ void IGFDecReplicateTCX10State_fx( IGF_DEC_INSTANCE_HANDLE hIGFDec /* i/o: instance handle of IGF Decoder */ ); +void stereo_dft_dec_analyze_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 *input_fx, /* i : input signal */ + Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const Word16 chan, /* i : channel number */ + const Word16 input_frame, /* i : input frame size */ + const Word16 output_frame, /* i : output frame size */ + const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : signal type to analyze */ + const Word16 k_offset, /* i : offset of DFT */ + const Word16 delay, /* i : delay in samples for input signal */ + Word16 *q, + Word16 *q_out_DFT +); + +void filter_with_allpass_fx( + const Word32 *sig, /* i : allpass input signal */ + Word32 *out, /* o : filtered output */ + const int16_t len, /* i : length of input */ + basic_allpass_t *ap /* i/o: basic allpass structure */ +); + +void stereo_dft_dec_core_switching_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 output_fx[], /* i/o: synthesis @internal Fs */ + Word32 synth_fx[], /* i/o: synthesis @output Fs */ + Word32 hb_synth_fx[], /* i/o: hb synthesis */ + Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const Word16 output_frame, /* i : output frame length */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB FOR DFT Stereo */ + const Word16 sba_dirac_stereo_dtx_flag, /* i : DTX indicator FOR SBA DirAC stereo */ + Word16 *q, + Word16 *q_DFT ); + #endif \ No newline at end of file diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index d5da101f3..ab7cf3aec 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -195,5 +195,56 @@ const Word16 ivas_cos_twiddle_80_fx[ IVAS_80_PT_LEN >> 1 ] = { SHC( 0x26f4 ), SHC( 0x2223 ), SHC( 0x1d45 ), SHC( 0x185a ), SHC( 0x1367 ), SHC( 0x0e6b ), SHC( 0x096a ), SHC( 0x0465 ), }; +const Word16 dft_trigo_12k8_fx[STEREO_DFT_N_12k8_ENC / 4 + 1] = +{ + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, 9512, 9896, 10278, 10659, + 11039, 11416, 11793, 12167, 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, 18204, 18537, 18868, + 19195, 19519, 19841, 20159, 20475, 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, 25330, 25583, + 25832, 26077, 26319, 26557, 26790, 27020, 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, 30273, + 30425, 30572, 30714, 30852, 30985, 31114, 31237, 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, 32767 +}; + +const Word16 dft_trigo_32k_fx[STEREO_DFT_N_32k_ENC / 4 + 1] = +{ + 0, 160, 321, 482, 643, 804, 964, 1125, 1286, 1447, 1607, 1768, 1929, 2089, 2250, 2410, 2570, 2731, 2891, 3051, 3211, 3371, 3531, 3691, 3851, 4011, 4170, 4330, 4489, + 4648, 4808, 4967, 5126, 5284, 5443, 5602, 5760, 5918, 6076, 6234, 6392, 6550, 6707, 6865, 7022, 7179, 7336, 7493, 7649, 7805, 7961, 8117, 8273, 8429, 8584, 8739, + 8894, 9049, 9203, 9358, 9512, 9665, 9819, 9972, 10125, 10278, 10431, 10583, 10735, 10887, 11039, 11190, 11341, 11492, 11642, 11793, 11942, 12092, 12241, 12391, + 12539, 12688, 12836, 12984, 13131, 13278, 13425, 13572, 13718, 13864, 14010, 14155, 14300, 14444, 14589, 14732, 14876, 15019, 15162, 15304, 15446, 15588, 15729, + 15870, 16011, 16151, 16291, 16430, 16569, 16707, 16846, 16983, 17121, 17258, 17394, 17530, 17666, 17801, 17936, 18070, 18204, 18338, 18471, 18604, 18736, 18868, + 18999, 19130, 19260, 19390, 19519, 19648, 19777, 19905, 20032, 20159, 20286, 20412, 20538, 20663, 20787, 20911, 21035, 21158, 21281, 21403, 21524, 21645, 21766, + 21886, 22005, 22124, 22242, 22360, 22478, 22594, 22711, 22826, 22941, 23056, 23170, 23283, 23396, 23509, 23620, 23732, 23842, 23952, 24062, 24171, 24279, 24387, + 24494, 24600, 24706, 24812, 24916, 25021, 25124, 25227, 25330, 25431, 25532, 25633, 25733, 25832, 25931, 26029, 26126, 26223, 26319, 26415, 26509, 26604, 26697, + 26790, 26882, 26974, 27065, 27155, 27245, 27334, 27423, 27510, 27597, 27684, 27769, 27854, 27939, 28023, 28106, 28188, 28270, 28351, 28431, 28511, 28589, 28668, + 28745, 28822, 28898, 28974, 29049, 29123, 29196, 29269, 29341, 29412, 29482, 29552, 29621, 29690, 29758, 29825, 29891, 29956, 30021, 30085, 30149, 30211, 30273, + 30334, 30395, 30455, 30514, 30572, 30629, 30686, 30742, 30797, 30852, 30906, 30959, 31011, 31063, 31114, 31164, 31213, 31262, 31309, 31357, 31403, 31448, 31493, + 31537, 31581, 31623, 31665, 31706, 31746, 31785, 31824, 31862, 31899, 31936, 31971, 32006, 32040, 32074, 32106, 32138, 32169, 32199, 32229, 32257, 32285, 32312, + 32339, 32364, 32389, 32413, 32436, 32458, 32480, 32501, 32521, 32540, 32559, 32577, 32594, 32610, 32625, 32640, 32653, 32666, 32679, 32690, 32701, 32711, 32720, + 32728, 32736, 32742, 32748, 32753, 32758, 32761, 32764, 32766, 32767, 32767 +}; +const Word16 dft_trigo_48k_fx[STEREO_DFT_N_MAX_ENC / 4 + 1] = +{ + 0, 107, 214, 321, 428, 536, 643, 750, 857, 964, 1072, 1179, 1286, 1393, 1500, 1607, 1714, 1822, 1929, 2036, 2143, 2250, 2357, 2464, 2570, 2677, 2784, 2891, 2998, + 3105, 3211, 3318, 3425, 3531, 3638, 3744, 3851, 3957, 4064, 4170, 4277, 4383, 4489, 4595, 4701, 4808, 4914, 5020, 5126, 5231, 5337, 5443, 5549, 5654, 5760, 5866, + 5971, 6076, 6182, 6287, 6392, 6497, 6602, 6707, 6812, 6917, 7022, 7127, 7231, 7336, 7440, 7545, 7649, 7753, 7857, 7961, 8065, 8169, 8273, 8377, 8480, 8584, 8687, + 8791, 8894, 8997, 9100, 9203, 9306, 9409, 9512, 9614, 9717, 9819, 9921, 10023, 10125, 10227, 10329, 10431, 10532, 10634, 10735, 10837, 10938, 11039, 11140, 11240, + 11341, 11442, 11542, 11642, 11742, 11843, 11942, 12042, 12142, 12241, 12341, 12440, 12539, 12638, 12737, 12836, 12934, 13033, 13131, 13229, 13327, 13425, 13523, + 13621, 13718, 13815, 13913, 14010, 14106, 14203, 14300, 14396, 14492, 14589, 14684, 14780, 14876, 14971, 15067, 15162, 15257, 15352, 15446, 15541, 15635, 15729, + 15823, 15917, 16011, 16104, 16197, 16291, 16384, 16476, 16569, 16661, 16754, 16846, 16938, 17029, 17121, 17212, 17303, 17394, 17485, 17576, 17666, 17756, 17846, + 17936, 18026, 18115, 18204, 18293, 18382, 18471, 18559, 18648, 18736, 18824, 18911, 18999, 19086, 19173, 19260, 19347, 19433, 19519, 19605, 19691, 19777, 19862, + 19947, 20032, 20117, 20202, 20286, 20370, 20454, 20538, 20621, 20704, 20787, 20870, 20953, 21035, 21117, 21199, 21281, 21362, 21443, 21524, 21605, 21685, 21766, + 21846, 21926, 22005, 22084, 22164, 22242, 22321, 22399, 22478, 22556, 22633, 22711, 22788, 22865, 22941, 23018, 23094, 23170, 23246, 23321, 23396, 23471, 23546, + 23620, 23695, 23769, 23842, 23916, 23989, 24062, 24134, 24207, 24279, 24351, 24422, 24494, 24565, 24636, 24706, 24777, 24847, 24916, 24986, 25055, 25124, 25193, + 25261, 25330, 25397, 25465, 25532, 25599, 25666, 25733, 25799, 25865, 25931, 25996, 26061, 26126, 26191, 26255, 26319, 26383, 26446, 26509, 26572, 26635, 26697, + 26759, 26821, 26882, 26944, 27004, 27065, 27125, 27185, 27245, 27305, 27364, 27423, 27481, 27539, 27597, 27655, 27712, 27769, 27826, 27883, 27939, 27995, 28050, + 28106, 28161, 28215, 28270, 28324, 28377, 28431, 28484, 28537, 28589, 28642, 28694, 28745, 28797, 28848, 28898, 28949, 28999, 29049, 29098, 29147, 29196, 29245, + 29293, 29341, 29388, 29435, 29482, 29529, 29575, 29621, 29667, 29712, 29758, 29802, 29847, 29891, 29935, 29978, 30021, 30064, 30106, 30149, 30190, 30232, 30273, + 30314, 30355, 30395, 30435, 30474, 30514, 30552, 30591, 30629, 30667, 30705, 30742, 30779, 30816, 30852, 30888, 30924, 30959, 30994, 31029, 31063, 31097, 31130, + 31164, 31197, 31229, 31262, 31294, 31325, 31357, 31387, 31418, 31448, 31478, 31508, 31537, 31566, 31595, 31623, 31651, 31679, 31706, 31733, 31759, 31785, 31811, + 31837, 31862, 31887, 31912, 31936, 31960, 31983, 32006, 32029, 32051, 32074, 32095, 32117, 32138, 32159, 32179, 32199, 32219, 32238, 32257, 32276, 32294, 32312, + 32330, 32347, 32364, 32381, 32397, 32413, 32428, 32444, 32458, 32473, 32487, 32501, 32514, 32528, 32540, 32553, 32565, 32577, 32588, 32599, 32610, 32620, 32630, + 32640, 32649, 32658, 32666, 32675, 32683, 32690, 32697, 32704, 32711, 32717, 32723, 32728, 32733, 32738, 32742, 32746, 32750, 32753, 32756, 32759, 32761, 32763, + 32765, 32766, 32767, 32767, 32767 +}; /* clang-format on */ diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index b696c2c57..1a78371ed 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -48,5 +48,8 @@ extern const Word16 ivas_sin_twiddle_160_fx[ IVAS_160_PT_LEN >> 1 ]; extern const Word16 ivas_cos_twiddle_160_fx[ IVAS_160_PT_LEN >> 1 ]; extern const Word16 ivas_sin_twiddle_80_fx[ IVAS_80_PT_LEN >> 1 ]; extern const Word16 ivas_cos_twiddle_80_fx[ IVAS_80_PT_LEN >> 1 ]; +extern const Word16 dft_trigo_12k8_fx[STEREO_DFT_N_12k8_ENC / 4 + 1]; +extern const Word16 dft_trigo_32k_fx[STEREO_DFT_N_32k_ENC / 4 + 1]; +extern const Word16 dft_trigo_48k_fx[STEREO_DFT_N_MAX_ENC / 4 + 1]; #endif \ No newline at end of file diff --git a/lib_com/lerp.c b/lib_com/lerp.c index 832217dc6..fcb42345c 100644 --- a/lib_com/lerp.c +++ b/lib_com/lerp.c @@ -382,3 +382,134 @@ static void lerp_proc(Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 buf } } + +#ifdef IVAS_FLOAT_FIXED + +static void L_lerp_proc_fx( const Word32 *f_fx, Word32 *f_out_fx, const Word16 bufferNewSize, const Word16 bufferOldSize ); + +/*-------------------------------------------------------------* + * procedure lerp() * + * * + * * + *-------------------------------------------------------------*/ +void L_lerp_fx( Word32 *f, Word32 *f_out, Word16 bufferNewSize, Word16 bufferOldSize ) +{ + Word16 tmpNewSize; + + IF ( 128 * bufferNewSize > bufferOldSize * 507 ) + { + tmpNewSize = bufferOldSize * 2; + WHILE ( bufferNewSize > bufferOldSize ) + { + IF ( 128 * bufferNewSize <= 507 * bufferOldSize ) + { + tmpNewSize = bufferNewSize; + } + + L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize ); + + f = f_out; + bufferOldSize = tmpNewSize; + tmpNewSize *= 2; + } + } + ELSE IF ( 128 * bufferOldSize > bufferNewSize * 507 ) + { + tmpNewSize = bufferOldSize / 2; + WHILE ( bufferNewSize < bufferOldSize ) + { + IF ( 128 * bufferOldSize <= 507 * bufferNewSize ) + { + tmpNewSize = bufferNewSize; + } + + L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize ); + + f = f_out; + bufferOldSize = tmpNewSize; + tmpNewSize /= 2; + } + } + ELSE + { + L_lerp_proc_fx( f, f_out, bufferNewSize, bufferOldSize ); + } + + return; +} + +/*-------------------------------------------------------------* + * procedure lerp_proc() * + * * + * * + *-------------------------------------------------------------*/ +static void L_lerp_proc_fx( + const Word32 *f_fx, + Word32 *f_out_fx, + const Word16 bufferNewSize, + const Word16 bufferOldSize +) +{ + Word16 i, idx; + Word32 pos_fx, shift_fx, diff_fx; + Word32 buf_fx[2 * L_FRAME_MAX]; + Word16 tmp; + + IF ( bufferNewSize == bufferOldSize ) + { + Copy32( f_fx, buf_fx, bufferNewSize ); + Copy32( buf_fx, f_out_fx, bufferNewSize ); + return; + } + + /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */ + tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) ); + shift_fx = L_shl( L_deposit_l( tmp ), 4 - 15 + 21 ); // q =21 + pos_fx = Mpy_32_32( L_sub( shift_fx, 1 << 21 ), 1073741824 ); + + IF ( shift_fx < L_shr( 644245094, 31 - 21 ) ) + { + pos_fx = L_sub( pos_fx, L_shr( 279172874, 31 - 21 ) ); + } + + /* first point of interpolation */ + IF ( pos_fx < 0 ) + { + buf_fx[0] = L_add( f_fx[0], L_shl( Mpy_32_32( pos_fx, L_sub( f_fx[1], f_fx[0] ) ), 31 - 21 ) ); + } + ELSE + { + idx = (Word16) L_shr( pos_fx, 21 ); + diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) ); + buf_fx[0] = L_add( f_fx[idx], L_shl( Mpy_32_32( diff_fx, L_sub( f_fx[idx + 1], f_fx[idx] ) ), 31 - 21 ) ); + } + + pos_fx = L_add( pos_fx, shift_fx ); + + FOR ( i = 1; i < bufferNewSize - 1; i++ ) + { + idx = (Word16) L_shr( pos_fx, 21 ); + diff_fx = pos_fx - L_shl( idx, 21 ); + + buf_fx[i] = L_add( f_fx[idx], L_shl( Mpy_32_32( diff_fx, L_sub( f_fx[idx + 1], f_fx[idx] ) ), 31 - 21 ) ); + pos_fx = L_add( pos_fx, shift_fx ); + } + + + /* last point */ + idx = (Word16) L_shr( pos_fx, 21 ); + + IF ( pos_fx > L_shl( bufferOldSize - 1, 21 ) ) + { + idx = bufferOldSize - 2; + } + + diff_fx = pos_fx - L_shl( idx, 21 ); + + buf_fx[bufferNewSize - 1] = L_add( f_fx[idx], L_shl( Mpy_32_32( diff_fx, L_sub( f_fx[idx + 1], f_fx[idx] ) ), 31 - 21 ) ); + + Copy32( buf_fx, f_out_fx, bufferNewSize ); + + return; +} +#endif \ No newline at end of file diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 38c560f78..5a3731b90 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -2026,6 +2026,7 @@ void synth_mem_updt2( //lerp.c void lerp(Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize); +void L_lerp_fx( Word32 *f, Word32 *f_out, Word16 bufferNewSize, Word16 bufferOldSize ); //index_pvq_opt.c @@ -3776,6 +3777,17 @@ void fft_fx( const Word16 s /* i : sign */ ); +void rfft_fx( + Word32 *x, /* i/o: values */ + const Word16 *w, /* i : window */ + const Word16 length, /* i : length of fft */ + const Word16 isign /* i : sign */ +); + +Word16 find_guarded_bits_fx(Word32 n); + +Word16 L_norm_arr(Word32* arr, Word16 size); + void edct2_fx_ivas( const Word16 n, const Word16 isgn, @@ -7728,12 +7740,37 @@ void fft_cldfb_fx( const Word16 size /* size of fft operation */ ); -#ifdef IVAS_FLOAT_FIXED +void stereo_dft_dec_analyze_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 *input_fx, /* i : input signal */ + Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const int16_t chan, /* i : channel number */ + const int16_t input_frame, /* i : input frame size */ + const int16_t output_frame, /* i : output frame size */ + const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : type of signal to analyse */ + const int16_t k_offset, /* i : offset of DFT */ + const int16_t delay, /* i : delay in samples for input signal */ + Word16 *q, + Word16 *q_DFT +); + +void set32_fx( + Word32 y[], /* i/o: Vector to set */ + const Word32 a, /* i : Value to set the vector to */ + const Word16 N /* i : Lenght of the vector */ +); + void delay_signal_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ Word32 mem[], /* i/o: synchronization memory */ const Word16 delay /* i : delay in samples */ ); -#endif -#endif + +void v_add_fx( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */ + const int16_t N /* i : Vector length */ +); +#endif \ No newline at end of file diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index ad1869f4f..a75d9d78e 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -3070,7 +3070,6 @@ void delay_signal( return; } -#ifdef IVAS_FLOAT_FIXED void delay_signal_fx( Word32 x[], /* i/o: signal to be delayed */ const Word16 len, /* i : length of the input signal */ @@ -3088,4 +3087,20 @@ void delay_signal_fx( return; } -#endif \ No newline at end of file + +void v_add_fx( + const Word32 x1[], /* i : Input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 + vector 2 */ + const int16_t N /* i : Vector length */ +) +{ + int16_t i; + + for ( i = 0; i < N; i++ ) + { + y[i] = L_add_sat(x1[i], x2[i]); + } + + return; +} diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index 150048573..ade189e09 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -612,10 +612,18 @@ void open_decoder_LPD_flt( if (st->tcxonly) { st->p_bpf_noise_buf_float = NULL; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = NULL; +#endif + } else { st->p_bpf_noise_buf_float = st->bpf_noise_buf_float; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = st->bpf_noise_buf_32; +#endif + } if (bwidth == SWB && (total_brate == ACELP_16k40 || total_brate == ACELP_24k40) && st->element_mode == EVS_MONO) diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index 809c64aed..aa1e7e286 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -252,10 +252,18 @@ static void decode_frame_type_flt( if ( st->tcxonly ) { st->p_bpf_noise_buf_float = NULL; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = NULL; +#endif + } else { st->p_bpf_noise_buf_float = st->bpf_noise_buf_float; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = st->bpf_noise_buf_32; +#endif + } } } diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index e1a5b2a33..747dc755c 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -38,6 +38,7 @@ #include "rom_com.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -697,8 +698,123 @@ ivas_error ivas_core_dec( { stereo_mdct2dft_update( hCPE, output[0], synth[0] ); } +#ifdef IVAS_FLOAT_FIXED + Word16 q = 11, q_DFT[2] = { 3, 3 }; + Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; + Word32 synth_fx[L_FRAME48k]; + Word32 hb_synth_fx[L_FRAME48k]; + Word32 output_fx[960]; + FOR( int ind = 0; ind < 960; ind++ ) + { + output_fx[ind] = (Word32) ( output[0][ind] * ( 1 << q ) ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int ind = 0; ind < L_FRAME32k; ind++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx[ind] = (Word32) ( hCPE->hCoreCoder[0]->hHQ_core->old_outLB[ind] * ( 1 << q ) ); + } + IF( (hCPE->hCoreCoder[0] != NULL) && (hCPE->hCoreCoder[0]->p_bpf_noise_buf_32 != NULL) ) + FOR( int ind = 0; ind < L_FRAME16k; ind++ ) + { + hCPE->hCoreCoder[0]->p_bpf_noise_buf_32[ind] = (Word32) ( hCPE->hCoreCoder[0]->p_bpf_noise_buf_float[ind] * ( 1 << q ) ); + } + IF( DFT != NULL ) + FOR( int ind = 0; ind < CPE_CHANNELS; ind++ ) + { + FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + { + DFT_fx[ind][j] = (Word32) ( DFT[ind][j] * ( 1 << q_DFT[ind] ) ); + } + } + FOR( int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++ ) + hCPE->input_mem_BPF_fx[0][ind] = (Word32) ( hCPE->input_mem_BPF[0][ind] * ( 1 << q ) ); + FOR( int ind = 0; ind < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); ind++ ) + hCPE->input_mem_fx[0][ind] = (Word32) ( hCPE->input_mem[0][ind] * ( 1 << q ) ); + FOR( int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++ ) + hCPE->input_mem_LB_fx[0][ind] = (Word32) ( hCPE->input_mem_LB[0][ind] * ( 1 << q ) ); + FOR( int ind = 0; ind < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); ind++ ) + hCPE->input_mem_fx[1][ind] = (Word32) ( hCPE->input_mem[1][ind] * ( 1 << q ) ); + FOR( int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++ ) + hCPE->input_mem_LB_fx[1][ind] = (Word32) ( hCPE->input_mem_LB[1][ind] * ( 1 << q ) ); + IF( hCPE->hStereoDft != NULL ) + FOR( int ind = 0; ind < NS2SA( 16000, DELAY_BWE_TOTAL_NS ); ind++ ) + { + hCPE->hStereoDft->ap_delay_mem_fx[ind] = (Word32) ( hCPE->hStereoDft->ap_delay_mem[ind] * ( 1 << q ) ); + } + FOR( int ind = 0; ind < hCPE->hCoreCoder[0]->output_Fs / FRAMES_PER_SEC; ind++ ) + { + synth_fx[ind] = (Word32) ( synth[0][ind] * ( 1 << q ) ); + hb_synth_fx[ind] = (Word32) ( hb_synth[0][ind] * ( 1 << q ) ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int ind = 0; ind < L_FRAME48k; ind++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx[ind] = (Word32) ( hCPE->hCoreCoder[0]->hHQ_core->old_out[ind] * ( 1 << q ) ); + } + IF( hCPE->hStereoDft != NULL ) + FOR( int ind = 0; ind < NS2SA( 16000, STEREO_DFT32MS_OVL_NS ); ind++ ) + { + hCPE->hStereoDft->buff_LBTCX_mem_fx[ind] = (Word32) ( hCPE->hStereoDft->buff_LBTCX_mem[ind] * ( 1 << q ) ); + } + // Function call goes here + stereo_dft_dec_core_switching_fx( hCPE, output_fx, synth_fx, hb_synth_fx, DFT_fx, output_frame, use_cldfb_for_dft, 0, &q, q_DFT ); + IF(DFT != NULL) { + FOR( i = 0; i < CPE_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + { + DFT[i][j] = (float) DFT_fx[i][j] / (float) ( 1 << q_DFT[i] ); + } + } + } + FOR( i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_BPF[0][i] = (float) hCPE->input_mem_BPF_fx[0][i] / (float) ( 1 << q ); + FOR( i = 0; i < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem[0][i] = (float) hCPE->input_mem_fx[0][i] / (float) ( 1 << q ); + FOR( i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB[0][i] = (float) hCPE->input_mem_LB_fx[0][i] / (float) ( 1 << q ); + FOR( i = 0; i < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem[1][i] = (float) hCPE->input_mem_fx[1][i] / (float) ( 1 << q ); + FOR( i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB[1][i] = (float) hCPE->input_mem_LB_fx[1][i] / (float) ( 1 << q ); + IF( hCPE->hStereoDft !=NULL ) + FOR( i = 0; i < NS2SA( 16000, DELAY_BWE_TOTAL_NS ); i++ ) + { + hCPE->hStereoDft->ap_delay_mem[i] = (float) hCPE->hStereoDft->ap_delay_mem_fx[i] / (float) ( 1 << q ); + } + IF( (hCPE->hCoreCoder[0] !=NULL) && (hCPE->hCoreCoder[0]->p_bpf_noise_buf_32!=NULL) ) + FOR( i = 0; i < L_FRAME16k; i++ ) + { + hCPE->hCoreCoder[0]->p_bpf_noise_buf_float[i] = (float) hCPE->hCoreCoder[0]->p_bpf_noise_buf_32[i] / (float) ( 1 << q ); + } + FOR( i = 0; i < 960; i++ ) + { + output[0][i] = (float) output_fx[i] / (float) ( 1 << q ); + } + FOR( i = 0; i < hCPE->hCoreCoder[0]->output_Fs / FRAMES_PER_SEC; i++ ) + { + synth[0][i] = (float) synth_fx[i] / (float) ( 1 << q ); + hb_synth[0][i] = (float) hb_synth_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( i = 0; i < L_FRAME48k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_out[i] = (float) hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hStereoDft != NULL ) + FOR( i = 0; i < NS2SA( 16000, STEREO_DFT32MS_OVL_NS ); i++ ) + { + hCPE->hStereoDft->buff_LBTCX_mem[i] = (float) hCPE->hStereoDft->buff_LBTCX_mem_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( i = 0; i < L_FRAME32k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_outLB[i] = (float) hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx[i] / (float) ( 1 << q ); + } +#else stereo_dft_dec_core_switching( hCPE, output[0], synth[0], hb_synth[0], DFT, output_frame, use_cldfb_for_dft, 0 ); +#endif if ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) { diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index eb6df1bf7..94b93e505 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -38,6 +38,7 @@ #include "rom_com.h" #include "prot.h" #include "ivas_prot.h" +#include "prot_fx2.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #include @@ -431,6 +432,9 @@ ivas_error ivas_cpe_dec( if ( hCPE->element_mode == IVAS_CPE_DFT && !( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) ) { float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; + set_f( DFT[0], 0.0f, STEREO_DFT_BUF_MAX ); + set_f( DFT[1], 0.0f, STEREO_DFT_BUF_MAX ); + /* core decoder */ if ( ( error = ivas_core_dec( NULL, NULL, hCPE, st_ivas->hMCT, n_channels, output, outputHB, DFT, 0 ) ) != IVAS_ERR_OK ) @@ -665,6 +669,20 @@ ivas_error create_cpe_dec( } set_zero( hCPE->input_mem_LB[i], STEREO_DFT32MS_OVL_16k ); +#ifdef IVAS_FLOAT_FIXED + IF ( ( hCPE->input_mem_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); + } + set32_fx( hCPE->input_mem_fx[i], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + + IF ( ( hCPE->input_mem_LB_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * STEREO_DFT32MS_OVL_16k ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); + } + set32_fx( hCPE->input_mem_LB_fx[i], 0, STEREO_DFT32MS_OVL_16k ); +#endif + if ( i == 0 ) { if ( ( hCPE->input_mem_BPF[0] = (float *) malloc( sizeof( float ) * STEREO_DFT32MS_OVL_16k ) ) == NULL ) @@ -672,6 +690,14 @@ ivas_error create_cpe_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); } set_zero( hCPE->input_mem_BPF[0], STEREO_DFT32MS_OVL_16k ); +#ifdef IVAS_FLOAT_FIXED + if ( ( hCPE->input_mem_BPF_fx[0] = (Word32 *) malloc( sizeof( Word32 ) * STEREO_DFT32MS_OVL_16k ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DFT stereo memory\n" ) ); + } + set32_fx( hCPE->input_mem_BPF_fx[0], 0, STEREO_DFT32MS_OVL_16k ); +#endif + } if ( ( hCPE->output_mem[i] = (float *) malloc( sizeof( float ) * NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ) ) == NULL ) @@ -927,6 +953,13 @@ void destroy_cpe_dec( hCPE->input_mem[n] = NULL; free( hCPE->output_mem[n] ); hCPE->output_mem[n] = NULL; +#ifdef IVAS_FLOAT_FIXED + free( hCPE->input_mem_LB_fx[n] ); + hCPE->input_mem_LB_fx[n] = NULL; + free( hCPE->input_mem_fx[n] ); + hCPE->input_mem_fx[n] = NULL; +#endif + if ( hCPE->prev_synth_chs[n] != NULL ) { free( hCPE->prev_synth_chs[n] ); @@ -935,6 +968,11 @@ void destroy_cpe_dec( } free( hCPE->input_mem_BPF[0] ); hCPE->input_mem_BPF[0] = NULL; +#ifdef IVAS_FLOAT_FIXED + free( hCPE->input_mem_BPF_fx[0] ); + hCPE->input_mem_BPF_fx[0] = NULL; +#endif + } if ( hCPE->hStereoCng != NULL ) diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index 5ff377606..148f1c4e6 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -36,7 +36,9 @@ #include "cnst.h" #include "rom_com.h" #include "prot.h" +#include "prot_fx2.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -153,6 +155,444 @@ void ivas_post_proc( * * core switching in DFT stereo *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void stereo_dft_dec_core_switching_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 output_fx[], /* i/o: synthesis @internal Fs */ + Word32 synth_fx[], /* i/o: synthesis @output Fs */ + Word32 hb_synth_fx[], /* i/o: hb synthesis */ + Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const Word16 output_frame, /* i : output frame length */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB FOR DFT Stereo */ + const Word16 sba_dirac_stereo_dtx_flag, /* i : DTX indicator FOR SBA DirAC stereo */ + Word16 *q, + Word16 *q_DFT +) +{ + + Word32 output_Fs; + Decoder_State *st; + Word16 i, tmps; + Word16 delay_dft_dec, delay_dft_dec_lb, delay_tdbwe, delay_comp; + Word16 L_frameTCX; + Word16 predelay, ap_fade_len; + Word32 ap_fade_len_inv, ap_fade_len_fx; + Word16 qap_fade_len; + Word32 pAp_input_fx[L_FRAME16k]; + Word32 tcx_core_buf_fx[L_FRAME16k]; + Word64 calc_inv; + Word32 synth_tmp_fx[L_FRAME48k]; + + + st = hCPE->hCoreCoder[0]; /* in DFT stereo, only M channel is decoded by the CoreCoder */ + output_Fs = st->output_Fs; + L_frameTCX = st->hTcxDec->L_frameTCX; + + /*TBE*/ + delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + delay_dft_dec = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); + delay_dft_dec_lb = NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS ); + + /* TCX/ACELP/HQ-CORE->TCX */ + tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); /*cross-fading size @ FB*/ + delay_comp = NS2SA( st->L_frame * FRAMES_PER_SEC, DELAY_BWE_TOTAL_NS ); /*cross-fading size @ LB*/ + + calc_inv = 1; + calc_inv = calc_inv << 31; + + // Memory Tables ////////////////////////////////////////////////////////////////////////////// + + Word32 mem_len_inv_tbl[] = { 85899345, 42949672, 28633115, 21474836, 17179869, 14316557 }; + Word32 delay_comp_inv_tbl[] = { 2147483647, 306783378, 153391689, 97612893, 74051160, 58040098, 48806446, 42107522, 36398027, 32537631, 29020049 }; + /////////////////////////////////////////////////////////////////////////////////////////////// + + IF( st->last_L_frame != st->L_frame && st->last_L_frame <= L_FRAME16k && st->L_frame <= L_FRAME16k ) + { + L_lerp_fx( hCPE->input_mem_LB_fx[0], hCPE->input_mem_LB_fx[0], NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), NS2SA( st->last_L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + L_lerp_fx( hCPE->input_mem_BPF_fx[0], hCPE->input_mem_BPF_fx[0], NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), NS2SA( st->last_L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + } + + IF( st->prev_bfi && !( st->last_core_bfi == ACELP_CORE && st->last_con_tcx == 1 ) ) + { + /* last_core needed FOR correctly decoding ACELP->TCX/HQ switching frames in ivas_core_dec(). + In the following steps the decoder needs to consider IF the core was changed due to a lost frame to apply the correct transition */ + st->last_core = st->last_core_bfi; + } + + IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) + { + IF( ( ( st->last_core != ACELP_CORE || ( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) && st->last_core != AMR_WB_CORE ) || ( sba_dirac_stereo_dtx_flag && st->cng_type == FD_CNG ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ + { + /* In case of a TCX to ACELP switch next frame */ + Copy32( &output_fx[st->L_frame - NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + + /* BPF */ + IF( st->p_bpf_noise_buf_32 && st->core != HQ_CORE ) + { + stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 2, 0, q, q_DFT ); + } + /* st->p_bpf_noise_buf not updated FOR HQ core -> skip analysis and set input memory to zero */ + ELSE IF( st->p_bpf_noise_buf_32 && st->core == HQ_CORE ) + { + set32_fx( hCPE->input_mem_BPF_fx[0], 0, STEREO_DFT32MS_OVL_16k ); + } + + /* TCX */ + stereo_dft_dec_analyze_fx( hCPE, synth_fx, DFT_fx, 0, L_frameTCX, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0, q, q_DFT ); + } + ELSE IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) /* ACELP -> TCX/HQ */ + { + IF( st->last_core_brate <= SID_2k40 && st->element_mode == IVAS_SCE ) + { + Word32 mem_len = NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); + Word32 mem_len_inv = mem_len_inv_tbl[mem_len / 25]; + Word16 qmem_len = norm_l( mem_len ); + Word32 mem_len_fx = L_shl( mem_len, qmem_len ); + FOR( i = 0; i < mem_len; i++ ) + { + hCPE->input_mem_fx[0][i] = Mpy_32_32( hCPE->input_mem_fx[0][i], mem_len_fx - i * ( 1 << qmem_len ) ); + hCPE->input_mem_fx[0][i] = L_shl( Mpy_32_32( hCPE->input_mem_fx[0][i], mem_len_inv ), 31 - qmem_len ); + } + + /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ + FOR( i = 0; i < delay_tdbwe; i++ ) + { + hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = + L_add( hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], hb_synth_fx[i] ); + } + } + ELSE + { + /* Update FB input buff with hb synth FOR last delay_tdbwe sampled */ + FOR( i = 0; i < delay_tdbwe; i++ ) + { + hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = hb_synth_fx[i]; + } + } + + /* cross-fading between (delayed) TBE and FB-TCX over 2.3125ms */ + Copy32( synth_fx, synth_tmp_fx, output_frame ); + Word16 qtmps = norm_l( tmps ); + Word32 tmps_fx = L_shl( tmps, qtmps ); + Word32 tmps_inv = (Word32)(calc_inv / tmps); + FOR( i = 0; i < tmps; i++ ) + { + synth_tmp_fx[i] = L_add( Mpy_32_32( hb_synth_fx[i + delay_tdbwe], tmps_fx - i * ( 1 << qtmps ) ), Mpy_32_32( synth_fx[i], i * ( 1 << qtmps ) ) ); + synth_tmp_fx[i] = L_shl( Mpy_32_32( synth_tmp_fx[i], tmps_inv ), 31 - qtmps ); + } + + /* FB-TCX */ + stereo_dft_dec_analyze_fx( hCPE, synth_tmp_fx, DFT_fx, 0, L_frameTCX, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0, q, q_DFT ); + + IF( !st->tcxonly ) + { + IF( hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF ) + { + Copy32( output_fx, tcx_core_buf_fx, L_FRAME16k ); + } + /* fading-out LB-TCX/ACELP */ + Word16 qdelay_comp = norm_l( delay_comp ); + Word32 delay_comp_inv = delay_comp_inv_tbl[delay_comp / 7]; + Word32 delay_comp_fx = L_shl( delay_comp, qdelay_comp ); + FOR( i = 0; i < delay_comp; i++ ) + { + output_fx[i] = Mpy_32_32( output_fx[i], delay_comp_fx - i * ( 1 << qdelay_comp ) ); + output_fx[i] = L_shl( Mpy_32_32( output_fx[i], delay_comp_inv ), 31 - qdelay_comp ); + } + + /* In case of TCX frames, output LB TCX is zeroed out until the end but in case of an TCX->ACELP switch, this memory is needed, hence it is backed up */ + /* Unlike the case when DFT32MS is disabled, there is only 1 DFT analysis window, hence in the TCX frame we don't want to do a DFT analysis FOR LB TCX + but in a potential ACELP frame, we want the memories of the LB TCX FOR the last OLA samples so that HB analysis can be skipped */ + Copy32( &output_fx[st->L_frame - NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS )], hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + + /*zero the rest FOR avoiding adding contribution except the last samples which are not considered in DFT analysis (potentially used in next ACELP frame)*/ + IF( st->last_core_brate > SID_2k40 ) + { + FOR( ; i < st->L_frame; i++ ) + { + output_fx[i] = 0; + } + + stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB_ADD, 1, 0, q, q_DFT ); + + /* BPF */ + IF( st->p_bpf_noise_buf_32 ) + { + set32_fx( hCPE->input_mem_BPF_fx[0], 0, NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + } + } + } + } + } + ELSE /* ACELP core */ + { + IF( st->core_brate <= SID_2k40 && !( sba_dirac_stereo_dtx_flag ) ) + { + set32_fx( hCPE->input_mem_fx[0], 0, NS2SA( st->hTcxDec->L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hCPE->input_mem_LB_fx[0], 0, NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + + /* CNG generated in ivas_cpe_dec() */ + } + ELSE IF( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE || st->last_core == HQ_CORE ) /* TCX/HQ -> ACELP */ + { + IF( ( st->last_L_frame <= L_FRAME16k && st->L_frame <= L_FRAME16k ) || ( sba_dirac_stereo_dtx_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) + { + /* In case of a TCX to ACELP switch, retrieve the LB-TCX memories FOR the first STEREO_DFT32MS_OVL_NS NS of OLA */ + L_lerp_fx( hCPE->hStereoDft->buff_LBTCX_mem_fx, hCPE->input_mem_LB_fx[0], NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), NS2SA( st->last_L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + } + + IF( sba_dirac_stereo_dtx_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) + { + Word16 nZeros; + nZeros = (Word16) ( NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ); + delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + + Copy32( &st->hHQ_core->oldOut_fx[nZeros - delay_comp - NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS )], hCPE->input_mem_fx[0], NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + Copy32( synth_fx, synth_tmp_fx, output_frame ); + + Word16 mem_len; + mem_len = NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ); + + Word16 qmem_len = norm_l( mem_len ); + Word32 mem_len_fx = L_shl( mem_len, qmem_len ); + Word32 mem_len_inv = (Word32)(calc_inv / tmps); + FOR( i = 0; i < mem_len; i++ ) + { + hCPE->input_mem_LB_fx[0][i] = Mpy_32_32( hCPE->input_mem_LB_fx[0][i], mem_len_fx - ( i * ( 1 << qmem_len ) ) ); + hCPE->input_mem_LB_fx[0][i] = L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][i], mem_len_inv ), 31 - qmem_len ); + } + set32_fx( output_fx, 0, st->L_frame ); + + stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0, q, q_DFT ); + + /* BPF */ + IF( st->p_bpf_noise_buf_32 ) + { + stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); + } + } + ELSE + { + /* ACELP */ + FOR( i = 0; i < ( NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb ); i++ ) + { + hCPE->input_mem_LB_fx[0][i] = 0; + } + /* ACELP fading-in*/ + Word16 qdelay_dft_dec_lb = norm_l( delay_dft_dec_lb ); + Word32 delay_dft_dec_lb_inv = (Word32)(calc_inv / delay_dft_dec_lb); + FOR( i = 0; i < delay_dft_dec_lb; i++ ) + { + hCPE->input_mem_LB_fx[0][NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb + i] = + Mpy_32_32( hCPE->input_mem_LB_fx[0][NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb + i], i * ( 1 << qdelay_dft_dec_lb ) ); + hCPE->input_mem_LB_fx[0][NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb + i] = + L_shl( Mpy_32_32( hCPE->input_mem_LB_fx[0][NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec_lb + i], delay_dft_dec_lb_inv ), 31 - qdelay_dft_dec_lb ); + } + stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0, q, q_DFT ); + + /* BPF */ + IF( st->p_bpf_noise_buf_32 ) + { + stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); + } + + /* Fading-in TD-BWE, Fading-out FB-TCX*/ + Copy32( synth_fx, synth_tmp_fx, output_frame ); + IF( hCPE->last_element_mode != IVAS_CPE_MDCT ) + { + Word16 qdelay_dft_dec = norm_l( delay_dft_dec ); + Word32 delay_dft_dec_inv = (Word32)(calc_inv / delay_dft_dec); + Word32 delay_dft_dec_fx = L_shl( delay_dft_dec, qdelay_dft_dec ); + FOR( i = 0; i < delay_dft_dec; i++ ) /* 1.25 ms of hb_synth fade-in and TCX fade-out */ + { + hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec + i] = L_add( + Mpy_32_32( hb_synth_fx[delay_tdbwe - delay_dft_dec + i], i * ( 1 << qdelay_dft_dec ) ), + Mpy_32_32( hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec + i], delay_dft_dec_fx - i * ( 1 << qdelay_dft_dec ) ) ); + hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec + i] = L_shl( + Mpy_32_32( hCPE->input_mem_fx[0][NS2SA( L_frameTCX * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) - delay_dft_dec + i], delay_dft_dec_inv ), + 31 - qdelay_dft_dec ); + } + FOR( i = 0; i < delay_dft_dec; i++ ) /* 1.25 ms of hb_synth fade out. ICBWE fade in performed in time domain here */ + { + synth_tmp_fx[i] = Mpy_32_32( hb_synth_fx[delay_tdbwe - delay_dft_dec + i], delay_dft_dec_fx - i * ( 1 << qdelay_dft_dec ) ); + synth_tmp_fx[i] = L_shl( Mpy_32_32( synth_tmp_fx[i], delay_dft_dec_inv ), 31 - qdelay_dft_dec ); + } + + FOR( ; i < output_frame; i++ ) + { + synth_tmp_fx[i] = 0; + } + } + } + + + IF( sba_dirac_stereo_dtx_flag ) + { + stereo_dft_dec_analyze_fx( hCPE, synth_tmp_fx, DFT_fx, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB_ADD, 0, 0, q, q_DFT ); + } + ELSE IF( hCPE->last_element_mode == IVAS_CPE_MDCT ) + { + stereo_dft_dec_analyze_fx( hCPE, synth_tmp_fx, DFT_fx, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_HB_ADD, 1, 0, q, q_DFT ); + } + ELSE + { + stereo_dft_dec_analyze_fx( hCPE, synth_tmp_fx, DFT_fx, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB_ADD, 1, 0, q, q_DFT ); + } + } + ELSE /* ACELP -> ACELP */ + { + IF( sba_dirac_stereo_dtx_flag && st->core_brate <= SID_2k40 && st->cng_type == FD_CNG ) + { + set32_fx( output_fx, 0, st->L_frame ); + } + /* this needs an indication FOR sba2stereo in general */ + ELSE IF( hCPE->element_mode == IVAS_SCE && st->last_core_brate <= SID_2k40 && st->cng_type == FD_CNG ) + { + L_lerp_fx( hCPE->input_mem_fx[0], hCPE->input_mem_LB_fx[0], NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), NS2SA( output_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) ); + } + + /* ACELP synthesis @ internal sampling rate */ + + stereo_dft_dec_analyze_fx( hCPE, output_fx, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0, q, q_DFT ); + + /* BPF */ + IF( st->p_bpf_noise_buf_32 ) + { + stereo_dft_dec_analyze_fx( hCPE, st->p_bpf_noise_buf_32, DFT_fx, 0, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_BPF, 0, 0, q, q_DFT ); + } + + /* BWE */ + IF( sba_dirac_stereo_dtx_flag && st->core_brate <= SID_2k40 && st->cng_type == FD_CNG ) + { + stereo_dft_dec_analyze_fx( hCPE, synth_fx, DFT_fx, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB_ADD, 0, 0, q, q_DFT ); + } + ELSE IF( st->extl != -1 || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) + { + stereo_dft_dec_analyze_fx( hCPE, hb_synth_fx, DFT_fx, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_FB_ADD, 2, -delay_tdbwe, q, q_DFT ); + } + } + } + + /*----------------------------------------------------------------* + * enhanced stereo filling: allpass filter + *----------------------------------------------------------------*/ + + IF( hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF ) + { + IF( st->sr_core == INT_FS_12k8 ) + { + ap_fade_len = STEREO_DFT_ALLPASS_FADELEN_12k8; + } + ELSE + { + ap_fade_len = STEREO_DFT_ALLPASS_FADELEN_16k; + } + + qap_fade_len = norm_l( ap_fade_len ); + ap_fade_len_fx = L_shl( ap_fade_len, qap_fade_len ); + ap_fade_len_inv = ap_fade_len == 32 ? 67108864 : 53687091; + + IF( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) + { + Word16 numZeros = (Word16) ( NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); + Word32 tmp_fade_fx[max( STEREO_DFT_ALLPASS_FADELEN_12k8, STEREO_DFT_ALLPASS_FADELEN_16k )]; + + Copy32( st->hHQ_core->old_outLB_fx + numZeros, hCPE->hStereoDft->ap_fade_mem_fx, ap_fade_len ); + + IF( st->last_core == ACELP_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) && !st->tcxonly ) + { + Copy32( tcx_core_buf_fx, pAp_input_fx, st->L_frame ); + } + ELSE + { + Copy32( output_fx, pAp_input_fx, st->L_frame ); + } + + IF( st->last_core == ACELP_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) && !st->tcxonly ) /* ACELP -> TCX/HQ-Core */ + { + Copy32( tcx_core_buf_fx, tmp_fade_fx, ap_fade_len ); + FOR( i = 0; i < ap_fade_len; i++ ) + { + pAp_input_fx[i] = L_add( + Mpy_32_32( pAp_input_fx[i], i * ( 1 << qap_fade_len ) ), + Mpy_32_32( tmp_fade_fx[i], ap_fade_len_fx - i * ( 1 << qap_fade_len ) ) ); + pAp_input_fx[i] = L_shl( Mpy_32_32( pAp_input_fx[i], ap_fade_len_inv ), 31 - qap_fade_len ); + } + } + } + ELSE + { + Copy32( output_fx, pAp_input_fx, st->L_frame ); + IF( st->last_core != ACELP_CORE ) /* TCX/HQ-Core -> ACELP */ + { + FOR( i = 0; i < ap_fade_len; i++ ) + { + pAp_input_fx[i] = L_add( + Mpy_32_32( pAp_input_fx[i], i * ( 1 << qap_fade_len ) ), + Mpy_32_32( hCPE->hStereoDft->ap_fade_mem_fx[i], ap_fade_len_fx - i * ( 1 << qap_fade_len ) ) ); + pAp_input_fx[i] = L_shl( Mpy_32_32( pAp_input_fx[i], ap_fade_len_inv ), 31 - qap_fade_len ); + } + } + } + predelay = NS2SA( st->sr_core, DELAY_BWE_TOTAL_NS ); + + /* apply predelay to have same overall filter delay FOR all cases */ + + delay_signal_fx( pAp_input_fx, st->L_frame, hCPE->hStereoDft->ap_delay_mem_fx, predelay ); + + /* input zeroes FOR transient frames */ + IF( hCPE->hStereoDft->attackPresent ) + { + IF( hCPE->hStereoDft->ap_wasTransient ) + { + set32_fx( pAp_input_fx, 0, ap_fade_len ); + } + ELSE + { + FOR( i = 0; i < ap_fade_len; i++ ) + { + pAp_input_fx[i] = Mpy_32_32( pAp_input_fx[i], ap_fade_len_fx - i * ( 1 << qap_fade_len ) ); + pAp_input_fx[i] = L_shl( Mpy_32_32( pAp_input_fx[i], ap_fade_len_inv ), 31 - qap_fade_len ); + } + } + set32_fx( pAp_input_fx + ap_fade_len, 0, st->L_frame - ap_fade_len ); + hCPE->hStereoDft->ap_wasTransient = 1; + } + ELSE IF( hCPE->hStereoDft->ap_wasTransient ) + { + FOR( i = 0; i < ap_fade_len; i++ ) + { + pAp_input_fx[i] = Mpy_32_32( pAp_input_fx[i], i * ( 1 << qap_fade_len ) ); + pAp_input_fx[i] = L_shl( Mpy_32_32( pAp_input_fx[i], ap_fade_len_inv ), 31 - qap_fade_len ); + } + hCPE->hStereoDft->ap_wasTransient = 0; + } + + /* apply 5-stage allpass, each stage consisting of a nested allpass pair */ + + filter_with_allpass_fx( pAp_input_fx, pAp_input_fx, st->L_frame, &hCPE->hStereoDft->ap1 ); + filter_with_allpass_fx( pAp_input_fx, pAp_input_fx, st->L_frame, &hCPE->hStereoDft->ap2 ); + filter_with_allpass_fx( pAp_input_fx, pAp_input_fx, st->L_frame, &hCPE->hStereoDft->ap3 ); + + /* apply DFT to allpass-filtered signal */ + stereo_dft_dec_analyze_fx( hCPE, pAp_input_fx, DFT_fx, 1, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0, q, q_DFT ); + } + + IF( st->core == ACELP_CORE ) + { + IF( !use_cldfb_for_dft ) /* Skip this FOR DFT Stereo mono output at non-residual bitrates */ + { + L_lerp_fx( output_fx, synth_fx, output_frame, hCPE->hCoreCoder[0]->L_frame ); /* Dirty resampling, but should be good enough FOR ECU analysis */ + } + IF( !use_cldfb_for_dft || ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->cng_type == LP_CNG && st->extl == SWB_CNG && hCPE->nchan_out == 1 ) ) + { + v_add_fx( synth_fx, hb_synth_fx, synth_fx, output_frame ); /* Use one channel TD-BWE FOR ECU analysis buffer */ + } + } + + return; +} +#endif void stereo_dft_dec_core_switching( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ @@ -532,4 +972,4 @@ void stereo_dft_dec_core_switching( } return; -} +} \ No newline at end of file diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 0ab45b6f1..cb4628948 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -93,6 +93,25 @@ const float dft_ap_gains[5][3] = { 0.3f, -0.3f, 0.5f} }; +#ifdef IVAS_FLOAT_FIXED +const Word32 dft_bpf_weights_fx[] = +{ + 1073784832, 1068033792, 1050938752, 1022962432, 984855360, 937628928, 882514816, 820918592, 754369152, + 684457792, 612788736, 540921088, 470318240, 402303136, 338025728, 278428768, 224238096, 175948704, 133830104, + 97937064, 68129992, 44097504, 25391846, 11456825, 1667521, 4637491, 8128225, 9447854, 9195525, 7903813, + 6026913, 3934190, 1908039, 148176, 1226213, 2159294, 2654289, 2754147, 2529735, 2071248 +}; + +const Word32 dft_ap_gains_fx[5][3] = +{ + { 1073741824, -429496729, 1073741824 }, + { -858993459, 429496729, -1073741824 }, + { 858993459, -644245094, 1073741824 }, + { -858993459, 644245094, -1073741824 }, + { 644245094, -644245120, 1073741824 } +}; +#endif + const int16_t dft_ap_delays[3][3] = { { 2, 47, 61}, @@ -218,6 +237,82 @@ const float dft_win_8k[70] = 0.9544637f, 0.9609173f, 0.9668870f, 0.9723699f, 0.9773632f, 0.9818643f, 0.9858710f, 0.9893813f, 0.9923935f, 0.9949059f, 0.9969173f, 0.9984268f, 0.9994336f, 0.9999371f }; +#ifdef IVAS_FLOAT_FIXED +const Word16 dft_win232ms_8k_fx[75] = +{ + 343, 1029, 1714, 2399, 3083, 3766, 4447, 5126, 5802, 6476, 7148, 7816, 8480, 9141, 9798, 10451, 11099, 11742, 12381, 13013, 13640, 14261, 14876, 15484, 16085, 16680, 17267, + 17846, 18418, 18981, 19537, 20083, 20621, 21150, 21669, 22179, 22680, 23170, 23650, 24120, 24579, 25028, 25465, 25891, 26306, 26710, 27101, 27481, 27849, 28204, 28547, 28878, + 29196, 29501, 29793, 30072, 30338, 30591, 30830, 31056, 31268, 31466, 31651, 31822, 31978, 32121, 32250, 32364, 32464, 32550, 32622, 32680, 32723, 32751, 32766 +}; + +const Word16 dft_win232ms_12k8_fx[120] = +{ + 214, 643, 1072, 1500, 1929, 2357, 2784, 3211, 3638, 4064, 4489, 4914, 5337, 5760, 6182, 6602, 7022, 7440, 7857, 8273, 8687, 9100, 9512, 9921, 10329, 10735, 11140, + 11542, 11942, 12341, 12737, 13131, 13523, 13913, 14300, 14684, 15067, 15446, 15823, 16197, 16569, 16938, 17303, 17666, 18026, 18382, 18736, 19086, 19433, 19777, + 20117, 20454, 20787, 21117, 21443, 21766, 22084, 22399, 22711, 23018, 23321, 23620, 23916, 24207, 24494, 24777, 25055, 25330, 25599, 25865, 26126, 26383, 26635, + 26882, 27125, 27364, 27597, 27826, 28050, 28270, 28484, 28694, 28898, 29098, 29293, 29482, 29667, 29847, 30021, 30190, 30355, 30514, 30667, 30816, 30959, 31097, + 31229, 31357, 31478, 31595, 31706, 31811, 31912, 32006, 32095, 32179, 32257, 32330, 32397, 32458, 32514, 32565, 32610, 32649, 32683, 32711, 32733, 32750, 32761, 32767 +}; + +const Word16 dft_win232ms_16k_fx[150] = +{ + 171, 514, 857, 1200, 1543, 1886, 2228, 2570, 2912, 3254, 3595, 3936, 4277, 4617, 4956, 5295, 5633, 5971, 6308, 6644, 6980, 7315, 7649, 7982, 8315, 8646, 8977, 9306, + 9635, 9962, 10288, 10614, 10938, 11261, 11582, 11903, 12222, 12539, 12856, 13171, 13484, 13796, 14106, 14415, 14723, 15029, 15333, 15635, 15936, 16235, 16532, 16827, + 17121, 17412, 17702, 17990, 18276, 18559, 18841, 19121, 19399, 19674, 19947, 20219, 20487, 20754, 21019, 21281, 21540, 21798, 22053, 22305, 22556, 22803, 23048, 23291, + 23531, 23769, 24003, 24236, 24465, 24692, 24916, 25138, 25357, 25573, 25786, 25996, 26204, 26408, 26610, 26809, 27004, 27197, 27387, 27574, 27758, 27939, 28117, 28291, + 28463, 28631, 28797, 28959, 29118, 29273, 29426, 29575, 29722, 29864, 30004, 30140, 30273, 30403, 30529, 30652, 30772, 30888, 31001, 31110, 31216, 31319, 31418, 31514, + 31606, 31695, 31780, 31862, 31940, 32015, 32087, 32155, 32219, 32280, 32337, 32390, 32441, 32487, 32530, 32570, 32605, 32638, 32666, 32692, 32713, 32731, 32745, 32756, + 32763, 32767 +}; + +const Word16 dft_win232ms_32k_fx[300] = +{ + 85, 257, 428, 600, 772, 943, 1115, 1286, 1457, 1629, 1800, 1971, 2143, 2314, 2485, 2656, 2827, 2998, 3169, 3339, 3510, 3681, 3851, 4021, 4192, 4362, 4532, 4701, 4871, + 5041, 5210, 5380, 5549, 5718, 5887, 6055, 6224, 6392, 6560, 6728, 6896, 7064, 7231, 7399, 7566, 7732, 7899, 8065, 8232, 8398, 8563, 8729, 8894, 9059, 9224, 9388, 9553, + 9717, 9880, 10044, 10207, 10370, 10532, 10695, 10857, 11019, 11180, 11341, 11502, 11662, 11823, 11982, 12142, 12301, 12460, 12618, 12777, 12934, 13092, 13249, 13406, + 13562, 13718, 13874, 14029, 14184, 14338, 14492, 14646, 14799, 14952, 15105, 15257, 15408, 15560, 15710, 15861, 16011, 16160, 16309, 16458, 16606, 16754, 16901, 17048, + 17194, 17340, 17485, 17630, 17774, 17918, 18062, 18204, 18347, 18489, 18630, 18771, 18911, 19051, 19191, 19329, 19468, 19605, 19743, 19879, 20015, 20151, 20286, 20420, + 20554, 20688, 20820, 20953, 21084, 21215, 21346, 21476, 21605, 21734, 21862, 21989, 22116, 22242, 22368, 22493, 22618, 22741, 22865, 22987, 23109, 23231, 23351, 23471, + 23591, 23709, 23828, 23945, 24062, 24178, 24293, 24408, 24522, 24636, 24749, 24861, 24972, 25083, 25193, 25302, 25411, 25519, 25626, 25733, 25839, 25944, 26048, 26152, + 26255, 26357, 26459, 26560, 26660, 26759, 26858, 26956, 27053, 27149, 27245, 27340, 27434, 27528, 27620, 27712, 27803, 27894, 27984, 28072, 28161, 28248, 28334, 28420, + 28505, 28589, 28673, 28756, 28837, 28918, 28999, 29078, 29157, 29235, 29312, 29388, 29464, 29538, 29612, 29685, 29758, 29829, 29900, 29969, 30038, 30106, 30174, 30240, + 30306, 30371, 30435, 30498, 30560, 30622, 30682, 30742, 30801, 30859, 30917, 30973, 31029, 31083, 31137, 31190, 31242, 31294, 31344, 31394, 31442, 31490, 31537, 31583, + 31629, 31673, 31717, 31759, 31801, 31842, 31882, 31921, 31960, 31997, 32033, 32069, 32104, 32138, 32171, 32203, 32234, 32265, 32294, 32323, 32351, 32377, 32403, 32428, + 32453, 32476, 32498, 32520, 32540, 32560, 32579, 32597, 32614, 32630, 32645, 32660, 32673, 32686, 32697, 32708, 32718, 32727, 32735, 32742, 32749, 32754, 32758, 32762, + 32765, 32766, 32767 +}; + +const Word16 dft_win232ms_48k_fx[450] = +{ + 57, 171, 285, 400, 514, 629, 743, 857, 972, 1086, 1200, 1315, 1429, 1543, 1657, 1772, 1886, 2000, 2114, 2228, 2342, 2456, 2570, 2684, 2798, 2912, 3026, 3140, 3254, 3368, + 3482, 3595, 3709, 3823, 3936, 4050, 4163, 4277, 4390, 4503, 4617, 4730, 4843, 4956, 5069, 5182, 5295, 5408, 5521, 5633, 5746, 5858, 5971, 6083, 6196, 6308, 6420, 6532, + 6644, 6756, 6868, 6980, 7092, 7203, 7315, 7426, 7538, 7649, 7760, 7871, 7982, 8093, 8204, 8315, 8425, 8536, 8646, 8756, 8867, 8977, 9087, 9196, 9306, 9416, 9525, 9635, + 9744, 9853, 9962, 10071, 10180, 10288, 10397, 10505, 10614, 10722, 10830, 10938, 11045, 11153, 11261, 11368, 11475, 11582, 11689, 11796, 11903, 12009, 12115, 12222, 12328, + 12434, 12539, 12645, 12750, 12856, 12961, 13066, 13171, 13275, 13380, 13484, 13588, 13692, 13796, 13900, 14003, 14106, 14210, 14313, 14415, 14518, 14621, 14723, 14825, + 14927, 15029, 15130, 15231, 15333, 15434, 15534, 15635, 15735, 15836, 15936, 16036, 16135, 16235, 16334, 16433, 16532, 16631, 16729, 16827, 16925, 17023, 17121, 17218, + 17315, 17412, 17509, 17606, 17702, 17798, 17894, 17990, 18085, 18181, 18276, 18371, 18465, 18559, 18654, 18748, 18841, 18935, 19028, 19121, 19214, 19306, 19399, 19491, + 19582, 19674, 19765, 19857, 19947, 20038, 20128, 20219, 20308, 20398, 20487, 20577, 20665, 20754, 20843, 20931, 21019, 21106, 21194, 21281, 21367, 21454, 21540, 21626, + 21712, 21798, 21883, 21968, 22053, 22137, 22221, 22305, 22389, 22472, 22556, 22638, 22721, 22803, 22885, 22967, 23048, 23130, 23210, 23291, 23371, 23451, 23531, 23611, + 23690, 23769, 23847, 23925, 24003, 24081, 24159, 24236, 24313, 24389, 24465, 24541, 24617, 24692, 24767, 24842, 24916, 24991, 25064, 25138, 25211, 25284, 25357, 25429, + 25501, 25573, 25644, 25715, 25786, 25856, 25926, 25996, 26066, 26135, 26204, 26272, 26340, 26408, 26476, 26543, 26610, 26676, 26743, 26809, 26874, 26940, 27004, 27069, + 27133, 27197, 27261, 27324, 27387, 27450, 27512, 27574, 27636, 27697, 27758, 27819, 27879, 27939, 27998, 28058, 28117, 28175, 28233, 28291, 28349, 28406, 28463, 28519, + 28575, 28631, 28687, 28742, 28797, 28851, 28905, 28959, 29012, 29065, 29118, 29170, 29222, 29273, 29325, 29376, 29426, 29476, 29526, 29575, 29624, 29673, 29722, 29769, + 29817, 29864, 29911, 29958, 30004, 30050, 30095, 30140, 30185, 30229, 30273, 30317, 30360, 30403, 30445, 30487, 30529, 30571, 30612, 30652, 30692, 30732, 30772, 30811, + 30850, 30888, 30926, 30964, 31001, 31038, 31074, 31110, 31146, 31181, 31216, 31251, 31285, 31319, 31352, 31385, 31418, 31450, 31482, 31514, 31545, 31576, 31606, 31636, + 31666, 31695, 31724, 31752, 31780, 31808, 31835, 31862, 31889, 31915, 31940, 31966, 31991, 32015, 32040, 32063, 32087, 32110, 32132, 32155, 32176, 32198, 32219, 32239, + 32260, 32280, 32299, 32318, 32337, 32355, 32373, 32390, 32408, 32424, 32441, 32457, 32472, 32487, 32502, 32516, 32530, 32544, 32557, 32570, 32582, 32594, 32605, 32617, + 32627, 32638, 32648, 32657, 32666, 32675, 32684, 32692, 32699, 32706, 32713, 32720, 32726, 32731, 32736, 32741, 32745, 32749, 32753, 32756, 32759, 32761, 32763, 32765, + 32766, 32767, 32767 +}; + +const Word16 dft_win_8k_fx[70] = +{ + 367, 1102, 1837, 2570, 3303, 4033, 4762, 5488, 6212, 6932, 7649, 8362, 9071, 9775, 10474, 11168, 11857, 12539, 13215, 13885, 14547, 15203, 15850, 16490, 17121, 17743, + 18357, 18961, 19556, 20141, 20716, 21281, 21834, 22377, 22909, 23428, 23937, 24433, 24916, 25388, 25846, 26292, 26724, 27143, 27548, 27939, 28316, 28679, 29027, 29361, + 29680, 29984, 30273, 30547, 30805, 31048, 31275, 31487, 31682, 31862, 32026, 32173, 32305, 32420, 32518, 32601, 32666, 32716, 32749, 32765 +}; +#endif + /*------------------------------------------------------------------------- * stereo CNA tables diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 4ff133596..c7fc25788 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -48,6 +48,11 @@ extern const float dft_alpha_w_b2[STEREO_DFT_BAND_MAX]; extern const float dft_alpha_s_b2[STEREO_DFT_BAND_MAX]; extern const float dft_alpha_s2_b2[STEREO_DFT_BAND_MAX]; extern const float dft_bpf_weights[]; +#ifdef IVAS_FLOAT_FIXED +extern const Word32 dft_bpf_weights_fx[]; +extern const Word32 dft_ap_gains_fx[5][3]; +#endif + extern const float dft_alpha_w[]; extern const float dft_alpha_s[]; @@ -63,6 +68,14 @@ extern const float dft_win232ms_16k[150]; extern const float dft_win232ms_32k[300]; extern const float dft_win232ms_48k[450]; +#ifdef IVAS_FLOAT_FIXED +extern const Word16 dft_win232ms_8k_fx[75]; +extern const Word16 dft_win232ms_12k8_fx[120]; +extern const Word16 dft_win232ms_16k_fx[150]; +extern const Word16 dft_win232ms_32k_fx[300]; +extern const Word16 dft_win232ms_48k_fx[450]; +#endif + extern const float dft_win_8k[70]; extern const int16_t cna_init_bands[CNA_INIT_NBANDS + 1]; diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index d8487479f..3d2e0286a 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -37,6 +37,7 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" @@ -860,7 +861,122 @@ void ivas_sba_dirac_stereo_dec( /* do DFT Stereo core switching (including DFT analysis) here as CPE element was not available in SCE decoder */ mvr2r( hSCE->save_synth, tmp_synth, hSCE->hCoreCoder[0]->L_frame ); +#ifdef IVAS_FLOAT_FIXED + Word16 q = 11, q_DFT[2] = { 3, 3 }; + Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; + Word32 synth_fx[L_FRAME48k]; + Word32 hb_synth_fx[L_FRAME48k]; + Word32 output_fx[960]; + FOR( int i = 0; i < 960; i++ ) + { + output_fx[i] = (Word32)(output[0][i] * ( 1 << q )); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int i = 0; i < L_FRAME32k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx[i] = (Word32)(hCPE->hCoreCoder[0]->hHQ_core->old_outLB[i] * ( 1 << q )); + } + IF( (hCPE->hCoreCoder[0] != NULL) && (hCPE->hCoreCoder[0]->p_bpf_noise_buf_32 != NULL) ) + FOR( int i = 0; i < L_FRAME16k; i++ ) + { + hCPE->hCoreCoder[0]->p_bpf_noise_buf_32[i] = (Word32)(hCPE->hCoreCoder[0]->p_bpf_noise_buf_float[i] * ( 1 << q )); + } + IF( DFT != NULL ) + FOR( int i = 0; i < CPE_CHANNELS; i++ ) + { + FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + { + DFT_fx[i][j] = (Word32)(DFT[i][j] * ( 1 << q_DFT[i] )); + } + } + + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_BPF_fx[0][i] = (Word32)(hCPE->input_mem_BPF[0][i] * ( 1 << q )); + FOR( int i = 0; i < NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem_fx[0][i] = (Word32)(hCPE->input_mem[0][i] * ( 1 << q )); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB_fx[0][i] = (Word32)(hCPE->input_mem_LB[0][i] * ( 1 << q )); + FOR( int i = 0; i < NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem_fx[1][i] = (Word32)(hCPE->input_mem[1][i] * ( 1 << q )); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB_fx[1][i] = (Word32)(hCPE->input_mem_LB[1][i] * ( 1 << q )); + IF( hCPE->hStereoDft != NULL ) + FOR( int i = 0; i < NS2SA( 16000, DELAY_BWE_TOTAL_NS ); i++ ) + { + hCPE->hStereoDft->ap_delay_mem_fx[i] = (Word32)(hCPE->hStereoDft->ap_delay_mem[i] * ( 1 << q )); + } + FOR( int i = 0; i < hCPE->hCoreCoder[0]->output_Fs / FRAMES_PER_SEC; i++ ) + { + synth_fx[i] = (Word32)(hSCE->save_synth[i] * ( 1 << q )); + hb_synth_fx[i] = (Word32)(hSCE->save_hb_synth[i] * ( 1 << q )); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int i = 0; i < L_FRAME48k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx[i] = (Word32)(hCPE->hCoreCoder[0]->hHQ_core->old_out[i] * ( 1 << q )); + } + IF( hCPE->hStereoDft != NULL ) + FOR( int i = 0; i < NS2SA( 16000, STEREO_DFT32MS_OVL_NS ); i++ ) + { + hCPE->hStereoDft->buff_LBTCX_mem_fx[i] = (Word32)(hCPE->hStereoDft->buff_LBTCX_mem[i] * ( 1 << q )); + } + stereo_dft_dec_core_switching_fx( hCPE, output_fx /*hSCE->save_output*/, synth_fx, hb_synth_fx, DFT_fx, output_frame, 0, dtx_flag, &q, q_DFT ); + IF( DFT != NULL ) + FOR( int i = 0; i < CPE_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + { + DFT[i][j] = (float) DFT_fx[i][j] / (float) ( 1 << q_DFT[i] ); + } + } + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_BPF[0][i] = (float) hCPE->input_mem_BPF_fx[0][i] / (float) ( 1 << q ); + FOR( int i = 0; i < NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem[0][i] = (float) hCPE->input_mem_fx[0][i] / (float) ( 1 << q ); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB[0][i] = (float) hCPE->input_mem_LB_fx[0][i] / (float) ( 1 << q ); + FOR( int i = 0; i < NS2SA( hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem[1][i] = (float) hCPE->input_mem_fx[1][i] / (float) ( 1 << q ); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB[1][i] = (float) hCPE->input_mem_LB_fx[1][i] / (float) ( 1 << q ); + IF( hCPE->hStereoDft != NULL ) + FOR( int i = 0; i < NS2SA( 16000, DELAY_BWE_TOTAL_NS ); i++ ) + { + hCPE->hStereoDft->ap_delay_mem[i] = (float) hCPE->hStereoDft->ap_delay_mem_fx[i] / (float) ( 1 << q ); + } + IF( (hCPE->hCoreCoder[0] != NULL) && (hCPE->hCoreCoder[0]->p_bpf_noise_buf_32 != NULL) ) + FOR( int i = 0; i < L_FRAME16k; i++ ) + { + hCPE->hCoreCoder[0]->p_bpf_noise_buf_float[i] = (float) hCPE->hCoreCoder[0]->p_bpf_noise_buf_32[i] / (float) ( 1 << q ); + } + FOR( int i = 0; i < 960; i++ ) + { + output[0][i] = (float) output_fx[i] / (float) ( 1 << q ); + } + FOR( int i = 0; i < hCPE->hCoreCoder[0]->output_Fs / FRAMES_PER_SEC; i++ ) + { + hSCE->save_synth[i] = (float) synth_fx[i] / (float) ( 1 << q ); + hSCE->save_hb_synth[i] = (float) hb_synth_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int i = 0; i < L_FRAME48k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_out[i] = (float) hCPE->hCoreCoder[0]->hHQ_core->oldOut_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hStereoDft != NULL ) + FOR( int i = 0; i < NS2SA( 16000, STEREO_DFT32MS_OVL_NS ); i++ ) + { + hCPE->hStereoDft->buff_LBTCX_mem[i] = (float) hCPE->hStereoDft->buff_LBTCX_mem_fx[i] / (float) ( 1 << q ); + } + IF( hCPE->hCoreCoder[0] != NULL ) + FOR( int i = 0; i < L_FRAME32k; i++ ) + { + hCPE->hCoreCoder[0]->hHQ_core->old_outLB[i] = (float) hCPE->hCoreCoder[0]->hHQ_core->old_outLB_fx[i] / (float) ( 1 << q ); + } + +#else stereo_dft_dec_core_switching( hCPE, output[0] /*hSCE->save_output*/, hSCE->save_synth, hSCE->save_hb_synth, DFT, output_frame, 0, dtx_flag ); +#endif /* do updates here after skipping this in SCE decoder (needs to be done after core switching) */ updt_dec_common( hSCE->hCoreCoder[0], NORMAL_HQ_CORE, -1, hSCE->save_synth ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index e2c395eab..4f2b630d1 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -68,6 +68,12 @@ typedef struct float buffer[3][STEREO_DFT_ALLPASS_BUFFERLEN]; int16_t pos; +#ifdef IVAS_FLOAT_FIXED + Word32 gains_fx[3]; + Word32 buffer_fx[3][STEREO_DFT_ALLPASS_BUFFERLEN]; +#endif + + } basic_allpass_t; @@ -86,17 +92,37 @@ typedef struct stereo_dft_dec_data_struct const float *dft_trigo_8k; int16_t dft_trigo_step; +#ifdef IVAS_FLOAT_FIXED + const Word16 *dft_trigo_fx; + const Word16 *dft_trigo_12k8_fx; + const Word16 *dft_trigo_16k_fx; + const Word16 *dft_trigo_8k_fx; +#endif + + int16_t dft32ms_ovl; /* Overlap size */ const float *win32ms; /* DFT window */ const float *win32ms_12k8; /* DFT window */ const float *win32ms_16k; /* DFT window */ const float *win32ms_8k; /* DFT window */ +#ifdef IVAS_FLOAT_FIXED + const Word16 *win32ms_fx; /* DFT window */ + const Word16 *win32ms_12k8_fx; /* DFT window */ + const Word16 *win32ms_16k_fx; /* DFT window */ + const Word16 *win32ms_8k_fx; /* DFT window */ +#endif int16_t dft32ms_ovl2; /* Overlap2 size */ const float *win232ms; /* DFT window */ const float *win232ms_12k8; /* DFT window */ const float *win232ms_16k; /* DFT window */ const float *win232ms_8k; /* DFT window */ +#ifdef IVAS_FLOAT_FIXED + const Word16 *win232ms_fx; /* DFT window */ + const Word16 *win232ms_12k8_fx; /* DFT window */ + const Word16 *win232ms_16k_fx; /* DFT window */ + const Word16 *win232ms_8k_fx; /* DFT window */ +#endif const float *win_8k; /* DFT window residual */ @@ -160,6 +186,10 @@ typedef struct stereo_dft_dec_data_struct #endif // IVAS_FLOAT_FIXED float res_cod_mem[STEREO_DFT_OVL_8k]; float buff_LBTCX_mem[NS2SA( 16000, STEREO_DFT32MS_OVL_NS )]; +#ifdef IVAS_FLOAT_FIXED + Word32 buff_LBTCX_mem_fx[NS2SA( 16000, STEREO_DFT32MS_OVL_NS )]; +#endif + float stab_fac_smooth_res; /* low-pass filtered stability factor */ BPF_DEC_HANDLE hBpf; @@ -178,6 +208,11 @@ typedef struct stereo_dft_dec_data_struct basic_allpass_t ap1, ap2, ap3; float ap_delay_mem[NS2SA( 16000, DELAY_BWE_TOTAL_NS )]; float ap_fade_mem[STEREO_DFT_ALLPASS_FADELEN_16k]; +#ifdef IVAS_FLOAT_FIXED + Word32 ap_delay_mem_fx[NS2SA( 16000, DELAY_BWE_TOTAL_NS )]; + Word32 ap_fade_mem_fx[STEREO_DFT_ALLPASS_FADELEN_16k]; +#endif + int16_t ap_wasTransient; float smooth_dmx_nrg[STEREO_DFT_BAND_MAX]; float smooth_res_nrg[STEREO_DFT_BAND_MAX]; @@ -744,6 +779,12 @@ typedef struct cpe_dec_data_structure float *output_mem[CPE_CHANNELS]; float *prev_synth_chs[CPE_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED + Word32 *input_mem_fx[CPE_CHANNELS]; + Word32 *input_mem_LB_fx[CPE_CHANNELS]; + Word32 *input_mem_BPF_fx[1]; +#endif + /* buffers used for fading between MDCT and DFT Stereo */ float old_out_mdct[STEREO_MDCT2DFT_FADE_LEN_48k]; float old_outLB_mdct[2 * STEREO_MDCT2DFT_FADE_LEN_48k]; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index f0b7f59dc..c6ee4cd02 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -38,9 +38,11 @@ #include "rom_com.h" #include "rom_dec.h" #include "prot.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#include "ivas_rom_com_fx.h" #include "ivas_rom_dec.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED @@ -322,16 +324,34 @@ static void stereo_dft_dec_open( hStereoDft->dft_trigo_8k = dft_trigo_32k; hStereoDft->dft_trigo_12k8 = dft_trigo_12k8; hStereoDft->dft_trigo_16k = dft_trigo_32k; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->dft_trigo_8k_fx = dft_trigo_32k_fx; + hStereoDft->dft_trigo_12k8_fx = dft_trigo_12k8_fx; + hStereoDft->dft_trigo_16k_fx = dft_trigo_32k_fx; +#endif + hStereoDft->dft32ms_ovl = (int16_t) ( ( STEREO_DFT32MS_OVL_MAX * output_Fs ) / 48000 ); hStereoDft->win232ms_8k = dft_win232ms_8k; hStereoDft->win232ms_12k8 = dft_win232ms_12k8; hStereoDft->win232ms_16k = dft_win232ms_16k; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->win232ms_8k_fx = dft_win232ms_8k_fx; + hStereoDft->win232ms_12k8_fx = dft_win232ms_12k8_fx; + hStereoDft->win232ms_16k_fx = dft_win232ms_16k_fx; +#endif + hStereoDft->dft32ms_ovl2 = (int16_t) ( ( STEREO_DFT32MS_OVL2_MAX * output_Fs ) / 48000 ); hStereoDft->win32ms_8k = dft_win232ms_8k + 1; hStereoDft->win32ms_12k8 = dft_win232ms_12k8 + 1; hStereoDft->win32ms_16k = dft_win232ms_16k + 1; +#ifdef IVAS_FLOAT_FIXED + hStereoDft->win32ms_8k_fx = dft_win232ms_8k_fx + 1; + hStereoDft->win32ms_12k8_fx = dft_win232ms_12k8_fx + 1; + hStereoDft->win32ms_16k_fx = dft_win232ms_16k_fx + 1; +#endif + if ( output_Fs == 16000 ) { @@ -339,6 +359,12 @@ static void stereo_dft_dec_open( hStereoDft->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP; hStereoDft->win232ms = dft_win232ms_16k; hStereoDft->win32ms = dft_win232ms_16k + 1; + +#ifdef IVAS_FLOAT_FIXED + hStereoDft->dft_trigo_fx = dft_trigo_32k_fx; + hStereoDft->win232ms_fx = dft_win232ms_16k_fx; + hStereoDft->win32ms_fx = dft_win232ms_16k_fx + 1; +#endif } else if ( output_Fs == 32000 ) { @@ -346,6 +372,12 @@ static void stereo_dft_dec_open( hStereoDft->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_32k_STEP; hStereoDft->win232ms = dft_win232ms_32k; hStereoDft->win32ms = dft_win232ms_32k + 1; + +#ifdef IVAS_FLOAT_FIXED + hStereoDft->dft_trigo_fx = dft_trigo_32k_fx; + hStereoDft->win232ms_fx = dft_win232ms_32k_fx; + hStereoDft->win32ms_fx = dft_win232ms_32k_fx + 1; +#endif } else { @@ -354,6 +386,12 @@ static void stereo_dft_dec_open( hStereoDft->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_48k_STEP; hStereoDft->win232ms = dft_win232ms_48k; hStereoDft->win32ms = dft_win232ms_48k + 1; + +#ifdef IVAS_FLOAT_FIXED + hStereoDft->dft_trigo_fx = dft_trigo_48k_fx; + hStereoDft->win232ms_fx = dft_win232ms_48k_fx; + hStereoDft->win32ms_fx = dft_win232ms_48k_fx + 1; +#endif } hStereoDft->win_8k = dft_win_8k; @@ -461,9 +499,15 @@ void stereo_dft_dec_reset( set_zero( hStereoDft->g_state, STEREO_DFT_BAND_MAX ); +#ifdef IVAS_FLOAT_FIXED + init_basic_allpass( &hStereoDft->ap1, dft_ap_gains[0], dft_ap_gains_fx[0], dft_ap_delays[0] ); + init_basic_allpass( &hStereoDft->ap2, dft_ap_gains[1], dft_ap_gains_fx[1], dft_ap_delays[1] ); + init_basic_allpass( &hStereoDft->ap3, dft_ap_gains[2], dft_ap_gains_fx[2], dft_ap_delays[2] ); +#else init_basic_allpass( &hStereoDft->ap1, dft_ap_gains[0], dft_ap_delays[0] ); init_basic_allpass( &hStereoDft->ap2, dft_ap_gains[1], dft_ap_delays[1] ); init_basic_allpass( &hStereoDft->ap3, dft_ap_gains[2], dft_ap_delays[2] ); +#endif set_zero( hStereoDft->ap_delay_mem, NS2SA( 16000, DELAY_BWE_TOTAL_NS ) ); set_zero( hStereoDft->ap_fade_mem, STEREO_DFT_ALLPASS_FADELEN_16k ); @@ -645,6 +689,684 @@ void stereo_dft_dec_destroy( * DFT analysis on a 20ms frame *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void stereo_dft_dec_analyze( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + // const Word32 *input_fx, /* i : input signal */ + // Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + + const float *input, /* i : input signal */ + float out_DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + + const Word16 chan, /* i : channel number */ + const Word16 input_frame, /* i : input frame size */ + const Word16 output_frame, /* i : output frame size */ + const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : type of signal to analyse */ + const Word16 k_offset, /* i : offset of DFT */ + const Word16 delay /* i : delay in samples FOR input signal */ + /*Word16 *q, + Word16 *q_out_DFT*/ +) +{ + + Word16 q = 11; + Word32 output_Fs = hCPE->hCoreCoder[0]->output_Fs; + Word32 input_fx[2000]; + FOR( int i = 0; i < 960; i++ ) + { + input_fx[i] = (Word32)(input[i] * ( 1 << q )); + } + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_BPF_fx[0][i] = (Word32)(hCPE->input_mem_BPF[0][i] * ( 1 << q )); + FOR( int i = 0; i < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem_fx[0][i] = (Word32)(hCPE->input_mem[0][i] * ( 1 << q )); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB_fx[0][i] = (Word32)(hCPE->input_mem_LB[0][i] * ( 1 << q )); + FOR( int i = 0; i < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); i++ ) + hCPE->input_mem_fx[1][i] = (Word32)(hCPE->input_mem[1][i] * ( 1 << q )); + FOR( int i = 0; i < STEREO_DFT32MS_OVL_16k; i++ ) + hCPE->input_mem_LB_fx[1][i] = (Word32)(hCPE->input_mem_LB[1][i] * ( 1 << q )); + Word16 q_out_DFT[2] = { 3, 3 }; + Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; + IF( out_DFT ) + { + FOR( int i = 0; i < CPE_CHANNELS; i++ ) + FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + IF( abs( (Word32) out_DFT[i][j] ) != 0 ) + q_out_DFT[i] = min( q_out_DFT[i], norm_l( (Word32) out_DFT[i][j] ) ); + + FOR( int i = 0; i < CPE_CHANNELS; i++ ) + FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + out_DFT_fx[i][j] = (Word32)(out_DFT[i][j] * ( 1 << q_out_DFT[i] )); + } + ////////////////////////////////////////////////////////// + Word16 i, k; + STEREO_DFT_DEC_DATA_HANDLE hStereoDft; + Word32 *pInput_fx, *pInput_buff_fx; + Word32 *mem_fx, input_buff_fx[STEREO_DFT32MS_OVL_MAX + L_FRAME48k]; + Word32 DFT_fx[STEREO_DFT32MS_N_MAX], *pDFT_out_fx; + Word16 NFFT, NFFT_core, ovl, zp; + Word16 offset; + Word32 fac_fx; + const Word16 *trigo_fx, *win_left_fx, *win_right_fx, *win2_fx; + Word16 trigo_dec_fx[STEREO_DFT32MS_N_MAX / 2 + 1]; + Word16 trigo_step; + Word32 inputFs; + Word16 delay_dec; + Word16 mem_size; + Word16 ovl2; + + push_wmops( "DFT_analysis" ); + + hStereoDft = hCPE->hStereoDft; + + assert( output_frame == STEREO_DFT_NBDIV * hStereoDft->N ); + + /*-----------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + IF( input_frame == output_frame ) + { + trigo_fx = hStereoDft->dft_trigo_fx; + trigo_step = hStereoDft->dft_trigo_step * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_fx; + win_left_fx = hStereoDft->win32ms_fx; + win2_fx = hStereoDft->win232ms_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME ) + { + trigo_fx = hStereoDft->dft_trigo_12k8_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_12k8_fx; + win_left_fx = hStereoDft->win32ms_12k8_fx; + win2_fx = hStereoDft->win232ms_12k8_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + assert( ( chan == 1 ) && "12.8kHz sampling rate only FOR second channel, i.e. residual coding or allpass signal" ); + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME16k ) + { + trigo_fx = hStereoDft->dft_trigo_16k_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_16k_fx; + win_left_fx = hStereoDft->win32ms_16k_fx; + win2_fx = hStereoDft->win232ms_16k_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + assert( ( chan == 1 ) && hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF && "16kHz sampling rate only FOR second channel with allpass signal" ); + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME8k ) + { + assert( ( chan == 1 ) && "DFT stereo: 8kHz analysis only FOR residual coding" ); + trigo_fx = hStereoDft->dft_trigo_8k_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_8k_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_8k_fx; + win_left_fx = hStereoDft->win32ms_8k_fx; + win2_fx = hStereoDft->win232ms_8k_fx; + mem_fx = hCPE->input_mem_fx[chan]; + } + ELSE + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error in DFT stereo: sampling rate not supported" ); + mem_fx = NULL; /* to avoid compilation warning */ + trigo_fx = NULL; /* to avoid compilation warning */ + trigo_step = -1; /* to avoid compilation warning */ + win_right_fx = NULL; /* to avoid compilation warning */ + win_left_fx = NULL; /* to avoid compilation warning */ + win2_fx = NULL; /* to avoid compilation warning */ + } + + inputFs = input_frame * FRAMES_PER_SEC; + delay_dec = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); + zp = NS2SA( inputFs, STEREO_DFT32MS_ZP_NS ); + ovl = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); + NFFT = NS2SA( inputFs, STEREO_DFT32MS_N_NS ); + Word16 w1, w2, qw1, qw2, qfac_fx; + qw1 = norm_s( hStereoDft->NFFT ); + qw2 = norm_s( NFFT ); + w1 = shl( hStereoDft->NFFT, qw1 - 1 ); + w2 = shl( NFFT, qw2 ); + fac_fx = L_shl( div_s( w1, w2 ), 16 ); + qfac_fx = 31 - ( qw2 - ( qw1 - 1 ) ); + ovl2 = NS2SA( inputFs, STEREO_DFT32MS_OVL2_NS ); + + /* Offset FOR the time buffers */ + assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) ); + mem_size = delay_dec + delay; + + /* Update buffers */ + Copy32( mem_fx, input_buff_fx, mem_size ); + Copy32( input_fx, input_buff_fx + mem_size, input_frame ); + Copy32( input_buff_fx + input_frame, mem_fx, mem_size ); + pInput_buff_fx = input_buff_fx; + + IF( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + pop_wmops(); + return; + } + + + /*-----------------------------------------------------------------* + * DFT Analysis: loop over frame + *-----------------------------------------------------------------*/ + + assert( k_offset <= STEREO_DFT_NBDIV ); + + FOR( i = 0; i < NFFT / 4; i++ ) + { + trigo_dec_fx[i] = trigo_fx[i * trigo_step]; + trigo_dec_fx[NFFT / 2 - i] = trigo_fx[i * trigo_step]; + } + trigo_dec_fx[NFFT / 4] = trigo_fx[NFFT / 4 * trigo_step]; + + FOR( k = 0; k < STEREO_DFT_NBDIV - k_offset; k++ ) + { + set32_fx( DFT_fx, 0, STEREO_DFT32MS_N_MAX ); + IF( k == 0 ) + { + offset = 0; + } + ELSE + { + /* If OVL2 = OVL offset = 10ms */ + offset = NS2SA( inputFs, STEREO_DFT32MS_WIN_CENTER_NS - STEREO_DFT32MS_OVL2_NS / 2 ); + } + + pInput_fx = pInput_buff_fx + offset; + pDFT_out_fx = out_DFT_fx[chan] + k * STEREO_DFT32MS_N_MAX; + + /*Forwards FFT: L and R*/ + /* Zero Padding & Flat Portion */ + Copy32( pInput_fx, DFT_fx + zp, NFFT - 2 * zp ); + + /* Overlapping portions */ + IF( k == 0 ) + { + FOR( i = 0; i < ovl; i++ ) + { + DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win_left_fx[STEREO_DFT32MS_STEP * i] ); + } + FOR( i = 0; i < ovl2; i++ ) + { + DFT_fx[NFFT - zp - 1 - i] = Mpy_32_16_1( DFT_fx[NFFT - zp - 1 - i], win2_fx[i] ); + } + } + ELSE + { + FOR( i = 0; i < ovl2; i++ ) + { + DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win2_fx[i] ); + } + FOR( i = 0; i < ovl; i++ ) + { + DFT_fx[NFFT - zp - i - 1] = Mpy_32_16_1( DFT_fx[NFFT - zp - i - 1], win_right_fx[STEREO_DFT32MS_STEP * i] ); + } + } + Word16 q_DFT, q_shift, guarded_bits; + q_DFT = q; + guarded_bits = find_guarded_bits_fx( NFFT ); + q_shift = L_norm_arr( DFT_fx, NFFT ) - guarded_bits; + + FOR( Word16 j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); + } + + q_DFT += q_shift; + + rfft_fx( DFT_fx, trigo_dec_fx, NFFT, -1 ); + + q_shift = L_norm_arr( DFT_fx, NFFT ) - ( 31 - qfac_fx ); + FOR( Word16 j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); + } + q_DFT += q_shift; + IF( q_out_DFT[chan] - q_DFT > 0 ) + { + FOR( int j = 0; j < NFFT; j++ ) + { + out_DFT_fx[chan][j] = L_shr( out_DFT_fx[chan][j], q_out_DFT[chan] - q_DFT ); + } + q_out_DFT[chan] = q_DFT; + } + ELSE + { + FOR( int j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shr( DFT_fx[j], q_DFT - q_out_DFT[chan] ); + } + q_DFT = q_out_DFT[chan]; + } + + /*Resampling: filtering+scaling*/ + IF( ana_type == DFT_STEREO_DEC_ANA_FB || ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_NOCORE ) + { + pDFT_out_fx[0] = L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), 31 - qfac_fx ); /*DC*/ + IF( NFFT == hStereoDft->NFFT ) /*Nyquist*/ + { + pDFT_out_fx[1] = L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), 31 - qfac_fx ); + } + ELSE + { + pDFT_out_fx[1] = 0; + } + FOR( i = 2; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ); + } + FOR( i = NFFT; i < hStereoDft->NFFT; i++ ) + { + pDFT_out_fx[i] = 0; + } + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + pDFT_out_fx[0] = L_sub( pDFT_out_fx[0], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[0], fac_fx ), dft_bpf_weights_fx[0] ), 32 - qfac_fx ) ); + + FOR( i = 1; i < STEREO_DFT_BPF_SIZE; i++ ) + { + pDFT_out_fx[2 * i] = L_sub( pDFT_out_fx[2 * i], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i], fac_fx ), dft_bpf_weights_fx[i] ), 32 - qfac_fx ) ); + pDFT_out_fx[2 * i + 1] = L_sub( pDFT_out_fx[2 * i + 1], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i + 1], fac_fx ), dft_bpf_weights_fx[i] ), 32 - qfac_fx ) ); + } + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_HB_ADD ) + { + NFFT_core = NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_N_NS ); + + FOR( i = NFFT_core; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[i] ); + } + } + ELSE + { + pDFT_out_fx[0] = L_add( pDFT_out_fx[0], L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), 31 - qfac_fx ) ); /*DC*/ + IF( NFFT == hStereoDft->NFFT ) /*Nyquist*/ + { + pDFT_out_fx[1] = L_add( L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[1] ); + } + FOR( i = 2; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[i] ); + } + } + } + /////////////////////////////////////////////////////// + FOR( int j = 0; j < STEREO_DFT32MS_OVL_16k; j++ ) + hCPE->input_mem_BPF[0][j] = (float) hCPE->input_mem_BPF_fx[0][j] / (float) ( 1 << q ); + FOR( int j = 0; j < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); j++ ) + hCPE->input_mem[0][j] = (float) hCPE->input_mem_fx[0][j] / (float) ( 1 << q ); + FOR( int j = 0; j < STEREO_DFT32MS_OVL_16k; j++ ) + hCPE->input_mem_LB[0][j] = (float) hCPE->input_mem_LB_fx[0][j] / (float) ( 1 << q ); + FOR( int j = 0; j < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); j++ ) + hCPE->input_mem[1][j] = (float) hCPE->input_mem_fx[1][j] / (float) ( 1 << q ); + FOR( int j = 0; j < STEREO_DFT32MS_OVL_16k; j++ ) + hCPE->input_mem_LB[1][j] = (float) hCPE->input_mem_LB_fx[1][j] / (float) ( 1 << q ); + + IF( out_DFT ) + { + FOR( k = 0; k < CPE_CHANNELS; k++ ) + FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) + { + out_DFT[k][j] = (float) out_DFT_fx[k][j] / (float) ( 1 << q_out_DFT[k] ); + } + } + //////////////////////////////////////////////////////////////// + pop_wmops(); + return; +} +void stereo_dft_dec_analyze_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + const Word32 *input_fx, /* i : input signal */ + Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const Word16 chan, /* i : channel number */ + const Word16 input_frame, /* i : input frame size */ + const Word16 output_frame, /* i : output frame size */ + const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : type of signal to analyse */ + const Word16 k_offset, /* i : offset of DFT */ + const Word16 delay, /* i : delay in samples FOR input signal */ + Word16 *q, + Word16 *q_out_DFT ) +{ + + Word16 i, k; + STEREO_DFT_DEC_DATA_HANDLE hStereoDft; + Word32 *pInput_fx, *pInput_buff_fx; + Word32 *mem_fx, input_buff_fx[STEREO_DFT32MS_OVL_MAX + L_FRAME48k]; + Word32 DFT_fx[STEREO_DFT32MS_N_MAX], *pDFT_out_fx; + Word16 NFFT, NFFT_core, ovl, zp; + Word16 offset; + Word32 fac_fx; + const Word16 *trigo_fx, *win_left_fx, *win_right_fx, *win2_fx; + Word16 trigo_dec_fx[STEREO_DFT32MS_N_MAX / 2 + 1]; + Word16 trigo_step; + Word32 inputFs; + Word16 delay_dec; + Word16 mem_size; + Word16 ovl2; + + push_wmops( "DFT_analysis" ); + + hStereoDft = hCPE->hStereoDft; + + assert( output_frame == STEREO_DFT_NBDIV * hStereoDft->N ); + + /*-----------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + IF( input_frame == output_frame ) + { + trigo_fx = hStereoDft->dft_trigo_fx; + trigo_step = hStereoDft->dft_trigo_step * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_fx; + win_left_fx = hStereoDft->win32ms_fx; + win2_fx = hStereoDft->win232ms_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME ) + { + trigo_fx = hStereoDft->dft_trigo_12k8_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_12k8_fx; + win_left_fx = hStereoDft->win32ms_12k8_fx; + win2_fx = hStereoDft->win232ms_12k8_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + assert( ( chan == 1 ) && "12.8kHz sampling rate only FOR second channel, i.e. residual coding or allpass signal" ); + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME16k ) + { + trigo_fx = hStereoDft->dft_trigo_16k_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_16k_fx; + win_left_fx = hStereoDft->win32ms_16k_fx; + win2_fx = hStereoDft->win232ms_16k_fx; + + IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" ); + mem_fx = hCPE->input_mem_BPF_fx[chan]; + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_LB_ADD ) + { + mem_fx = hCPE->input_mem_LB_fx[chan]; + } + ELSE + { + assert( ( chan == 1 ) && hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF && "16kHz sampling rate only FOR second channel with allpass signal" ); + mem_fx = hCPE->input_mem_fx[chan]; + } + } + ELSE IF( input_frame == L_FRAME8k ) + { + assert( ( chan == 1 ) && "DFT stereo: 8kHz analysis only FOR residual coding" ); + trigo_fx = hStereoDft->dft_trigo_8k_fx; + trigo_step = STEREO_DFT_TRIGO_SRATE_8k_STEP * STEREO_DFT_TRIGO_DEC_STEP; + win_right_fx = hStereoDft->win32ms_8k_fx; + win_left_fx = hStereoDft->win32ms_8k_fx; + win2_fx = hStereoDft->win232ms_8k_fx; + mem_fx = hCPE->input_mem_fx[chan]; + } + ELSE + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error in DFT stereo: sampling rate not supported" ); + mem_fx = NULL; /* to avoid compilation warning */ + trigo_fx = NULL; /* to avoid compilation warning */ + trigo_step = -1; /* to avoid compilation warning */ + win_right_fx = NULL; /* to avoid compilation warning */ + win_left_fx = NULL; /* to avoid compilation warning */ + win2_fx = NULL; /* to avoid compilation warning */ + } + + inputFs = input_frame * FRAMES_PER_SEC; + delay_dec = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); + zp = NS2SA( inputFs, STEREO_DFT32MS_ZP_NS ); + ovl = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); + NFFT = NS2SA( inputFs, STEREO_DFT32MS_N_NS ); + Word16 w1, w2, qw1, qw2, qfac_fx; + qw1 = norm_s( hStereoDft->NFFT ); + qw2 = norm_s( NFFT ); + w1 = shl( hStereoDft->NFFT, qw1 - 1 ); + w2 = shl( NFFT, qw2 ); + fac_fx = L_shl( div_s( w1, w2 ), 16 ); + qfac_fx = 31 - ( qw2 - ( qw1 - 1 ) ); + ovl2 = NS2SA( inputFs, STEREO_DFT32MS_OVL2_NS ); + + /* Offset FOR the time buffers */ + assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) ); + mem_size = delay_dec + delay; + + /* Update buffers */ + Copy32( mem_fx, input_buff_fx, mem_size ); + Copy32( input_fx, input_buff_fx + mem_size, input_frame ); + Copy32( input_buff_fx + input_frame, mem_fx, mem_size ); + pInput_buff_fx = input_buff_fx; + + IF( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + pop_wmops(); + return; + } + + + /*-----------------------------------------------------------------* + * DFT Analysis: loop over frame + *-----------------------------------------------------------------*/ + + assert( k_offset <= STEREO_DFT_NBDIV ); + + FOR( i = 0; i < NFFT / 4; i++ ) + { + trigo_dec_fx[i] = trigo_fx[i * trigo_step]; + trigo_dec_fx[NFFT / 2 - i] = trigo_fx[i * trigo_step]; + } + trigo_dec_fx[NFFT / 4] = trigo_fx[NFFT / 4 * trigo_step]; + + FOR( k = 0; k < STEREO_DFT_NBDIV - k_offset; k++ ) + { + set32_fx( DFT_fx, 0, STEREO_DFT32MS_N_MAX ); + IF( k == 0 ) + { + offset = 0; + } + ELSE + { + /* If OVL2 = OVL offset = 10ms */ + offset = NS2SA( inputFs, STEREO_DFT32MS_WIN_CENTER_NS - STEREO_DFT32MS_OVL2_NS / 2 ); + } + + pInput_fx = pInput_buff_fx + offset; + pDFT_out_fx = out_DFT_fx[chan] + k * STEREO_DFT32MS_N_MAX; + + /*Forwards FFT: L and R*/ + /* Zero Padding & Flat Portion */ + Copy32( pInput_fx, DFT_fx + zp, NFFT - 2 * zp ); + + /* Overlapping portions */ + IF( k == 0 ) + { + FOR( i = 0; i < ovl; i++ ) + { + DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win_left_fx[STEREO_DFT32MS_STEP * i] ); + } + FOR( i = 0; i < ovl2; i++ ) + { + DFT_fx[NFFT - zp - 1 - i] = Mpy_32_16_1( DFT_fx[NFFT - zp - 1 - i], win2_fx[i] ); + } + } + ELSE + { + FOR( i = 0; i < ovl2; i++ ) + { + DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win2_fx[i] ); + } + FOR( i = 0; i < ovl; i++ ) + { + DFT_fx[NFFT - zp - i - 1] = Mpy_32_16_1( DFT_fx[NFFT - zp - i - 1], win_right_fx[STEREO_DFT32MS_STEP * i] ); + } + } + Word16 q_DFT, q_shift, guarded_bits; + q_DFT = *q; + guarded_bits = find_guarded_bits_fx( NFFT ); + q_shift = L_norm_arr( DFT_fx, NFFT ) - guarded_bits; + + FOR( Word16 j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); + } + + q_DFT += q_shift; + + rfft_fx( DFT_fx, trigo_dec_fx, NFFT, -1 ); + + q_shift = L_norm_arr( DFT_fx, NFFT ) - ( 31 - qfac_fx ); + FOR( Word16 j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); + } + q_DFT += q_shift; + IF( q_out_DFT[chan] - q_DFT > 0 ) + { + FOR( int j = 0; j < NFFT; j++ ) + { + out_DFT_fx[chan][j] = L_shr( out_DFT_fx[chan][j], q_out_DFT[chan] - q_DFT ); + } + q_out_DFT[chan] = q_DFT; + } + ELSE + { + FOR( int j = 0; j < NFFT; j++ ) + { + DFT_fx[j] = L_shr( DFT_fx[j], q_DFT - q_out_DFT[chan] ); + } + q_DFT = q_out_DFT[chan]; + } + + /*Resampling: filtering+scaling*/ + IF( ana_type == DFT_STEREO_DEC_ANA_FB || ana_type == DFT_STEREO_DEC_ANA_LB || ana_type == DFT_STEREO_DEC_ANA_NOCORE ) + { + pDFT_out_fx[0] = L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), 31 - qfac_fx ); /*DC*/ + IF( NFFT == hStereoDft->NFFT ) /*Nyquist*/ + { + pDFT_out_fx[1] = L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), 31 - qfac_fx ); + } + ELSE + { + pDFT_out_fx[1] = 0; + } + FOR( i = 2; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ); + } + FOR( i = NFFT; i < hStereoDft->NFFT; i++ ) + { + pDFT_out_fx[i] = 0; + } + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_BPF ) + { + pDFT_out_fx[0] = L_sub( pDFT_out_fx[0], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[0], fac_fx ), dft_bpf_weights_fx[0] ), 32 - qfac_fx ) ); + + FOR( i = 1; i < STEREO_DFT_BPF_SIZE; i++ ) + { + pDFT_out_fx[2 * i] = L_sub( pDFT_out_fx[2 * i], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i], fac_fx ), dft_bpf_weights_fx[i] ), 32 - qfac_fx ) ); + pDFT_out_fx[2 * i + 1] = L_sub( pDFT_out_fx[2 * i + 1], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i + 1], fac_fx ), dft_bpf_weights_fx[i] ), 32 - qfac_fx ) ); + } + } + ELSE IF( ana_type == DFT_STEREO_DEC_ANA_HB_ADD ) + { + NFFT_core = NS2SA( hCPE->hCoreCoder[0]->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_N_NS ); + + FOR( i = NFFT_core; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[i] ); + } + } + ELSE + { + pDFT_out_fx[0] = L_add( pDFT_out_fx[0], L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), 31 - qfac_fx ) ); /*DC*/ + IF( NFFT == hStereoDft->NFFT ) /*Nyquist*/ + { + pDFT_out_fx[1] = L_add( L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[1] ); + } + FOR( i = 2; i < NFFT; i++ ) + { + pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), 31 - qfac_fx ), pDFT_out_fx[i] ); + } + } + } + + pop_wmops(); + return; +} +#else void stereo_dft_dec_analyze( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ const float *input, /* i : input signal */ @@ -913,6 +1635,7 @@ void stereo_dft_dec_analyze( pop_wmops(); return; } +#endif /*------------------------------------------------------------------------- * stereo_dft_dec_synthesize() diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec.c index 391398fd0..e4469c9f4 100644 --- a/lib_dec/ivas_stereo_esf_dec.c +++ b/lib_dec/ivas_stereo_esf_dec.c @@ -33,6 +33,7 @@ #include #include "options.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -46,6 +47,9 @@ void init_basic_allpass( basic_allpass_t *ap, const float *gains, +#ifdef IVAS_FLOAT_FIXED + const Word32 *gains_fx, +#endif const int16_t *delays ) { int16_t i, j; @@ -54,10 +58,16 @@ void init_basic_allpass( { ap->gains[i] = gains[i]; ap->delays[i] = delays[i]; +#ifdef IVAS_FLOAT_FIXED + ap->gains_fx[i] = gains_fx[i]; +#endif for ( j = 0; j < STEREO_DFT_ALLPASS_BUFFERLEN; j++ ) { ap->buffer[i][j] = 0.f; +#ifdef IVAS_FLOAT_FIXED + ap->buffer_fx[i][j] = 0; +#endif } } @@ -123,3 +133,81 @@ void filter_with_allpass( return; } + +#ifdef IVAS_FLOAT_FIXED +void filter_with_allpass_fx( + const Word32 *sig, + Word32 *out, + const Word16 len, + basic_allpass_t *ap) +{ + Word16 k; + Word16 pos, mask; + Word16 d1, d2, d3; + Word32 P1_fx, P2_fx, P3_fx, P4_fx, P5_fx; + Word32 g1_fx, g2_fx, g3_fx, *D1_fx, *D2_fx, *D3_fx; + + P1_fx = P2_fx = P3_fx = P4_fx = P5_fx = 0; + mask = STEREO_DFT_ALLPASS_BUFFERLEN - 1; + + pos = ap->pos; + + g1_fx = ap->gains_fx[0]; + g2_fx = ap->gains_fx[1]; + g3_fx = ap->gains_fx[2]; + + d1 = ap->delays[0]; + d2 = ap->delays[1]; + d3 = ap->delays[2]; + + D1_fx = ap->buffer_fx[0]; + D2_fx = ap->buffer_fx[1]; + D3_fx = ap->buffer_fx[2]; + + Word32 D1_upd = pos + d1, D2_upd = pos + d2, D3_upd = pos + d3; + + FOR( k = 0; k <= mask; k++ ) + { + IF( pos == D1_upd ) + D1_upd = -1; + IF( pos == D2_upd ) + D2_upd = -1; + IF( pos == D3_upd ) + D3_upd = -1; + + P1_fx = L_sub( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); + P2_fx = L_sub( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); + P3_fx = L_add( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); + P4_fx = L_add( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); + P5_fx = L_add( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); + out[k] = P5_fx; /* could overwrite sig */ + + D1_fx[( pos + d1 ) & mask] = P2_fx; + D2_fx[( pos + d2 ) & mask] = P3_fx; + D3_fx[( pos + d3 ) & mask] = P4_fx; + + pos = ( pos + 1 ) & mask; + } + + FOR( k = mask + 1; k < len; k++ ) + { + + P1_fx = L_sub( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); + P2_fx = L_sub( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); + P3_fx = L_add( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); + P4_fx = L_add( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); + P5_fx = L_add( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); + out[k] = P5_fx; /* could overwrite sig */ + + D1_fx[( pos + d1 ) & mask] = P2_fx; + D2_fx[( pos + d2 ) & mask] = P3_fx; + D3_fx[( pos + d3 ) & mask] = P4_fx; + + pos = ( pos + 1 ) & mask; + } + + ap->pos = pos; + + return; +} +#endif diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 4ef647a7f..e856f14f3 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -232,10 +232,16 @@ void stereo_tcx_core_dec( if ( st->tcxonly ) { st->p_bpf_noise_buf_float = NULL; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = NULL; +#endif } else { st->p_bpf_noise_buf_float = st->bpf_noise_buf_float; +#ifdef IVAS_FLOAT_FIXED + st->p_bpf_noise_buf_32 = st->bpf_noise_buf_32; +#endif set_s( pitch, L_SUBFR, st->nb_subfr ); set_zero( pit_gain, st->nb_subfr ); } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 934e5727b..21daf233a 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1056,10 +1056,16 @@ typedef struct hq_nbfec_structure typedef struct hq_dec_structure { float old_out[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ +#ifdef IVAS_FLOAT_FIXED + Word32 oldOut_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ +#endif Word16 old_out_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ float old_outLB[L_FRAME32k]; Word16 old_out_LB_fx[L_FRAME32k]; /* HQ core - previous synthesis for OLA for Low Band */ +#ifdef IVAS_FLOAT_FIXED + Word32 old_outLB_fx[L_FRAME32k]; +#endif Word16 Q_old_wtda_LB; Word16 Q_old_wtda; @@ -2457,9 +2463,11 @@ typedef struct Decoder_State float bpf_noise_buf_float[L_FRAME16k]; Word16 bpf_noise_buf[L_FRAME_16k]; + Word32 bpf_noise_buf_32[L_FRAME_16k]; float *p_bpf_noise_buf_float; Word16 *p_bpf_noise_buf; + Word32 *p_bpf_noise_buf_32; int16_t enableGplc; int16_t flagGuidedAcelp; -- GitLab