diff --git a/lib_com/rom_com_fx.c b/lib_com/rom_com_fx.c index 2497e496f12a96ae115c85cda390c5b7d010fd67..a1465dc53241eb40588803f02f4b2bfa28a7549a 100644 --- a/lib_com/rom_com_fx.c +++ b/lib_com/rom_com_fx.c @@ -6178,3 +6178,456 @@ const Word16 sin_twiddle_table_16_8_2[16] = { SHC( 0x0000 ), SHC( 0xcf05 ), }; + + +/*----------------------------------------------------------------------------------* + * LP analysis windows + *----------------------------------------------------------------------------------*/ + +/* LP analysis window (length of the window is 25 ms which is 320 samples at 12.8kHz (Q15)*/ +const Word16 LP_assym_window_fx[L_LP] = { + 0x0a3d, 0x0a3f, 0x0a45, 0x0a50, 0x0a5f, 0x0a72, 0x0a89, 0x0aa4, + 0x0ac4, 0x0ae8, 0x0b10, 0x0b3c, 0x0b6d, 0x0ba1, 0x0bda, 0x0c17, + 0x0c57, 0x0c9c, 0x0ce5, 0x0d32, 0x0d83, 0x0dd8, 0x0e31, 0x0e8e, + 0x0eef, 0x0f54, 0x0fbd, 0x1029, 0x109a, 0x110e, 0x1185, 0x1201, + 0x1280, 0x1303, 0x1389, 0x1413, 0x14a1, 0x1532, 0x15c6, 0x165e, + 0x16f9, 0x1798, 0x183a, 0x18df, 0x1987, 0x1a32, 0x1ae1, 0x1b92, + 0x1c47, 0x1cfe, 0x1db8, 0x1e75, 0x1f35, 0x1ff8, 0x20bd, 0x2185, + 0x224f, 0x231c, 0x23ec, 0x24bd, 0x2592, 0x2668, 0x2740, 0x281b, + 0x28f8, 0x29d7, 0x2ab8, 0x2b9a, 0x2c7f, 0x2d65, 0x2e4d, 0x2f37, + 0x3022, 0x310f, 0x31fd, 0x32ec, 0x33dd, 0x34cf, 0x35c2, 0x36b7, + 0x37ac, 0x38a3, 0x399a, 0x3a92, 0x3b8b, 0x3c84, 0x3d7e, 0x3e79, + 0x3f74, 0x4070, 0x416c, 0x4268, 0x4364, 0x4461, 0x455d, 0x465a, + 0x4756, 0x4853, 0x494f, 0x4a4a, 0x4b46, 0x4c41, 0x4d3b, 0x4e35, + 0x4f2e, 0x5027, 0x511e, 0x5215, 0x530b, 0x5400, 0x54f4, 0x55e6, + 0x56d8, 0x57c8, 0x58b7, 0x59a4, 0x5a90, 0x5b7b, 0x5c64, 0x5d4b, + 0x5e30, 0x5f14, 0x5ff5, 0x60d5, 0x61b3, 0x628f, 0x6369, 0x6440, + 0x6515, 0x65e8, 0x66b9, 0x6787, 0x6853, 0x691c, 0x69e2, 0x6aa6, + 0x6b68, 0x6c26, 0x6ce2, 0x6d9b, 0x6e50, 0x6f03, 0x6fb3, 0x7060, + 0x710a, 0x71b1, 0x7254, 0x72f4, 0x7391, 0x742b, 0x74c1, 0x7554, + 0x75e3, 0x766f, 0x76f7, 0x777b, 0x77fc, 0x787a, 0x78f3, 0x7969, + 0x79dc, 0x7a4a, 0x7ab5, 0x7b1b, 0x7b7e, 0x7bdd, 0x7c38, 0x7c8f, + 0x7ce2, 0x7d31, 0x7d7c, 0x7dc3, 0x7e06, 0x7e45, 0x7e80, 0x7eb6, + 0x7ee9, 0x7f17, 0x7f41, 0x7f67, 0x7f89, 0x7fa6, 0x7fc0, 0x7fd5, + 0x7fe6, 0x7ff2, 0x7ffb, 0x7fff, 0x7ffe, 0x7ff6, 0x7fe5, 0x7fcb, + 0x7fa8, 0x7f7e, 0x7f4a, 0x7f0e, 0x7eca, 0x7e7d, 0x7e28, 0x7dca, + 0x7d64, 0x7cf6, 0x7c80, 0x7c02, 0x7b7b, 0x7aed, 0x7a57, 0x79b9, + 0x7914, 0x7866, 0x77b2, 0x76f6, 0x7632, 0x7568, 0x7496, 0x73be, + 0x72de, 0x71f8, 0x710c, 0x7019, 0x6f20, 0x6e20, 0x6d1b, 0x6c10, + 0x6aff, 0x69e8, 0x68cd, 0x67ab, 0x6685, 0x655a, 0x642b, 0x62f7, + 0x61be, 0x6081, 0x5f40, 0x5dfc, 0x5cb4, 0x5b68, 0x5a19, 0x58c7, + 0x5772, 0x561b, 0x54c1, 0x5365, 0x5206, 0x50a6, 0x4f44, 0x4de1, + 0x4c7c, 0x4b16, 0x49af, 0x4848, 0x46e0, 0x4578, 0x4410, 0x42a8, + 0x4141, 0x3fda, 0x3e73, 0x3d0e, 0x3baa, 0x3a47, 0x38e6, 0x3787, + 0x3629, 0x34ce, 0x3376, 0x321f, 0x30cc, 0x2f7b, 0x2e2e, 0x2ce4, + 0x2b9e, 0x2a5b, 0x291c, 0x27e2, 0x26ab, 0x2579, 0x244c, 0x2323, + 0x2200, 0x20e1, 0x1fc8, 0x1eb4, 0x1da6, 0x1c9e, 0x1b9c, 0x1a9f, + 0x19a9, 0x18b9, 0x17d0, 0x16ed, 0x1612, 0x153c, 0x146e, 0x13a7, + 0x12e8, 0x122f, 0x117e, 0x10d5, 0x1033, 0x0f99, 0x0f07, 0x0e7d, + 0x0dfa, 0x0d80, 0x0d0e, 0x0ca4, 0x0c42, 0x0be9, 0x0b98, 0x0b4f, + 0x0b0f, 0x0ad8, 0x0aa8, 0x0a82, 0x0a64, 0x0a4e, 0x0a41, 0x0a3d +}; + +/* LP analysis window (length of the window is 25ms which is 400 samples at 16kHz (Q15) */ +const Word16 LP_assym_window_16k_fx[L_LP_16k] = { + 0x0a3d, + 0x0a3e, + 0x0a42, + 0x0a49, + 0x0a53, + 0x0a5f, + 0x0a6e, + 0x0a7f, + 0x0a93, + 0x0aaa, + 0x0ac4, + 0x0ae0, + 0x0aff, + 0x0b21, + 0x0b45, + 0x0b6c, + 0x0b96, + 0x0bc2, + 0x0bf1, + 0x0c23, + 0x0c57, + 0x0c8e, + 0x0cc7, + 0x0d03, + 0x0d41, + 0x0d82, + 0x0dc6, + 0x0e0c, + 0x0e55, + 0x0ea0, + 0x0eee, + 0x0f3e, + 0x0f91, + 0x0fe6, + 0x103e, + 0x1098, + 0x10f4, + 0x1153, + 0x11b4, + 0x1218, + 0x127e, + 0x12e6, + 0x1351, + 0x13be, + 0x142d, + 0x149e, + 0x1512, + 0x1588, + 0x1600, + 0x167a, + 0x16f6, + 0x1774, + 0x17f5, + 0x1878, + 0x18fc, + 0x1983, + 0x1a0c, + 0x1a96, + 0x1b23, + 0x1bb1, + 0x1c42, + 0x1cd4, + 0x1d68, + 0x1dfe, + 0x1e96, + 0x1f30, + 0x1fcb, + 0x2068, + 0x2107, + 0x21a7, + 0x2249, + 0x22ed, + 0x2392, + 0x2439, + 0x24e1, + 0x258b, + 0x2636, + 0x26e2, + 0x2790, + 0x2840, + 0x28f0, + 0x29a2, + 0x2a56, + 0x2b0a, + 0x2bc0, + 0x2c77, + 0x2d2e, + 0x2de7, + 0x2ea2, + 0x2f5d, + 0x3019, + 0x30d6, + 0x3194, + 0x3253, + 0x3313, + 0x33d3, + 0x3495, + 0x3557, + 0x361a, + 0x36dd, + 0x37a2, + 0x3867, + 0x392c, + 0x39f2, + 0x3ab9, + 0x3b80, + 0x3c47, + 0x3d0f, + 0x3dd7, + 0x3ea0, + 0x3f68, + 0x4032, + 0x40fb, + 0x41c4, + 0x428e, + 0x4358, + 0x4422, + 0x44ec, + 0x45b6, + 0x4680, + 0x4749, + 0x4813, + 0x48dd, + 0x49a6, + 0x4a6f, + 0x4b38, + 0x4c01, + 0x4cca, + 0x4d92, + 0x4e59, + 0x4f20, + 0x4fe7, + 0x50ad, + 0x5173, + 0x5238, + 0x52fd, + 0x53c1, + 0x5484, + 0x5547, + 0x5608, + 0x56c9, + 0x578a, + 0x5849, + 0x5908, + 0x59c5, + 0x5a82, + 0x5b3d, + 0x5bf8, + 0x5cb2, + 0x5d6a, + 0x5e21, + 0x5ed8, + 0x5f8d, + 0x6041, + 0x60f3, + 0x61a5, + 0x6255, + 0x6303, + 0x63b0, + 0x645c, + 0x6507, + 0x65b0, + 0x6657, + 0x66fd, + 0x67a2, + 0x6844, + 0x68e6, + 0x6985, + 0x6a23, + 0x6abf, + 0x6b5a, + 0x6bf2, + 0x6c89, + 0x6d1e, + 0x6db2, + 0x6e43, + 0x6ed2, + 0x6f60, + 0x6fec, + 0x7075, + 0x70fd, + 0x7183, + 0x7206, + 0x7288, + 0x7307, + 0x7385, + 0x7400, + 0x7479, + 0x74f0, + 0x7565, + 0x75d7, + 0x7648, + 0x76b6, + 0x7721, + 0x778b, + 0x77f2, + 0x7857, + 0x78b9, + 0x7919, + 0x7977, + 0x79d2, + 0x7a2b, + 0x7a81, + 0x7ad5, + 0x7b27, + 0x7b76, + 0x7bc2, + 0x7c0c, + 0x7c54, + 0x7c98, + 0x7cdb, + 0x7d1b, + 0x7d58, + 0x7d93, + 0x7dcb, + 0x7e00, + 0x7e33, + 0x7e63, + 0x7e91, + 0x7ebc, + 0x7ee4, + 0x7f0a, + 0x7f2d, + 0x7f4d, + 0x7f6b, + 0x7f86, + 0x7f9e, + 0x7fb3, + 0x7fc6, + 0x7fd7, + 0x7fe4, + 0x7fef, + 0x7ff7, + 0x7ffc, + 0x7fff, + 0x7fff, + 0x7ff9, + 0x7fee, + 0x7fde, + 0x7fc8, + 0x7fac, + 0x7f8c, + 0x7f65, + 0x7f39, + 0x7f08, + 0x7ed1, + 0x7e95, + 0x7e54, + 0x7e0d, + 0x7dc1, + 0x7d70, + 0x7d19, + 0x7cbd, + 0x7c5c, + 0x7bf6, + 0x7b8b, + 0x7b1b, + 0x7aa5, + 0x7a2b, + 0x79ab, + 0x7927, + 0x789e, + 0x7810, + 0x777d, + 0x76e6, + 0x764a, + 0x75a9, + 0x7504, + 0x745a, + 0x73ac, + 0x72fa, + 0x7243, + 0x7188, + 0x70c9, + 0x7006, + 0x6f3f, + 0x6e74, + 0x6da5, + 0x6cd2, + 0x6bfc, + 0x6b22, + 0x6a44, + 0x6963, + 0x687f, + 0x6797, + 0x66ac, + 0x65be, + 0x64cd, + 0x63d9, + 0x62e2, + 0x61e8, + 0x60ec, + 0x5fed, + 0x5eeb, + 0x5de7, + 0x5ce1, + 0x5bd8, + 0x5ace, + 0x59c1, + 0x58b3, + 0x57a2, + 0x5690, + 0x557c, + 0x5467, + 0x5350, + 0x5238, + 0x511f, + 0x5005, + 0x4ee9, + 0x4dcd, + 0x4cb0, + 0x4b92, + 0x4a74, + 0x4955, + 0x4836, + 0x4716, + 0x45f6, + 0x44d6, + 0x43b6, + 0x4297, + 0x4177, + 0x4058, + 0x3f39, + 0x3e1b, + 0x3cfe, + 0x3be1, + 0x3ac5, + 0x39aa, + 0x3891, + 0x3778, + 0x3661, + 0x354b, + 0x3436, + 0x3323, + 0x3212, + 0x3102, + 0x2ff5, + 0x2ee9, + 0x2de0, + 0x2cd8, + 0x2bd3, + 0x2ad0, + 0x29d0, + 0x28d2, + 0x27d7, + 0x26df, + 0x25e9, + 0x24f7, + 0x2407, + 0x231a, + 0x2231, + 0x214b, + 0x2068, + 0x1f89, + 0x1ead, + 0x1dd5, + 0x1d00, + 0x1c2f, + 0x1b62, + 0x1a99, + 0x19d4, + 0x1913, + 0x1856, + 0x179d, + 0x16e9, + 0x1638, + 0x158d, + 0x14e5, + 0x1442, + 0x13a4, + 0x130a, + 0x1275, + 0x11e5, + 0x1159, + 0x10d3, + 0x1051, + 0x0fd4, + 0x0f5c, + 0x0ee9, + 0x0e7b, + 0x0e12, + 0x0daf, + 0x0d50, + 0x0cf7, + 0x0ca3, + 0x0c55, + 0x0c0b, + 0x0bc7, + 0x0b88, + 0x0b4f, + 0x0b1b, + 0x0aed, + 0x0ac3, + 0x0aa0, + 0x0a82, + 0x0a69, + 0x0a56, + 0x0a48, + 0x0a40, + 0x0a3d, +}; diff --git a/lib_com/rom_com_fx.h b/lib_com/rom_com_fx.h index ac6a0ef466454b142454964902582182753984c7..01ef473c4f641352268f2fdb045bf2e33f83ce48 100644 --- a/lib_com/rom_com_fx.h +++ b/lib_com/rom_com_fx.h @@ -111,4 +111,7 @@ extern const Word32 rot_vec_ana_im_L40_fx[20]; extern const Word32 rot_vec_ana_re_L60_fx[30]; extern const Word32 rot_vec_ana_im_L60_fx[30]; +extern const Word16 LP_assym_window_fx[]; /* Assymetric window for LP analysis @12.8kHz (Q15) */ +extern const Word16 LP_assym_window_16k_fx[]; /* Assymetric window for LP analysis @16kHz (Q15) */ + #endif diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 76ca272563883c67527e209332787b1bbea15eb1..9c8ade511abc14cdec0293e05edf727c7e4ca041 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -43,6 +43,7 @@ #ifdef IVAS_FLOAT_FIXED #include "prot_fx.h" #include "prot_fx_enc.h" +#include "rom_com_fx.h" #endif /*-------------------------------------------------------------------* @@ -235,12 +236,30 @@ void stereo_tcx_core_enc( const int16_t vad_hover_flag /* i : VAD hangover flag */ ) { +#ifdef IVAS_FLOAT_FIXED + Word32 pitch_buf_fx[NB_SUBFR16k]; /* 15Q16 */ + + // Convert gamma to fixed point. + if ( (Word16) ( st->gamma_flt * 100 ) == 92 ) + { + st->gamma = GAMMA1; + st->inv_gamma = GAMMA1_INV; + } + else if ( (Word16) ( st->gamma_flt * 100 ) == 94 ) + { + st->gamma = GAMMA16k; + st->inv_gamma = GAMMA16k_INV; + } +#endif + #ifdef IVAS_FLOAT_FIXED TCX_ENC_HANDLE hTcxEnc; Word16 i, n; + Word16 tmp1, tmp2; /*size and windowing*/ const float *p_new_samples; + Word16 q_ind_val; Word16 n_subframes; Word16 last_core_orig; @@ -258,11 +277,15 @@ void stereo_tcx_core_enc( Word16 bits_param_lpc[10], no_param_lpc; /*LPC*/ - float lsf_q[M], lsp_q[M], lsp[M], lsf[M]; + float lsf_q[M], lsp_q[M], lsf[M]; + Word16 lsp_q_fx[M]; float lspmid_q[M]; + Word16 lspmid_q_fx[M]; float A_q[M + 1]; + Word16 A_q_fx[M + 1]; float gainlpc[2][FDNS_NPTS]; float lsp_tcx_q[M], lsf_tcx_q[M]; + // Word16 lsp_tcx_q_fx[M], lsf_tcx_q_fx[M]; int16_t tcx_lpc_cdk; Word16 A_q_ind[M + 1]; /*for LPC-based AC*/ Word16 lspq_ind[M]; /*for LPC-based AC*/ @@ -357,6 +380,88 @@ void stereo_tcx_core_enc( // T_op[i] = (int16_t)(T_op[i] * (float)st->L_frame / (float)L_FRAME + 0.5f); } } + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + move16(); + p_new_samples = new_samples_12k8; + } + ELSE + { + p_new_samples = new_samples_16k; + move16(); + } + + /*--------------------------------------------------------------* + * TCX20/TCX10 switching decision + *---------------------------------------------------------------*/ + + IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) + { + st->core = TCX_10_CORE; + move16(); + n_subframes = 2; + move16(); + test(); + IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, HALF_OVERLAP ) || EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) + { + nbits_header = add( nbits_header, 2 ); + } + ELSE + { + nbits_header = add( nbits_header, 1 ); + } + } + ELSE IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) + { + st->core = TCX_20_CORE; + move16(); + n_subframes = 1; + move16(); + } + + nbits_start = hBstr->nb_bits_tot; + move16(); + + /*--------------------------------------------------------------------------------* + * Write TCX signaling + *--------------------------------------------------------------------------------*/ + + /* TCX20/TCX10 and coder type */ + writeTCXMode( st, hBstr, 0, /* MCT_flag */ &nbits_start ); + + /* write last_core for error concealment */ + q_ind_val = 0; + move16(); + test(); + IF( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) + { + q_ind_val = 1; + move16(); + } + push_next_indice( hBstr, q_ind_val, 1 ); + + /* write TCX overlap mode (1 bit: full, 2 bits: half or no overlap) */ + writeTCXWindowing( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); + IF( EQ_16( st->core, TCX_10_CORE ) ) + { + writeTCXWindowing( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); + } + + assert( nbits_header == ( hBstr->nb_bits_tot - nbits_start ) ); + + /*--------------------------------------------------------------* + * Core Signal Analysis: MDCT, TNS, LPC analysis + *---------------------------------------------------------------*/ + + /* TODO: integrate this. */ + core_signal_analysis_high_bitrate( p_new_samples, T_op, lsp_new, lsp_mid, st, NULL, tnsSize, tnsBits, param_core, <pBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag ); + + bitsAvailable = sub( st->bits_frame_core, nbits_header ); + IF( st->igf ) + { + bitsAvailable = sub( bitsAvailable, st->hIGFEnc->infoTotalBitsWritten ); + } #else TCX_ENC_HANDLE hTcxEnc; int16_t i, n; @@ -461,7 +566,6 @@ void stereo_tcx_core_enc( T_op[i] = (int16_t) ( T_op[i] * (float) st->L_frame / (float) L_FRAME + 0.5f ); } } -#endif if ( st->L_frame == L_FRAME ) { @@ -524,15 +628,26 @@ void stereo_tcx_core_enc( /*--------------------------------------------------------------* * Envelope Quantization and FDNS *---------------------------------------------------------------*/ +#endif if ( !st->enableTcxLpc ) { +#ifdef IVAS_FLOAT_FIXED + IF( st->envWeighted ) + { + /* Unweight the envelope */ + E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); + st->envWeighted = 0; + move16(); + } +#else if ( st->envWeighted ) { /* Unweight the envelope */ E_LPC_lsp_unweight_float( st->lsp_old, st->lsp_old, st->lsf_old, 1.0f / st->gamma_flt ); st->envWeighted = 0; } +#endif lpc_quantization( st, lsp_new, lsp_mid, lsp_q, lsf_q, lspmid_q, AUDIO, 0, /*No acelp->no need to compute any mid-LPC*/ param_lpc, nbits_lpc, bits_param_lpc, &no_param_lpc ); @@ -548,7 +663,12 @@ void stereo_tcx_core_enc( } } +#ifdef IVAS_FLOAT_FIXED + last_core_orig = st->last_core; + move16(); +#else last_core_orig = st->last_core; +#endif for ( n = 0; n < n_subframes; n++ ) { /* Get the envelope */ @@ -560,6 +680,31 @@ void stereo_tcx_core_enc( tcx_lpc_cdk = tcxlpc_get_cdk_float( st->hTcxCfg->coder_type ); #endif +#ifdef IVAS_FLOAT_FIXED0 /* High MLD if this is enabled. */ + // Float to fix + for ( int j = 0; j < M; j++ ) + { + lsp_new_fx[j] = float_to_fix16( lsp_new[j], Q15 ); + st->lspold_enc_fx[j] = float_to_fix16( st->lspold_enc[j], Q15 ); + } + st->gamma = float_to_fix16( st->gamma_flt, Q15 ); + + /* Get the envelope corresponding to the current frame */ + E_LPC_int_lpc_tcx( st->lspold_enc_fx, lsp_new_fx, A_q_fx ); + + /* Weight the envelope */ + weight_a_fx( A_q_fx, A_q_fx, st->gamma, M ); + + /* Convert to lsp and lsf */ + E_LPC_a_lsp_conversion( A_q_fx, lsp_fx, lsp_new_fx, M ); + + E_LPC_lsp_lsf_conversion( lsp_fx, lsf_fx, M ); + + for ( int j = 0; j < M; j++ ) + { + lsf[j] = (float) lsf_fx[j] / 2.56f; + } +#else /* Get the envelope corresponding to the current frame */ E_LPC_int_lpc_tcx_float( st->lspold_enc, lsp_new, A_q ); @@ -567,36 +712,119 @@ void stereo_tcx_core_enc( weight_a( A_q, A_q, st->gamma_flt, M ); /* Convert to lsp and lsf */ + float lsp[M]; a2lsp_stab( A_q, lsp, lsp_new ); lsp2lsf( lsp, lsf, M, INT_FS_12k8 ); +#endif /* Quantize */ Q_lsf_tcxlpc( lsf, lsf_tcx_q, lspq_ind, param_lpc, st->narrowBand, tcx_lpc_cdk, st->mem_MA, st->hTcxCfg->coder_type, st->Bin_E ); +#ifdef IVAS_FLOAT_FIXED + /* Account for consumed bits */ + nbits_lpc[0] = TCXLPC_NUMBITS; + if ( param_lpc[0] ) + { + nbits_lpc[0] += TCXLPC_IND_NUMBITS; + } +#else /* Account for consumed bits */ nbits_lpc[0] = TCXLPC_NUMBITS; if ( param_lpc[0] ) { nbits_lpc[0] += TCXLPC_IND_NUMBITS; } +#endif +#ifdef IVAS_FLOAT_FIXED0 /* High MLD if this is enabled. */ + /* Convert quantized lsf to lsp and A */ + for ( int j = 0; j < M; j++ ) + { + lsf_tcx_q_fx[j] = (Word16) ( lsf_tcx_q[j] * 2.56f ); + } + E_LPC_lsf_lsp_conversion( lsf_tcx_q_fx, lsp_tcx_q_fx, M ); + for ( int j = 0; j < M; j++ ) + { + lsp_tcx_q[j] = fix16_to_float( lsp_tcx_q_fx[j], Q15 ); + } + E_LPC_f_lsp_a_conversion( lsp_tcx_q_fx, A_q_fx, M ); + for ( int j = 0; j < M + 1; j++ ) + { + A_q[j] = fix16_to_float( A_q_fx[j], Q14 - norm_s( A_q_fx[0] ) ); + } +#else /* Convert quantized lsf to lsp and A */ lsf2lsp( lsf_tcx_q, lsp_tcx_q, M, INT_FS_12k8 ); lsp2a_stab( lsp_tcx_q, A_q, M ); +#endif +#ifdef IVAS_FLOAT_FIXED0 /* High MLD if this is enabled. */ + for ( int j = 0; j < M + 1; j++ ) + { + A_q_fx[j] = (Word16) ( A_q[j] / A_q[0] * ONE_IN_Q12 ); + A_q[j] = (float) A_q_fx[j] / A_q_fx[0]; + } +#endif } else if ( !st->tcxonly ) { E_LPC_int_lpc_tcx_float( st->lsp_old, lsp_q, A_q ); + +#ifdef IVAS_FLOAT_FIXED0 /* High MLD if this is enabled. */ + for ( int j = 0; j < M + 1; j++ ) + { + A_q_fx[j] = (Word16) ( A_q[j] / A_q[0] * ONE_IN_Q12 ); + A_q[j] = (float) A_q_fx[j] / A_q_fx[0]; + } +#endif } else if ( n + 2 == n_subframes ) /* First TCX10/5 subframe */ { +#ifdef IVAS_FLOAT_FIXED + for ( int j = 0; j < M; j++ ) + { + lspmid_q_fx[j] = float_to_fix16( lspmid_q[j], Q15 ); + } + E_LPC_f_lsp_a_conversion( lspmid_q_fx, A_q_fx, M ); + for ( int j = 0; j < M + 1; j++ ) + { + A_q[j] = fix16_to_float( A_q_fx[j], Q14 - norm_s( A_q_fx[0] ) ); + } +#else lsp2a_stab( lspmid_q, A_q, M ); +#endif } else { +#ifdef IVAS_FLOAT_FIXED + for ( int j = 0; j < M; j++ ) + { + lsp_q_fx[j] = float_to_fix16( lsp_q[j], Q15 ); + } + E_LPC_f_lsp_a_conversion( lsp_q_fx, A_q_fx, M ); + for ( int j = 0; j < M + 1; j++ ) + { + A_q[j] = fix16_to_float( A_q_fx[j], Q14 - norm_s( A_q_fx[0] ) ); + } +#else lsp2a_stab( lsp_q, A_q, M ); +#endif + } + +#ifdef IVAS_FLOAT_FIXED + IF( hTcxEnc->tcx_lpc_shaped_ari ) + { + basop_E_LPC_f_lsp_a_conversion( lspq_ind, A_q_ind, M ); } + bitsAvailable = sub( bitsAvailable, nbits_lpc[n] ); + + /* Shape spectrum */ + /* TODO: integrate this. */ + ShapeSpectrum( st->hTcxCfg, A_q, gainlpc[n], st->L_frame / n_subframes, st->hTcxCfg->tcx_coded_lines / n_subframes, hTcxEnc->spectrum[n], hTcxEnc->fUseTns[n], st, NULL ); + + st->last_core = st->core; + move16(); +#else if ( hTcxEnc->tcx_lpc_shaped_ari ) { basop_E_LPC_f_lsp_a_conversion( lspq_ind, A_q_ind, M ); @@ -608,8 +836,63 @@ void stereo_tcx_core_enc( ShapeSpectrum( st->hTcxCfg, A_q, gainlpc[n], st->L_frame / n_subframes, st->hTcxCfg->tcx_coded_lines / n_subframes, hTcxEnc->spectrum[n], hTcxEnc->fUseTns[n], st, NULL ); st->last_core = st->core; +#endif + } + +#ifdef IVAS_FLOAT_FIXED + st->last_core = last_core_orig; + move16(); + + /*--------------------------------------------------------------------------------* + * Write LPC parameters + *--------------------------------------------------------------------------------*/ + + writeLPCparam( st, hBstr, param_lpc, bits_param_lpc, no_param_lpc, &total_nbbits ); + + assert( total_nbbits == ( nbits_lpc[0] + nbits_lpc[1] ) ); + + /*--------------------------------------------------------------* + * Run TCX10/20 Core + *---------------------------------------------------------------*/ + + hTcxEnc->measuredBwRatio = ONE_IN_Q14; + move16(); + + FOR( n = 0; n < n_subframes; n++ ) + { + target_bits[n] = sub( idiv1616( add( bitsAvailable, sub( sub( n_subframes, 1 ), n ) ), n_subframes ), tnsBits[n] ); + move16(); + + test(); + IF( st->enablePlcWaveadjust && EQ_16( n, sub( n_subframes, 1 ) ) ) + { + target_bits[n] = sub( target_bits[n], 1 ); + move16(); + } + IF( n == 0 ) + { + target_bits[n] = sub( target_bits[n], ltpBits ); + move16(); + } + + /* Run TCX20/10 encoder */ + tmp1 = imult1616( n, st->L_frame ); + IF( tmp1 != 0 ) + { + tmp1 = idiv1616( tmp1, n_subframes ); + } + tmp2 = imult1616( n, NPRM_DIV ); + /* TODO: integrate this. */ + QuantizeSpectrum( st, A_q, A_q_ind, gainlpc[n], st->synth_flt + tmp1, target_bits[n], tnsSize[n], param_core + tmp2, n, &hm_cfg[n], vad_hover_flag ); } + /* Update tcx overlap mode */ + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + + // Fix to float + hTcxEnc->measuredBwRatio_flt = fix16_to_float( hTcxEnc->measuredBwRatio, Q14 ); +#else st->last_core = last_core_orig; /*--------------------------------------------------------------------------------* @@ -645,13 +928,34 @@ void stereo_tcx_core_enc( /* Update tcx overlap mode */ st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; +#endif coder_tcx_post( st, A_q, Aw ); +#ifdef IVAS_FLOAT_FIXED + IF( st->enableTcxLpc ) + { + // Float to fixed + Word16 lsp_tcx_q_fx[M]; + Word16 lsf_q_fx[M]; + for ( int j = 0; j < M; j++ ) + { + lsp_tcx_q_fx[j] = float_to_fix16( lsp_tcx_q[j], Q15 ); + } + E_LPC_lsp_unweight( lsp_tcx_q_fx, lsp_q_fx, lsf_q_fx, st->inv_gamma, M ); /* Update lsf_q for encoderSideLossSimulation() */ + // Fixed to float + for ( int j = 0; j < M; j++ ) + { + lsp_q[j] = fix16_to_float( lsp_q_fx[j], Q15 ); + lsf_q[j] = (float) lsf_q_fx[j] / 2.56f; + } + } +#else if ( st->enableTcxLpc ) { E_LPC_lsp_unweight_float( lsp_tcx_q, lsp_q, lsf_q, 1.0f / st->gamma_flt ); /* Update lsf_q for encoderSideLossSimulation() */ } +#endif /* Update lsp/lsf memory */ if ( st->enableTcxLpc && st->core != ACELP_CORE ) @@ -675,6 +979,120 @@ void stereo_tcx_core_enc( mvr2r( lsp_q, st->lsp_old, M ); } + +#ifdef IVAS_FLOAT_FIXED + // Float to fixed + Word16 Q_exc, exp_exc; + f2me_buf_16( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, &exp_exc, L_EXC_MEM ); + Q_exc = 15 - exp_exc; + floatToFixed_arr( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, Q_exc, L_EXC_MEM ); + floatToFixed_arr( st->lsp_old16k, st->lsp_old16k_fx, Q15, M ); + IF( st->hTdCngEnc != NULL ) + { + floatToFixed_arrL( st->hTdCngEnc->ho_ener_circ, st->hTdCngEnc->ho_ener_circ_fx, Q6, HO_HIST_SIZE ); + floatToFixed_arr( st->hTdCngEnc->ho_lsp_circ, st->hTdCngEnc->ho_lsp_circ_fx, Q15, HO_HIST_SIZE * M ); + floatToFixed_arrL( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); + floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); + st->hTdCngEnc->lp_ener_fx = float_to_fix( st->hTdCngEnc->lp_ener, Q6 ); + } + IF( st->hDtxEnc != NULL ) + { + floatToFixed_arr( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG_fx, Q15, M ); + } + + Word16 lsp_new_fx_arr[M]; + Word16 *lsp_new_fx = &lsp_new_fx_arr[0]; + floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); + st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); +#endif + +#ifdef IVAS_FLOAT_FIXED + test(); + test(); + IF( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) + { + /* update CNG parameters in active frames */ + test(); + test(); + IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && NE_16( st->core, ACELP_CORE ) ) + { + Word16 buf_fx[L_LP], res_fx[L_FRAME], A_fx[M + 1], tmp_fx, lsptmp_fx[M]; + Word32 A_fx32[M + 1], r_fx[M + 1]; + Word16 Q_r; + + assert( st->L_frame == L_FRAME ); + + Copy( st->synth + L_FRAME - L_LP, buf_fx, L_LP ); + tmp_fx = st->synth[L_FRAME - L_LP - 1]; + move16(); + preemph_copy_fx( buf_fx, buf_fx, st->preemph_fac, L_LP, &tmp_fx ); + autocorr_fx_32( buf_fx, M, r_fx, &Q_r, L_LP, LP_assym_window_fx, 0, 0 ); + lag_wind_32( r_fx, M, INT_FS_12k8, LAGW_WEAK ); + lev_dur_fx( A_fx32, r_fx, M, NULL, Q12, Q_r ); + FOR( Word16 j = 0; j < M; j++ ) + { + A_fx[j] = extract_l( A_fx32[j] ); + } + E_LPC_a_lsp_conversion( A_fx, lsptmp_fx, lsp_new_fx, M ); + Residu3_fx( A_fx, buf_fx + L_LP - L_FRAME, res_fx, L_FRAME, 0 ); + + cng_params_upd_ivas_fx( lsptmp_fx, res_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, + st->hTdCngEnc->ho_lsp_circ_fx, Q_r, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hFdCngEnc->hFdCngCom->CngBandwidth ); + Q_exc = Q_r; + move16(); + } + ELSE + { + cng_params_upd_ivas_fx( lsp_new_fx, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, + st->hTdCngEnc->ho_lsp_circ_fx, Q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hFdCngEnc->hFdCngCom->CngBandwidth ); + } + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + /* store LSPs@16k, potentially to be used in CNG@16k */ + Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); + } + + /* Set 16k LSP flag for CNG buffer */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 0; + move16(); + } + ELSE + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 1; + move16(); + } + + /* efficient DTX hangover control */ + IF( GT_16( st->hTdCngEnc->burst_ho_cnt, 1 ) ) + { + dtx_hangover_control_fx( st, lsp_new_fx ); + } + } + + /*--------------------------------------------------------------------------------* + * Encode TCX20/10 parameters + *--------------------------------------------------------------------------------*/ + + /* TODO: convert this function */ + writeTCXparam( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, add( nbits_lpc[0], nbits_lpc[1] ), NULL, NULL, NULL, -1 ); + + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + + IF( NE_16( param_core[1 + NOISE_FILL_RANGES], 0 ) ) + { + Word32 tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxEnc->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxEnc->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /* 15Q16 */ + set32_fx( pitch_buf_fx, tcxltp_pitch_tmp, NB_SUBFR16k ); + } + ELSE + { + set32_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q16, NB_SUBFR16k ); + } +#else if ( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) { /* update CNG parameters in active frames */ @@ -691,7 +1109,6 @@ void stereo_tcx_core_enc( lag_wind_flt( r, M, INT_FS_12k8, LAGW_WEAK ); lev_dur( A, r, M, NULL ); a2lsp_stab( A, lsptmp, lsp_new ); - residu( A, M, buf + L_LP - L_FRAME, res, L_FRAME ); cng_params_upd( lsptmp, res, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ, &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ, ENC, st->hTdCngEnc->ho_env_circ, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); @@ -717,7 +1134,6 @@ void stereo_tcx_core_enc( } } - /*--------------------------------------------------------------------------------* * Encode TCX20/10 parameters *--------------------------------------------------------------------------------*/ @@ -726,7 +1142,6 @@ void stereo_tcx_core_enc( total_nbbits = hBstr->nb_bits_tot - nbits_start; - if ( param_core[1 + NOISE_FILL_RANGES] != 0 ) { set_f( pitch_buf, hTcxEnc->tcxltp_pitch_int + (float) hTcxEnc->tcxltp_pitch_fr / (float) st->pit_res_max, NB_SUBFR16k ); @@ -735,6 +1150,23 @@ void stereo_tcx_core_enc( { set_f( pitch_buf, L_SUBFR, NB_SUBFR16k ); } +#endif + +#ifdef IVAS_FLOAT_FIXED + // Fixed to float + for ( int j = 0; j < NB_SUBFR16k; j++ ) + { + pitch_buf[j] = fix_to_float( pitch_buf_fx[j], Q16 ); + } + IF( st->hTdCngEnc != NULL ) + { + fixedToFloat_arrL( st->hTdCngEnc->ho_ener_circ_fx, st->hTdCngEnc->ho_ener_circ, Q6, HO_HIST_SIZE ); + fixedToFloat_arr( st->hTdCngEnc->ho_lsp_circ_fx, st->hTdCngEnc->ho_lsp_circ, Q15, HO_HIST_SIZE * M ); + fixedToFloat_arrL( st->hTdCngEnc->ho_env_circ_fx, st->hTdCngEnc->ho_env_circ, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); + fixedToFloat_arr( st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_exc2_buf_flt, Q_exc, HO_HIST_SIZE * L_FFT ); + fixedToFloat_arr( st->hTdCngEnc->ho_lsp_circ2_fx, st->hTdCngEnc->ho_lsp_circ2, M, Q15 ); + } +#endif pop_wmops(); return;