diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 261ef6f907f1777ec47a9c01f3ff7661b5999b80..e1fe5bc8cd94f4bf739564376181dd8de1577b41 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1395,6 +1395,10 @@ enum #define FDCNG_VQ_DCT_MAXTRUNC 18 #define FDCNG_VQ_MAX_LEN_WB 21 +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 +#define FDCNG_VQ_MAX_LEN_WB1 20 +#endif + #define FDCNG_VQ_DCT_NPOST 8 typedef enum _DCTTYPE @@ -1402,7 +1406,12 @@ typedef enum _DCTTYPE DCT_T2_24_XX = 0, /* truncated DCT_T2_24 */ IDCT_T2_XX_24 = 1, DCT_T2_21_XX = 2, /* truncated DCT_T2_21 */ - IDCT_T2_XX_21 = 3 + IDCT_T2_XX_21 = 3 +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + ,DCT_T2_20_XX = 4, /* truncated DCT_T2_20 */ + IDCT_T2_XX_20 = 5 +#endif + } DCTTYPE; diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index 02a735e80c0baf8914c90526bd7fde29581f5dd8..eb4276cb9af653a74c65a83e11955c5921ef0abb 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -2460,7 +2460,11 @@ void dctT2_N_apply_matrix( mat_step_col = matrix_row_dim; /* matrix maximum storage size dependent, width of first row in matrix */ mat_step_row = 0; mat_step_col_flag = 1; +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + assert( dcttype == DCT_T2_20_XX || dcttype == DCT_T2_21_XX || dcttype == DCT_T2_24_XX ); +#else assert( dcttype == DCT_T2_21_XX || dcttype == DCT_T2_24_XX ); +#endif } else { @@ -2569,6 +2573,14 @@ void create_IDCT_N_Matrix( float *inv_matrixFloatQ, const int16_t N, const int16 idx_ptr = idctT2_21_compressed_idx; len = N; } +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + if ( N == FDCNG_VQ_MAX_LEN_WB1 ) + { + absval_ptr = unique_idctT2_20coeffsQ16; + idx_ptr = idctT2_20_compressed_idx; + len = N; + } +#endif assert( alloc_size >= ( n_cols * len ) ); /* enough space for the full expanded IDCT matrix */ assert( N <= len ); diff --git a/lib_com/options.h b/lib_com/options.h index 9c461d84e6698b8bad3cb76268bd3d7e99636239..06fff26458d0daf5e8777fe9ecccb2297550f1af 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,7 +158,7 @@ #define ERI_MSVQ_CLEANUP /* Eri: Contribution #31 BE modularization of msvq encoder side DCT21&DCT24 within msvq_enc() */ - +#define FIX_443_ERI_MSVQ_CLEANUP_WB1 /*Eri: Contribution 31 ticket #443, added support for fdcng WB1 bandwidth(N==20) used in dyx cond ISM2 at 16.4 kbps (total_rate==4450 <= 8kbps) */ #define FIX_416_ISM_BR_SWITCHING /* FhG: add missing CLDFB reconfig to ISM BR switching */ #define FIX_SP2A /* VA: Issue 412: Adjust threshold for the S_p2a feature in the tonal detector */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 69bcaa6647e5993a78d229b349a279ab79e90b4d..8e7df63db1dfd0f8e984f130ef9a36d27488d229 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8141,7 +8141,10 @@ int16_t msvq_stage1_dct_search( /* o ); int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( - /* o : (updated p_max) */ +/* o : (updated p_max) */ +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + const int16_t n, /*i : original target length */ +#endif const float *st1_syn_vec_ptr, /* i : IDCT24 synthesis vectors */ const float *u, /* i : target signal */ const int16_t maxC_st1, /* i : number of candidates in stage1 */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 9c2b49bca20ed1dfff728ec98f4396c89c2eb7e7..89bd0bd03aaeb1cc26ebc639a8fe41d114ab74b5 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -6140,7 +6140,39 @@ const Word8 idctT2_21_compressed_idx[(FDCNG_VQ_DCT_MAXTRUNC *( (21/2) + 1)) /* }; /*low storage IDCT24x18 table && IDCT21*18 */ - +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 +const Word16 unique_idctT2_20coeffsQ16[21] = { + 0, 1626, 3242, 4838, 6404, 7931, 9409, 10828, + 12181, 13459, 14654, 15759, 16766, 17670, 18465, 19147, + 19710, 20152, 20469, 20660, 20724 +}; + +const Word8 idctT2_20_compressed_idx[(FDCNG_VQ_DCT_MAXTRUNC *( (20/2) )) /* == 180 Word8 */ ] = { + 10, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, + 10, 17, 14, 11, 8, 5, 2, -1, -4, -7, -10, -13, -16, -19, -18, -15, -12, -9, + 10, 15, 10, 5, 0, -5, -10, -15, -20, -15, -10, -5, 0, 5, 10, 15, 20, 15, + 10, 13, 6, -1, -8, -15, -18, -11, -4, 3, 10, 17, 16, 9, 2, -5, -12, -19, + 10, 11, 2, -7, -16, -15, -6, 3, 12, 19, 10, 1, -8, -17, -14, -5, 4, 13, + 10, 9, -2, -13, -16, -5, 6, 17, 12, 1, -10, -19, -8, 3, 14, 15, 4, -7, + 10, 7, -6, -19, -8, 5, 18, 9, -4, -17, -10, 3, 16, 11, -2, -15, -12, 1, + 10, 5, -10, -15, 0, 15, 10, -5, -20, -5, 10, 15, 0, -15, -10, 5, 20, 5, + 10, 3, -14, -9, 8, 15, -2, -19, -4, 13, 10, -7, -16, 1, 18, 5, -12, -11, + 10, 1, -18, -3, 16, 5, -14, -7, 12, 9, -10, -11, 8, 13, -6, -15, 4, 17, + /* + 10, -1, -18, 3, 16, -5, -14, 7, 12, -9, -10, 11, 8, -13, -6, 15, 4, -17, + 10, -3, -14, 9, 8, -15, -2, 19, -4, -13, 10, 7, -16, -1, 18, -5, -12, 11, + 10, -5, -10, 15, 0, -15, 10, 5, -20, 5, 10, -15, 0, 15, -10, -5, 20, -5, + 10, -7, -6, 19, -8, -5, 18, -9, -4, 17, -10, -3, 16, -11, -2, 15, -12, -1, + 10, -9, -2, 13, -16, 5, 6, -17, 12, -1, -10, 19, -8, -3, 14, -15, 4, 7, + 10, -11, 2, 7, -16, 15, -6, -3, 12, -19, 10, -1, -8, 17, -14, 5, 4, -13, + 10, -13, 6, 1, -8, 15, -18, 11, -4, -3, 10, -17, 16, -9, 2, 5, -12, 19, + 10, -15, 10, -5, 0, 5, -10, 15, -20, 15, -10, 5, 0, -5, 10, -15, 20, -15, + 10, -17, 14, -11, 8, -5, 2, 1, -4, 7, -10, 13, -16, 19, -18, 15, -12, 9, + 10, -19, 18, -17, 16, -15, 14, -13, 12, -11, 10, -9, 8, -7, 6, -5, 4, -3 */ +}; + /*low storage IDCT20x18 table */ + +#endif diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index 3ea7a7f4c31c44b1f880993fba2ae854ebff83ae..1d0bdf494bff34a5bf5e9aaad50abd3da93e9302 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -1163,6 +1163,11 @@ extern const Word8 idctT2_24_compressed_idx[]; extern const Word16 unique_idctT2_21coeffsQ16[]; extern const Word8 idctT2_21_compressed_idx[]; +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 +extern const Word16 unique_idctT2_20coeffsQ16[]; +extern const Word8 idctT2_20_compressed_idx[]; +#endif + extern const float idctT2_24_X_matrixFloatQ[]; diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index d71c24d45c0c8a1d04170f0f884658ab2cccbbcf..7859b8f12fd34cf59b6702d49192b6c80a6abff2 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -556,6 +556,21 @@ void FdCng_encodeSID( /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched in FDCNG band domain */ + +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + if ( N == FDCNG_VQ_MAX_LEN_WB1 || N == FDCNG_VQ_MAX_LEN_WB ) + { + DCTTYPE dcttype = ( N == FDCNG_VQ_MAX_LEN_WB1 ) ? DCT_T2_20_XX : DCT_T2_21_XX; + + create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); + /* truncated DCT 20 or DCT 21 analysis */ + dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, dcttype ); + /* truncated IDCT_N extension to 24 bands */ + extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, dcttype + 1 ); + + mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ + } +#else if ( N == FDCNG_VQ_MAX_LEN_WB ) { create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); @@ -566,6 +581,8 @@ void FdCng_encodeSID( mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ } +#endif + create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); msvq_enc( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices ); msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 0f7a798a75a8971530b55965a1ae43a7cb1b5a64..ea3724d25ff36664a041e63775a190542b78350f 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -277,7 +277,10 @@ int16_t msvq_stage1_dct_search( essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1 MSE in the DCT24 domain truncated search, excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep the WB MSEs update for the subsequent stages */ -int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( /* o : (updated p_max) */ +int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( /* o : (updated p_max) */ +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + const int16_t n, /*i : original target length */ +#endif const float *st1_syn_vec_ptr, /* i : IDCT24 synthesis vectors */ const float *u, /* i : target signal */ const int16_t maxC_st1, /* i : number of candidates in stage1 */ @@ -286,20 +289,39 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( { int16_t p_max_local, c; const float *p2; +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB1]; + + assert( n == FDCNG_VQ_MAX_LEN_WB || n == FDCNG_VQ_MAX_LEN_WB1 ); +#else float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB]; +#endif for ( c = 0; c < maxC_st1; c++ ) - { /* point to extended synthesis part */ + { /* point to extended synthesis part */ +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + p2 = (const float *) &( st1_syn_vec_ptr[c * FDCNG_VQ_MAX_LEN + n] ); /* ptr init to synthesis candidate c */ + /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */ + v_sub( p2, &( u[n] ), high_diff, FDCNG_VQ_MAX_LEN - n ); + res24 = dotp( high_diff, high_diff, FDCNG_VQ_MAX_LEN - n ); /* sum squared over top env. values above WB coeffs */ +#else p2 = (const float *) &( st1_syn_vec_ptr[c * FDCNG_VQ_MAX_LEN + FDCNG_VQ_MAX_LEN_WB] ); /* ptr init to synthesis candidate c */ /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */ v_sub( p2, &( u[FDCNG_VQ_MAX_LEN_WB] ), high_diff, FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB ); res24 = dotp( high_diff, high_diff, FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB ); /* sum squared over top env. values above WB coeffs */ +#endif dist_ptr[c] -= res24; /* remove DCT24 high band error contribution */ } + +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 /* finally update p_max, as it may potentially change, + due to the core DCT24 search optimizing over longer basis vectors than DCT (n==20 || n==21 ) */ +#else + /* finally update p_max, as it may potentially change, due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */ +#endif p_max_local = maximum( dist_ptr, maxC_st1, NULL ); return p_max_local; @@ -466,7 +488,11 @@ void msvq_enc( if ( !s && applyDCT_flag != 0 ) /* means: m==1 */ { /* stage 1 candidates search in truncated dct24 domain without any weights */ - assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */ +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB1 || N == FDCNG_VQ_MAX_LEN_WB ); /* 20, 21 and 24 allowed */ +#else + assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */ +#endif assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, @@ -646,8 +672,14 @@ void msvq_enc( indices[1][c * stages] = indices_st1_local[c]; /* move established stage#1 indices to global MSVQ list structure */ } + +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + /* extract the selected stage one vectors in DCT domain , apply IDCT_N and scale up */ + /*always extract full length signal(24) to be able to update WB( N==20 || N==21) candidate MSE values */ +#else /* extract the selected stage one vectors in DCT domain , apply IDCT_N and scale up */ /*always extract full length signal(24) to be able to update WB( N==21) candidate MSE values */ +#endif for ( c = 0; c < maxC_pre; c++ ) { dec_FDCNG_MSVQ_stage1( indices_st1_local[c], FDCNG_VQ_MAX_LEN, invTrfMatrix, dcttype + 1, &( st1_syn_vec_ptr[c * FDCNG_VQ_MAX_LEN] ), NULL ); @@ -661,7 +693,7 @@ void msvq_enc( if ( !s ) /* means: m==1 */ { /* This loop is identical to the one below, except, that the inner - loop over c=0..m is hardcoded to c=0, since m=1. */ + loop over c=0..m is hardcoded to c=0, since m=1. */ /* dist[0][0] */ for ( j = 0; j < levels[s]; j++ ) { @@ -785,10 +817,18 @@ void msvq_enc( excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep WB MSEs update for the subsequent stages */ #ifdef ERI_MSVQ_CLEANUP + +#ifdef FIX_443_ERI_MSVQ_CLEANUP_WB1 + if ( s == 0 && applyDCT_flag != 0 && ( n == FDCNG_VQ_MAX_LEN_WB1 || n == FDCNG_VQ_MAX_LEN_WB ) ) + { + p_max = msvq_stage1_dct_recalc_candidates_fdcng_wb( n, st1_syn_vec_ptr, u, maxC, dist[1] ); + } +#else if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) { p_max = msvq_stage1_dct_recalc_candidates_fdcng_wb( st1_syn_vec_ptr, u, maxC, dist[1] ); } +#endif #else if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) {