From 03d98545ac74bcbe5502471c38d4e5b2968679c8 Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Tue, 25 Apr 2023 19:37:45 +0200 Subject: [PATCH 01/10] initial functional split within MSVQ encoder function --- lib_com/options.h | 3 + lib_enc/lsf_msvq_ma_enc.c | 274 +++++++++++++++++++++++++++++++++++++- 2 files changed, 270 insertions(+), 7 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 91f2a1ad72..60dea0b66f 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,6 +158,9 @@ #define ERI_FDCNGVQ_LOW_ROM /* Eri: Contribution #31 Table ROM saving for IVAS FDCNG-VQ modes */ +#define ERI_MSVQ_CLEANUP /* Eri: BE modularization of msvq encoder side DCT c-code */ + + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 190f4e2a74..9acfd70e96 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -53,6 +53,235 @@ #include "ivas_prot.h" void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); + +#ifdef ERI_MSVQ_CLEANUP + + + +int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ + const int16_t maxC_st1, /* i : number of candidates to provide */ + + float *invTrfMatrix, /* i/o: IDCT synthesis matrix for dim N */ + + float *st1_mse_ptr, /* i : dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /* o: selecetd cand indices */ + float *st1_syn_vec_ptr , /* i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /* o: resulting stage 1 MSEs in DCT24 domain */ + ) + +{ /* stage 1 search in truncated dct domain without any weights */ + + float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; + float u_mr[FDCNG_VQ_MAX_LEN]; + float u_mr_scaled[FDCNG_VQ_MAX_LEN]; + float mse_trunc_segm[FDCNG_VQ_DCT_NSEGM]; + float tmp, check_mse; + float mse; /* Word32 */ + + int16_t p_max,c,c2, segm, j_full,j,i ; + int16_t n_ana, p_mins[2], idx_min[2]; + + const Word8 *cbpW8; + const Word16 *dct_col_shift_tab; + + float *st1_mse_pair; + int16_t *st1_idx_pair; + + DCTTYPE dcttype = DCT_T2_24_XX; + float tmp2; + int16_t check_ind[FDCNG_VQ_DCT_NPOST]; + + n_ana = N; /* VQ stage#1 core is currentlu always using stored DCT24 coeffs */ + assert( n_ana >= FDCNG_VQ_DCT_MAXTRUNC ); /* check for FDCNGVQ WB , SWB, FB operation */ + + /*remove mean/mid fdcng stage#1 vector, in original subband domain */ + v_sub( u, cdk1r_tr_midQ_truncQ, u_mr, n_ana ); + + v_multc( u_mr, fdcng_dct_invScaleF[1], u_mr_scaled, n_ana ); /*scale up target to upscaled W8x storage domain */ + /* 16.0-->scale up from Q0 to search domain in Q4, not really needed in BASOP , impl. by shifts */ + + dctT2_N_apply_matrix( (const float *) u_mr_scaled, dct_target, min( FDCNG_VQ_DCT_MAXTRUNC, n_ana ), n_ana, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, dcttype ); + + mse = 0; + /* init search state ptr's at the top */ + set_f( dist1_ptr, FLT_MAX, maxC_st1); + st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ + for ( segm = 0; segm < FDCNG_VQ_DCT_NSEGM; segm++ ) + { + /* point to a new paired location for each segment */ + st1_mse_pair += 2; /* req. ptr init +=2 */ + st1_idx_pair += 2 ; /* req. ptr init +=2 */ + p_max = 0; /* req. to point to 1 or 0 */ + + /* compute segment common trunction error in dctN domain */ + mse_trunc_segm[segm] = 0; + mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cdk1_ivas_cols_per_segment[segm]] ) ), cdk1_ivas_trunc_dct_cols_per_segment[segm] ); + + cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage*/ + + for ( j = 0; j < cdk1_ivas_entries_per_segment[segm]; j++ ) + { + /* unweighted segmented search DCT domain loop */ + j_full = j + cdk1_ivas_cum_entries_per_segment[segm]; /* or simply use j_full++ */ + + mse = mse_trunc_segm[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ + + dct_col_shift_tab = stage1_dct_col_syn_shift[segm]; /* ptr init */ + + for ( c2 = 0; c2 < cdk1_ivas_cols_per_segment[segm]; c2++ ) + { + +#define WMC_TOOL_SKIP + tmp = dct_target[c2] - (float) ( ( (Word16) cbpW8[c2] ) << dct_col_shift_tab[c2] ); /* Word8 storage MSE inner loop */ + LOGIC( 1 ); + SHIFT( 1 ); + ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/ +#undef WMC_TOOL_SKIP + + mse += tmp * tmp; /* L_mac or L_mac0() square Word16 -> Word32*/ + } + st1_mse_ptr[j_full] = mse; /* save MSE in shared dynamic RAM, move32() in BASOP */ + +#define WMC_TOOL_SKIP + cbpW8 += cdk1_ivas_cols_per_segment[segm]; /* fixed pointer increment for each segment */ +#undef WMC_TOOL_SKIP + + /* overwrite with a new worst index at p_max */ +#ifdef ERI_FDCNGVQ_LOW_ROM + /* The three inner loop if's below are not really properly instrumented by WMC tool */ + /* a ptr to worst index will be in use */ +#endif + if ( mse < st1_mse_pair[p_max] ) /* L_sub */ + { + st1_idx_pair[p_max] = j_full; /* simplified */ + } /* BASOP 2 ops */ + + if ( st1_idx_pair[p_max] == j_full ) /* simplified */ + { /* idx updated to j_full --> also update mse */ + st1_mse_pair[p_max] = mse; /* move32(), single BASOP */ + } /* BASOP 3 ops */ + + /* avoid WC costly list management by always updating p_max, as we have only a pair to maintain */ + p_max = 0; /* move16() */ + if ( ( st1_mse_pair[0] - st1_mse_pair[1] ) < 0 ) /* L_sub()*/ + { + p_max = 1; /* move16() */ + } /* BASOP 3 ops ,Note 2 ops possible in BASOP with L_sub and L_lshr */ + + /* Note: logical shift right not available in ANSI-C */ + /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */ + /* in java logical shift right is available as >>> , in BASOP it is L_lshr */ + + /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */ + } /* j in section */ + + } /* next segment */ + + for ( j = 0; j < maxC_st1; j++ ) + { + /* compute_full mse using stored DCT24 domain MSE's */ + /* calculate MSE from stage1 inner using existing inner DCT domain variables */ + dist1_ptr[j] *= fdcng_dct_scaleF[2]; /* single multiplication to get the MSE scale to the correct input domain */ + } + + p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish current worst candidate for stage#2 among all maxC_st1 candidates */ + + p_mins[0] = minimum( dist1_ptr, maxC_st1, NULL ); /* find best entry among all maxC_pre */ + tmp = dist1_ptr[p_mins[0]]; + dist1_ptr[p_mins[0]] = FLT_MAX; /* exclude 1st */ + + p_mins[1] = minimum( dist1_ptr, maxC_st1, NULL ); /* find 2nd best entry */ + tmp2 = dist1_ptr[p_mins[1]]; + dist1_ptr[p_mins[1]] = FLT_MAX; /* exclude 2nd */ + + dist1_ptr[p_mins[0]] = tmp; /* restore 1st */ + dist1_ptr[p_mins[1]] = tmp2; /* restore 2nd */ + + idx_min[0] = indices_st1_local[p_mins[0]]; + idx_min[1] = indices_st1_local[p_mins[1]]; + + + /* use global exclusion list to never reselect the two (best) MSE values sofar */ + st1_mse_ptr[idx_min[0]] = FLT_MAX; /* move32() */ + st1_mse_ptr[idx_min[1]] = FLT_MAX; /* move32() */ + + /* circular MSE-neigbour list in use to potentially replace some segment search candidates */ + /* using both 1st and 2nd best neighbours in fwd and rev directions */ + check_ind[0] = cdk1_ivas_segm_neighbour_fwd[idx_min[0]]; + check_ind[1] = cdk1_ivas_segm_neighbour_rev[idx_min[0]]; + + check_ind[2] = cdk1_ivas_segm_neighbour_fwd[idx_min[1]]; + check_ind[3] = cdk1_ivas_segm_neighbour_rev[idx_min[1]]; + + check_ind[4] = cdk1_ivas_segm_neighbour_fwd[check_ind[0]]; + check_ind[5] = cdk1_ivas_segm_neighbour_rev[check_ind[1]]; + + check_ind[6] = cdk1_ivas_segm_neighbour_fwd[check_ind[2]]; + check_ind[FDCNG_VQ_DCT_NPOST-1] = cdk1_ivas_segm_neighbour_rev[check_ind[3]]; + + for ( i = 0; i < FDCNG_VQ_DCT_NPOST; i++ ) + { + /* move MSE from search to synthesis domain */ + /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */ + check_mse = st1_mse_ptr[check_ind[i]] * fdcng_dct_scaleF[2]; + + if ( check_mse < dist1_ptr[p_max] ) + { /* new winner , replace */ + dist1_ptr[p_max] = check_mse; + indices_st1_local[p_max] = check_ind[i]; + st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */ + p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */ + } + } + + /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */ + /* always extract full length signal(24) to be able to update WB( N==21) candidate MSE values */ + /* in the case that only a part of the IDCT vector is in final use */ + for ( c = 0; c < maxC_st1; c++ ) + { + dec_FDCNG_MSVQ_stage1( indices_st1_local[c], N, invTrfMatrix, dcttype + 1, &( st1_syn_vec_ptr[c * N] ), NULL ); + } + + return p_max; +}; + + +/* recalc MSE for WB(0..20) coeffs , + 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_wb( /* o : (updated p_max) */ + 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 */ + float *dist_ptr /* i/o: updated MSE vector for stage1 */ +) +{ + int16_t p_max_local, c; + const float *p2; + float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB]; + + for ( c = 0; c < maxC_st1; c++ ) + { /* point to extended synthesis part */ + 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 */ + + dist_ptr[c] -= res24; /* remove DCT24 high band error contribution */ + } + + /* finally update p_max, as it may potentially change, + due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */ + p_max_local = maximum( dist_ptr, maxC_st1, NULL ); + + return p_max_local; +}; +#endif + #endif /*--------------------------------------------------------------------------* @@ -87,9 +316,8 @@ void msvq_enc( float resid_buf[2 * LSFMBEST_MAX * M_MAX], dist_buf[2 * LSFMBEST_MAX], Tmp[M_MAX]; int16_t idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; int16_t n, maxn, start; - - #ifdef ERI_FDCNGVQ_LOW_ROM +#ifndef ERI_MSVQ_CLEANUP /* buffers */ float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; float u_mr[FDCNG_VQ_MAX_LEN]; @@ -110,20 +338,28 @@ void msvq_enc( int16_t check_ind[FDCNG_VQ_DCT_NPOST]; int16_t segm, j_full, maxC_pre; - float *st1_syn_vec_ptr; /* 8* 24 floats in dynRAM */ - float *st1_mse_ptr; /* 2^¨7 == 128 floats in existing dRAM used for stage 1 candidate analysis, 128 Word32 in BASOP */ + #endif + float *st1_syn_vec_ptr; /* ptr to buffer in dynRAM */ + float *st1_mse_ptr; /* ptr to buffer in existing dRAM used for stage 1 candidate analysis */ + #ifdef ERI_MSVQ_CLEANUP + int16_t indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2]; /* after stage#1 DCT search this is copied to the global indices[1][s*stages] structure */ +#else float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB]; - maxC_pre = ( FDCNG_VQ_DCT_NSEGM * 2 ); +#endif assert( maxC <= LSFMBEST_MAX ); assert( ( LSFMBEST_MAX * M_MAX ) > ( N * maxC ) ); /* top of resid_buf is resid[1] and used for stage#1 residuals (input target u), - we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs + we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs */ st1_mse_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] ); /* reuse top of residual resid[0] scratch RAM for stage1 MSEs */ + st1_syn_vec_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC; /* reuse top of resid[0] scratch RAM for residual */ +#ifndef ERI_MSVQ_CLEANUP dcttype = DCT_T2_24_XX; +#endif + #endif /*----------------------------------------------------------------* @@ -209,6 +445,22 @@ void msvq_enc( } #ifdef ERI_FDCNGVQ_LOW_ROM + +#ifdef ERI_MSVQ_CLEANUP + 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 ); + assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); + p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, invTrfMatrix, st1_mse_ptr, indices_st1_local, st1_syn_vec_ptr, dist[1] ); + + /* move established stage#1 indices to the global MSVQ list structure */ + for ( c = 0; c < maxC; c++ ) + { + indices[1][c * stages] = indices_st1_local[c]; + } + } +#else if ( !s && applyDCT_flag != 0 ) /* means: m==1 */ { /* stage 1 search in truncated dct domain without any weights */ @@ -263,7 +515,7 @@ void msvq_enc( mse += tmp * tmp; /* L_mac or L_mac0() square Word16 -> Word32*/ } - st1_mse_ptr[j_full] = mse; /* save MSE in shared dynamic 2^7=128 RAM, move32() in BASOP */ + st1_mse_ptr[j_full] = mse; /* save MSE in shared dynamic 2^7=128 RAM, move32() in BASOP */ #define WMC_TOOL_SKIP cbpW8 += cdk1_ivas_cols_per_segment[segm]; /* pointer increment */ @@ -370,6 +622,7 @@ void msvq_enc( assert( maxC == maxC_pre ); } +#endif else /* non-DCT Stage #1 code below */ #endif @@ -512,6 +765,12 @@ void msvq_enc( 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 WB MSEs update for the subsequent stages */ +#ifdef ERI_MSVQ_CLEANUP + if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) + { + p_max = msvq_stage1_dct_recalc_candidates_wb( st1_syn_vec_ptr, u, maxC, dist[1] ); + } +#else if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) { assert( start == 0 ); @@ -527,6 +786,7 @@ void msvq_enc( /* update p_max, as it may potentially change, due to the core DCT24 search originally optimizing over longer basis vectors than 21 */ p_max = maximum( dist[1], maxC, NULL ); } +#endif #endif m = maxC; } /* for (m=1, s=0; s Date: Thu, 4 May 2023 15:37:50 +0200 Subject: [PATCH 02/10] modularized msvq_enc stage1 dct code shoud be BE --- lib_com/lsf_tools.c | 6 +- lib_com/options.h | 3 +- lib_enc/lsf_msvq_ma_enc.c | 232 +++++++++++++++++++++++--------------- 3 files changed, 143 insertions(+), 98 deletions(-) diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index 5f0916dbd1..51562d9461 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -2060,14 +2060,14 @@ void dec_FDCNG_MSVQ_stage1( assert( j < cdk1_ivas_entries_per_segment[segm_ind] ); /* Word8 column variable Qx storage*/ - cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */ - cbpW8 += j * cdk1_ivas_cols_per_segment[segm_ind]; /* adaptive ptr init */ + cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */ + cbpW8 += j * cdk1_ivas_cols_per_segment[segm_ind]; /* adaptive ptr init */ dct_col_shift_tab = stage1_dct_col_syn_shift[segm_ind]; for ( col = 0; col < cdk1_ivas_cols_per_segment[segm_ind]; col++ ) { dct_vec[col] = (float) ( ( (Word16) cbpW8[col] ) << dct_col_shift_tab[col] ); - /* LOGIC( 1 );SHIFT( 1 ); ADD( 1 ); + /* LOGIC( 1 ); SHIFT( 1 ); ADD( 1 ); in BASOP: s_and(for W8->W16), shl(), sub() */ } diff --git a/lib_com/options.h b/lib_com/options.h index 60dea0b66f..1a6bafe685 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -158,7 +158,8 @@ #define ERI_FDCNGVQ_LOW_ROM /* Eri: Contribution #31 Table ROM saving for IVAS FDCNG-VQ modes */ -#define ERI_MSVQ_CLEANUP /* Eri: BE modularization of msvq encoder side DCT c-code */ +#define ERI_MSVQ_CLEANUP /* Eri: BE modularization, mainly for future BASOP of msvq encoder side DCT21&DCT24 c-code */ + /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 9acfd70e96..95ea385436 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -56,115 +56,132 @@ void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_ #ifdef ERI_MSVQ_CLEANUP - - -int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ - const float *u, /* i : target */ - const int16_t N, /* i : target length and IDCT synthesis length */ - const int16_t maxC_st1, /* i : number of candidates to provide */ - - float *invTrfMatrix, /* i/o: IDCT synthesis matrix for dim N */ - - float *st1_mse_ptr, /* i : dynRAM buffer for MSEs */ - int16_t *indices_st1_local, /* o: selecetd cand indices */ - float *st1_syn_vec_ptr , /* i/o: buffer for IDCT24 synthesis */ - float *dist1_ptr /* o: resulting stage 1 MSEs in DCT24 domain */ - ) +int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ + + /* parameterization of segmented DCT domain storage */ + const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ + + const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ + const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ + float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + + const float *midQ_truncQ, /* i: midQ vector */ + const float *dct_invScaleF, /* i: global inv scale factors*/ + const float *dct_scaleF, /* i: global scale factors*/ + const Word16 n_segm, /* i: number of segments */ + const Word16 *cols_per_segment, /* i: remaining length per segment */ + const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ + const Word16 *entries_per_segment, /* i: number of rows per segment */ + const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ + + const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ + const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ + const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ + const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ + const Word16 npost_check, /*i: number of neigbours to check , should be even */ + + float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /*o: selected cand indices */ + float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ +) -{ /* stage 1 search in truncated dct domain without any weights */ +{ /* stage1 search in a segmentwise truncated dctN domain without weights */ float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; float u_mr[FDCNG_VQ_MAX_LEN]; float u_mr_scaled[FDCNG_VQ_MAX_LEN]; float mse_trunc_segm[FDCNG_VQ_DCT_NSEGM]; float tmp, check_mse; - float mse; /* Word32 */ + float mse; /* Word32 in BASOP */ - int16_t p_max,c,c2, segm, j_full,j,i ; + int16_t p_max, c, c2, segm, j_full, j, i; int16_t n_ana, p_mins[2], idx_min[2]; const Word8 *cbpW8; const Word16 *dct_col_shift_tab; float *st1_mse_pair; - int16_t *st1_idx_pair; + int16_t *st1_idx_pair; - DCTTYPE dcttype = DCT_T2_24_XX; float tmp2; int16_t check_ind[FDCNG_VQ_DCT_NPOST]; - - n_ana = N; /* VQ stage#1 core is currentlu always using stored DCT24 coeffs */ - assert( n_ana >= FDCNG_VQ_DCT_MAXTRUNC ); /* check for FDCNGVQ WB , SWB, FB operation */ + assert( ( npost_check % 2 == 0 ) && ( npost_check <= FDCNG_VQ_DCT_NPOST ) ); + + assert( n_segm <= FDCNG_VQ_DCT_NSEGM ); + + n_ana = N; /* VQ stage#1 core is currently always using stored DCT N coeffs */ + assert( n_ana >= max_dct_trunc ); /* check for FDCNGVQ WB , SWB, FB operation */ - /*remove mean/mid fdcng stage#1 vector, in original subband domain */ - v_sub( u, cdk1r_tr_midQ_truncQ, u_mr, n_ana ); + /* remove mid stage#1 vector, in original input domain */ + v_sub( u, midQ_truncQ, u_mr, n_ana ); - v_multc( u_mr, fdcng_dct_invScaleF[1], u_mr_scaled, n_ana ); /*scale up target to upscaled W8x storage domain */ + v_multc( u_mr, dct_invScaleF[1], u_mr_scaled, n_ana ); /* scale up target to upscaled W8x storage domain */ /* 16.0-->scale up from Q0 to search domain in Q4, not really needed in BASOP , impl. by shifts */ - dctT2_N_apply_matrix( (const float *) u_mr_scaled, dct_target, min( FDCNG_VQ_DCT_MAXTRUNC, n_ana ), n_ana, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, dcttype ); + dctT2_N_apply_matrix( (const float *) u_mr_scaled, dct_target, min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix, max_dct_trunc, dcttype ); mse = 0; /* init search state ptr's at the top */ - set_f( dist1_ptr, FLT_MAX, maxC_st1); - st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ - st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ - for ( segm = 0; segm < FDCNG_VQ_DCT_NSEGM; segm++ ) + set_f( dist1_ptr, FLT_MAX, maxC_st1 ); + st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ + + for ( segm = 0; segm < n_segm; segm++ ) { /* point to a new paired location for each segment */ - st1_mse_pair += 2; /* req. ptr init +=2 */ - st1_idx_pair += 2 ; /* req. ptr init +=2 */ - p_max = 0; /* req. to point to 1 or 0 */ + st1_mse_pair += 2; /* req. ptr init +=2 */ + st1_idx_pair += 2; /* req. ptr init +=2 */ + p_max = 0; /* req. to point to one of 1 or 0 , this init can potentially be omitted here as p_max is always 1 or 0 */ /* compute segment common trunction error in dctN domain */ mse_trunc_segm[segm] = 0; - mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cdk1_ivas_cols_per_segment[segm]] ) ), cdk1_ivas_trunc_dct_cols_per_segment[segm] ); + mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] ); - cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage*/ + cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */ - for ( j = 0; j < cdk1_ivas_entries_per_segment[segm]; j++ ) + for ( j = 0; j < entries_per_segment[segm]; j++ ) { /* unweighted segmented search DCT domain loop */ - j_full = j + cdk1_ivas_cum_entries_per_segment[segm]; /* or simply use j_full++ */ + j_full = j + cum_entries_per_segment[segm]; /* or simply use j_full++ */ mse = mse_trunc_segm[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ - dct_col_shift_tab = stage1_dct_col_syn_shift[segm]; /* ptr init */ + dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */ - for ( c2 = 0; c2 < cdk1_ivas_cols_per_segment[segm]; c2++ ) + for ( c2 = 0; c2 < cols_per_segment[segm]; c2++ ) { - #define WMC_TOOL_SKIP tmp = dct_target[c2] - (float) ( ( (Word16) cbpW8[c2] ) << dct_col_shift_tab[c2] ); /* Word8 storage MSE inner loop */ LOGIC( 1 ); SHIFT( 1 ); ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/ #undef WMC_TOOL_SKIP - mse += tmp * tmp; /* L_mac or L_mac0() square Word16 -> Word32*/ } st1_mse_ptr[j_full] = mse; /* save MSE in shared dynamic RAM, move32() in BASOP */ #define WMC_TOOL_SKIP - cbpW8 += cdk1_ivas_cols_per_segment[segm]; /* fixed pointer increment for each segment */ + cbpW8 += cols_per_segment[segm]; /* fixed pointer increment for each segment */ #undef WMC_TOOL_SKIP /* overwrite with a new worst index at p_max */ -#ifdef ERI_FDCNGVQ_LOW_ROM - /* The three inner loop if's below are not really properly instrumented by WMC tool */ - /* a ptr to worst index will be in use */ -#endif + + /* Note: The three inner loop if's below are not 100% properly instrumented by WMC tool */ if ( mse < st1_mse_pair[p_max] ) /* L_sub */ { - st1_idx_pair[p_max] = j_full; /* simplified */ + st1_idx_pair[p_max] = j_full; /* move16, single BASOP */ } /* BASOP 2 ops */ - if ( st1_idx_pair[p_max] == j_full ) /* simplified */ - { /* idx updated to j_full --> also update mse */ - st1_mse_pair[p_max] = mse; /* move32(), single BASOP */ - } /* BASOP 3 ops */ + if ( st1_idx_pair[p_max] == j_full ) + { /* idx updated --> also update mse */ + st1_mse_pair[p_max] = mse; /* move32(), single BASOP */ + } /* BASOP 3 ops */ - /* avoid WC costly list management by always updating p_max, as we have only a pair to maintain */ + /* avoid WC costly candidate list management by always updating p_max, + as we have only a pair in each segment to maintain */ p_max = 0; /* move16() */ if ( ( st1_mse_pair[0] - st1_mse_pair[1] ) < 0 ) /* L_sub()*/ { @@ -173,7 +190,7 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candi /* Note: logical shift right not available in ANSI-C */ /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */ - /* in java logical shift right is available as >>> , in BASOP it is L_lshr */ + /* in java logical shift right is available as >>> , in BASOP it is available as L_lshr */ /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */ } /* j in section */ @@ -184,10 +201,13 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candi { /* compute_full mse using stored DCT24 domain MSE's */ /* calculate MSE from stage1 inner using existing inner DCT domain variables */ - dist1_ptr[j] *= fdcng_dct_scaleF[2]; /* single multiplication to get the MSE scale to the correct input domain */ + dist1_ptr[j] *= dct_scaleF[2]; /* multiplication to get the DCT inner MSE scale to the correct input domain */ } - p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish current worst candidate for stage#2 among all maxC_st1 candidates */ + assert( (maxC_st1 >= 3) ); + assert( (maxC_st1 <= 8) ); + + p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish current worst candidate for MSVQ stage#2 among all maxC_st1 candidates so far */ p_mins[0] = minimum( dist1_ptr, maxC_st1, NULL ); /* find best entry among all maxC_pre */ tmp = dist1_ptr[p_mins[0]]; @@ -195,7 +215,7 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candi p_mins[1] = minimum( dist1_ptr, maxC_st1, NULL ); /* find 2nd best entry */ tmp2 = dist1_ptr[p_mins[1]]; - dist1_ptr[p_mins[1]] = FLT_MAX; /* exclude 2nd */ + dist1_ptr[p_mins[1]] = FLT_MAX; /* exclude 2nd */ dist1_ptr[p_mins[0]] = tmp; /* restore 1st */ dist1_ptr[p_mins[1]] = tmp2; /* restore 2nd */ @@ -204,56 +224,61 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candi idx_min[1] = indices_st1_local[p_mins[1]]; - /* use global exclusion list to never reselect the two (best) MSE values sofar */ + /* use global exclusion list to never reselect the two (best) global MSE values sofar */ st1_mse_ptr[idx_min[0]] = FLT_MAX; /* move32() */ st1_mse_ptr[idx_min[1]] = FLT_MAX; /* move32() */ - /* circular MSE-neigbour list in use to potentially replace some segment search candidates */ + /* circular MSE-neigbour list in use to potentially replace some segment search candidates */ /* using both 1st and 2nd best neighbours in fwd and rev directions */ - check_ind[0] = cdk1_ivas_segm_neighbour_fwd[idx_min[0]]; - check_ind[1] = cdk1_ivas_segm_neighbour_rev[idx_min[0]]; + check_ind[0] = segm_neighbour_fwd[idx_min[0]]; + check_ind[1] = segm_neighbour_rev[idx_min[0]]; - check_ind[2] = cdk1_ivas_segm_neighbour_fwd[idx_min[1]]; - check_ind[3] = cdk1_ivas_segm_neighbour_rev[idx_min[1]]; + check_ind[2] = segm_neighbour_fwd[idx_min[1]]; + check_ind[3] = segm_neighbour_rev[idx_min[1]]; - check_ind[4] = cdk1_ivas_segm_neighbour_fwd[check_ind[0]]; - check_ind[5] = cdk1_ivas_segm_neighbour_rev[check_ind[1]]; + check_ind[4] = segm_neighbour_fwd[check_ind[0]]; + check_ind[5] = segm_neighbour_rev[check_ind[1]]; - check_ind[6] = cdk1_ivas_segm_neighbour_fwd[check_ind[2]]; - check_ind[FDCNG_VQ_DCT_NPOST-1] = cdk1_ivas_segm_neighbour_rev[check_ind[3]]; + check_ind[6] = segm_neighbour_fwd[check_ind[2]]; + check_ind[FDCNG_VQ_DCT_NPOST - 1] = segm_neighbour_rev[check_ind[3]]; - for ( i = 0; i < FDCNG_VQ_DCT_NPOST; i++ ) + for ( i = 0; i < npost_check; i++ ) { - /* move MSE from search to synthesis domain */ - /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */ - check_mse = st1_mse_ptr[check_ind[i]] * fdcng_dct_scaleF[2]; - + /* move MSE from DCT-inner loop search to input synthesis domain */ + /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */ + check_mse = st1_mse_ptr[check_ind[i]] * dct_scaleF[2]; + if ( check_mse < dist1_ptr[p_max] ) - { /* new winner , replace */ - dist1_ptr[p_max] = check_mse; - indices_st1_local[p_max] = check_ind[i]; - st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */ - p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */ + { /* new winner , replace worst */ + dist1_ptr[p_max] = check_mse; + indices_st1_local[p_max] = check_ind[i]; + st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */ + p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */ } } /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */ - /* always extract full length signal(24) to be able to update WB( N==21) candidate MSE values */ - /* in the case that only a part of the IDCT vector is in final use */ - for ( c = 0; c < maxC_st1; c++ ) + /* always extract full length signal(e.g. 24) to be able to update WB(e.g. N_in==21) candidate MSE values */ + /* in the case that only a part of the IDCTN vector is in final use */ + + /* synthesis not yet fully parameterized/generalized for other IDCT lengths */ + assert( N == 24 ); { - dec_FDCNG_MSVQ_stage1( indices_st1_local[c], N, invTrfMatrix, dcttype + 1, &( st1_syn_vec_ptr[c * N] ), NULL ); + for ( c = 0; c < maxC_st1; c++ ) + { + dec_FDCNG_MSVQ_stage1( indices_st1_local[c], N, invTrfMatrix, dcttype + 1, &( st1_syn_vec_ptr[c * N] ), NULL ); + } } - return p_max; + return p_max; /*ptr to worst performing candidate */ }; -/* recalc MSE for WB(0..20) coeffs , +/* recalc MSE for fdcng WB(0..20) coeffs , 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_wb( /* o : (updated p_max) */ +int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( /* o : (updated p_max) */ 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 */ @@ -317,7 +342,7 @@ void msvq_enc( int16_t idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; int16_t n, maxn, start; #ifdef ERI_FDCNGVQ_LOW_ROM -#ifndef ERI_MSVQ_CLEANUP +#ifndef ERI_MSVQ_CLEANUP /* buffers */ float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; float u_mr[FDCNG_VQ_MAX_LEN]; @@ -338,12 +363,12 @@ void msvq_enc( int16_t check_ind[FDCNG_VQ_DCT_NPOST]; int16_t segm, j_full, maxC_pre; - #endif +#endif float *st1_syn_vec_ptr; /* ptr to buffer in dynRAM */ float *st1_mse_ptr; /* ptr to buffer in existing dRAM used for stage 1 candidate analysis */ - #ifdef ERI_MSVQ_CLEANUP +#ifdef ERI_MSVQ_CLEANUP int16_t indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2]; /* after stage#1 DCT search this is copied to the global indices[1][s*stages] structure */ -#else +#else float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB]; maxC_pre = ( FDCNG_VQ_DCT_NSEGM * 2 ); #endif @@ -352,13 +377,13 @@ void msvq_enc( /* top of resid_buf is resid[1] and used for stage#1 residuals (input target u), we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs */ - st1_mse_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] ); /* reuse top of residual resid[0] scratch RAM for stage1 MSEs */ + st1_mse_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] ); /* reuse top of residual resid[0] scratch RAM for stage1 MSEs */ st1_syn_vec_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC; /* reuse top of resid[0] scratch RAM for residual */ #ifndef ERI_MSVQ_CLEANUP dcttype = DCT_T2_24_XX; -#endif +#endif #endif @@ -448,16 +473,35 @@ void msvq_enc( #ifdef ERI_MSVQ_CLEANUP 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 ); + assert( N == FDCNG_VQ_MAX_LEN ); assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); - p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, invTrfMatrix, st1_mse_ptr, indices_st1_local, st1_syn_vec_ptr, dist[1] ); + + p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, + DCT_T2_24_XX, + FDCNG_VQ_DCT_MAXTRUNC, + invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + cdk1r_tr_midQ_truncQ, /* i: midQ vector */ + fdcng_dct_invScaleF, /* i: global inv scale factors*/ + fdcng_dct_scaleF, /* i: global scale factors*/ + FDCNG_VQ_DCT_NSEGM, /* i: number of segments */ + cdk1_ivas_cols_per_segment, /* i: remaining length per segment */ + cdk1_ivas_trunc_dct_cols_per_segment, /* i: trunc length per segment */ + cdk1_ivas_entries_per_segment, /* i: number of rows per segment */ + cdk1_ivas_cum_entries_per_segment, /* i: number of cumulative entries */ + cdk_37bits_ivas_stage1_W8Qx_dct_sections, /*i: Word8(byte) segment table ptrs */ + stage1_dct_col_syn_shift, /*i: columnwise syn shift tables */ + cdk1_ivas_segm_neighbour_fwd, /*i: circular neighbour list fwd */ + cdk1_ivas_segm_neighbour_rev, /*i: circular neighbour list reverse */ + FDCNG_VQ_DCT_NPOST, /*i: number of circ. neigbours to post check */ + st1_mse_ptr, indices_st1_local, st1_syn_vec_ptr, dist[1] ); + /* move established stage#1 indices to the global MSVQ list structure */ for ( c = 0; c < maxC; c++ ) { - indices[1][c * stages] = indices_st1_local[c]; + indices[1][c * stages] = indices_st1_local[c]; } } #else @@ -768,7 +812,7 @@ void msvq_enc( #ifdef ERI_MSVQ_CLEANUP if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) { - p_max = msvq_stage1_dct_recalc_candidates_wb( st1_syn_vec_ptr, u, maxC, dist[1] ); + p_max = msvq_stage1_dct_recalc_candidates_fdcng_wb( st1_syn_vec_ptr, u, maxC, dist[1] ); } #else if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB ) -- GitLab From b1c89d61151f9cb443e450c84f920fed48162def Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Thu, 4 May 2023 16:20:08 +0200 Subject: [PATCH 03/10] clang format fixes --- lib_com/lsf_tools.c | 4 +- lib_enc/lsf_msvq_ma_enc.c | 84 +++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index 51562d9461..6d7ca2ecd9 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -2060,8 +2060,8 @@ void dec_FDCNG_MSVQ_stage1( assert( j < cdk1_ivas_entries_per_segment[segm_ind] ); /* Word8 column variable Qx storage*/ - cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */ - cbpW8 += j * cdk1_ivas_cols_per_segment[segm_ind]; /* adaptive ptr init */ + cbpW8 = cdk_37bits_ivas_stage1_W8Qx_dct_sections[segm_ind]; /* Word8 storage fixed ptr_init */ + cbpW8 += j * cdk1_ivas_cols_per_segment[segm_ind]; /* adaptive ptr init */ dct_col_shift_tab = stage1_dct_col_syn_shift[segm_ind]; for ( col = 0; col < cdk1_ivas_cols_per_segment[segm_ind]; col++ ) diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 95ea385436..2a446cda4f 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -56,12 +56,12 @@ void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_ #ifdef ERI_MSVQ_CLEANUP -int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ - const float *u, /* i : target */ - const int16_t N, /* i : target length and IDCT synthesis length */ +int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ /* parameterization of segmented DCT domain storage */ - const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ + const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ @@ -76,16 +76,16 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , be const Word16 *entries_per_segment, /* i: number of rows per segment */ const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ - const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ - const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ - const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ - const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ - const Word16 npost_check, /*i: number of neigbours to check , should be even */ + const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ + const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ + const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ + const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ + const Word16 npost_check, /*i: number of neigbours to check , should be even */ - float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ - int16_t *indices_st1_local, /*o: selected cand indices */ - float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ - float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ + float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /*o: selected cand indices */ + float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ ) { /* stage1 search in a segmentwise truncated dctN domain without weights */ @@ -180,7 +180,7 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , be st1_mse_pair[p_max] = mse; /* move32(), single BASOP */ } /* BASOP 3 ops */ - /* avoid WC costly candidate list management by always updating p_max, + /* avoid WC costly candidate list management by always updating p_max, as we have only a pair in each segment to maintain */ p_max = 0; /* move16() */ if ( ( st1_mse_pair[0] - st1_mse_pair[1] ) < 0 ) /* L_sub()*/ @@ -204,8 +204,8 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , be dist1_ptr[j] *= dct_scaleF[2]; /* multiplication to get the DCT inner MSE scale to the correct input domain */ } - assert( (maxC_st1 >= 3) ); - assert( (maxC_st1 <= 8) ); + assert( ( maxC_st1 >= 3 ) ); + assert( ( maxC_st1 <= 8 ) ); p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish current worst candidate for MSVQ stage#2 among all maxC_st1 candidates so far */ @@ -250,10 +250,10 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , be if ( check_mse < dist1_ptr[p_max] ) { /* new winner , replace worst */ - dist1_ptr[p_max] = check_mse; - indices_st1_local[p_max] = check_ind[i]; - st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */ - p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */ + dist1_ptr[p_max] = check_mse; + indices_st1_local[p_max] = check_ind[i]; + st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */ + p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */ } } @@ -279,10 +279,10 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , be 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) */ - 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 */ - float *dist_ptr /* i/o: updated MSE vector for stage1 */ + 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 */ + float *dist_ptr /* i/o: updated MSE vector for stage1 */ ) { int16_t p_max_local, c; @@ -299,7 +299,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( dist_ptr[c] -= res24; /* remove DCT24 high band error contribution */ } - /* finally update p_max, as it may potentially change, + /* finally update p_max, as it may potentially change, due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */ p_max_local = maximum( dist_ptr, maxC_st1, NULL ); @@ -477,26 +477,26 @@ void msvq_enc( /* stage 1 candidates search in truncated dct24 domain without any weights */ assert( N == FDCNG_VQ_MAX_LEN ); assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); - - p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, - DCT_T2_24_XX, + + p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, + DCT_T2_24_XX, FDCNG_VQ_DCT_MAXTRUNC, - invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ - cdk1r_tr_midQ_truncQ, /* i: midQ vector */ - fdcng_dct_invScaleF, /* i: global inv scale factors*/ - fdcng_dct_scaleF, /* i: global scale factors*/ - FDCNG_VQ_DCT_NSEGM, /* i: number of segments */ - cdk1_ivas_cols_per_segment, /* i: remaining length per segment */ - cdk1_ivas_trunc_dct_cols_per_segment, /* i: trunc length per segment */ - cdk1_ivas_entries_per_segment, /* i: number of rows per segment */ - cdk1_ivas_cum_entries_per_segment, /* i: number of cumulative entries */ + invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + cdk1r_tr_midQ_truncQ, /* i: midQ vector */ + fdcng_dct_invScaleF, /* i: global inv scale factors*/ + fdcng_dct_scaleF, /* i: global scale factors*/ + FDCNG_VQ_DCT_NSEGM, /* i: number of segments */ + cdk1_ivas_cols_per_segment, /* i: remaining length per segment */ + cdk1_ivas_trunc_dct_cols_per_segment, /* i: trunc length per segment */ + cdk1_ivas_entries_per_segment, /* i: number of rows per segment */ + cdk1_ivas_cum_entries_per_segment, /* i: number of cumulative entries */ cdk_37bits_ivas_stage1_W8Qx_dct_sections, /*i: Word8(byte) segment table ptrs */ - stage1_dct_col_syn_shift, /*i: columnwise syn shift tables */ - cdk1_ivas_segm_neighbour_fwd, /*i: circular neighbour list fwd */ - cdk1_ivas_segm_neighbour_rev, /*i: circular neighbour list reverse */ - FDCNG_VQ_DCT_NPOST, /*i: number of circ. neigbours to post check */ + stage1_dct_col_syn_shift, /*i: columnwise syn shift tables */ + cdk1_ivas_segm_neighbour_fwd, /*i: circular neighbour list fwd */ + cdk1_ivas_segm_neighbour_rev, /*i: circular neighbour list reverse */ + FDCNG_VQ_DCT_NPOST, /*i: number of circ. neigbours to post check */ st1_mse_ptr, indices_st1_local, st1_syn_vec_ptr, dist[1] ); - + /* move established stage#1 indices to the global MSVQ list structure */ for ( c = 0; c < maxC; c++ ) -- GitLab From b70d44cb68050ff478b7c878cf4663df7107e5a8 Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Fri, 5 May 2023 11:36:58 +0200 Subject: [PATCH 04/10] assert fixed for FDCNG WB --- lib_com/options.h | 2 +- lib_enc/fd_cng_enc.c | 6 +++--- lib_enc/lsf_msvq_ma_enc.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 75c6c206c2..661972a71d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -161,7 +161,7 @@ #define FIX_422 /* FhG: Issue 422: re-introduce fix for noisy speech buffer in ParamISM */ #define ERI_FDCNGVQ_LOW_ROM /* Eri: Contribution #31 Table ROM saving for IVAS FDCNG-VQ modes */ -#define ERI_MSVQ_CLEANUP /* Eri: Contribution #31 BE modularization, mainly for future BASOP of msvq encoder side DCT21&DCT24 c-code */ +#define ERI_MSVQ_CLEANUP /* Eri: Contribution #31 BE modularization of msvq encoder side DCT21&DCT24 within msvq_enc() */ #define FIX_416_ISM_BR_SWITCHING /* FhG: add missing CLDFB reconfig to ISM BR switching */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index a76b741ca4..1e68a6fe78 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -1298,7 +1298,7 @@ void FdCngEncodeDiracMDCTStereoSID( #ifdef ERI_FDCNGVQ_LOW_ROM convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ - E[0] = sum_f( ms_ptr[0], NPART ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ + E[0] = sum_f( ms_ptr[0], NPART ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ #else convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); @@ -1323,8 +1323,8 @@ void FdCngEncodeDiracMDCTStereoSID( #ifdef ERI_FDCNGVQ_LOW_ROM /* DCT domain compressed/truncated indices used for first stage */ /* mid quantization using stages #1 through 6 */ - if ( N[0] == FDCNG_VQ_MAX_LEN_WB ) - { + if ( N[0] == FDCNG_VQ_MAX_LEN_WB ) + { create_IDCT_N_Matrix( invTrfMatrix, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /* truncated DCT 21 analysis */ dctT2_N_apply_matrix( (const float *) ms_ptr[0], dct_target, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 2a446cda4f..134af34cc9 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -475,7 +475,7 @@ 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 ); + assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */ assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, -- GitLab From 55a18714d7b481d20328ae78a24a7e7fa3f90fee Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Fri, 5 May 2023 11:52:19 +0200 Subject: [PATCH 05/10] ifdef corrections --- lib_enc/fd_cng_enc.c | 1 + lib_enc/lsf_msvq_ma_enc.c | 142 +++++++++++++++++++------------------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 839eec3dd6..babfd4a164 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -1260,6 +1260,7 @@ void FdCngEncodeDiracMDCTStereoSID( } /* M/S transform on log envelopes */ +#ifdef ERI_FDCNGVQ_LOW_ROM convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ E[0] = sum_f( ms_ptr[0], NPART ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 7e787477a1..fd66cb57c3 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -52,6 +52,7 @@ #include "ivas_prot.h" void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); +#ifdef ERI_FDCNGVQ_LOW_ROM #ifdef ERI_MSVQ_CLEANUP int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ @@ -379,9 +380,9 @@ void msvq_enc( #ifndef ERI_MSVQ_CLEANUP dcttype = DCT_T2_24_XX; - #endif +#endif /*----------------------------------------------------------------* * Allocate memory for previous (parent) and current nodes. * Parent node is indexed [0], current node is indexed [1]. @@ -465,12 +466,11 @@ void msvq_enc( } #ifdef ERI_FDCNGVQ_LOW_ROM - #ifdef ERI_MSVQ_CLEANUP 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 */ + assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */ assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM ); p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, @@ -663,37 +663,86 @@ void msvq_enc( else /* non-DCT Stage #1 code below */ if ( !s ) /* means: m==1 */ - { - /* This loop is identical to the one below, except, that the inner + { + /* 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. */ - /* dist[0][0] */ - for ( j = 0; j < levels[s]; j++ ) + /* dist[0][0] */ + for ( j = 0; j < levels[s]; j++ ) + { + en = 0.0f; + /* w,Tmp */ + /* Compute weighted codebook element and its energy */ + for ( c2 = 0; c2 < n; c2++ ) + { + Tmp[start + c2] = w[start + c2] * cbp[c2]; + en += cbp[c2] * Tmp[start + c2]; + } + cbp += maxn; /* pointer is incremented */ + + pTmp = &resid[0][0]; + /* Tmp */ + tmp = ( *pTmp++ ) * Tmp[0]; + for ( c2 = 1; c2 < N; c2++ ) { - en = 0.0f; - /* w,Tmp */ - /* Compute weighted codebook element and its energy */ - for ( c2 = 0; c2 < n; c2++ ) + tmp += ( *pTmp++ ) * Tmp[c2]; + } + tmp = en - 2.0f * tmp; + tmp += dist[0][0]; + if ( tmp < dist[1][p_max] ) + { + /* Replace worst */ + dist[1][p_max] = tmp; + indices[1][p_max * stages] = j; + parents[p_max] = 0; + + p_max = 0; + for ( c2 = 1; c2 < maxC; c2++ ) { - Tmp[start + c2] = w[start + c2] * cbp[c2]; - en += cbp[c2] * Tmp[start + c2]; + if ( dist[1][c2] > dist[1][p_max] ) + { + p_max = c2; + } } - cbp += maxn; /* pointer is incremented */ + } /* if (tmp <= dist[1][p_max]) */ + } /* for (j=0; j dist[1][p_max] ) - { - p_max = c2; - } - } - } /* if (tmp <= dist[1][p_max]) */ - } /* for(c=0; c Date: Fri, 5 May 2023 13:13:51 +0200 Subject: [PATCH 06/10] prot.h updates --- lib_com/prot.h | 36 ++++++++++++++++ lib_enc/lsf_msvq_ma_enc.c | 90 +++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/lib_com/prot.h b/lib_com/prot.h index 33fba361ce..fc9ba74651 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8076,6 +8076,7 @@ void msvq_dec( Word16 *uq_ind /* o : quantized vector (fixed point) */ ); + void dec_FDCNG_MSVQ_stage1( int16_t j_full, /* i: index full range */ int16_t n, /* i: dimension to generate */ @@ -8112,6 +8113,41 @@ void extend_dctN_input( const int16_t n_cols, /* i: number of columns == truncation length */ DCTTYPE dcttype ); /* i: matrix type */ +int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ + const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ + const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ + const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ + float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + const float *midQ_truncQ, /* i: midQ vector */ + const float *dct_invScaleF, /* i: global inv scale factors*/ + const float *dct_scaleF, /* i: global scale factors*/ + const Word16 n_segm, /* i: number of segments */ + const Word16 *cols_per_segment, /* i: remaining length per segment */ + const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ + const Word16 *entries_per_segment, /* i: number of rows per segment */ + const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ + const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ + const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ + const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ + const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ + const Word16 npost_check, /*i: number of neigbours to check , should be even */ + float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /*o: selected cand indices */ + float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ +); + +int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( + /* o : (updated p_max) */ + 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 */ + float *dist_ptr /* i/o: updated MSE vector for stage1 */ +); + + void PulseResynchronization( const float *src_exc, /* i : Input excitation buffer */ float *dst_exc, /* o : output excitation buffer */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index fd66cb57c3..f1eb1bae13 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -50,44 +50,45 @@ #include "ivas_prot.h" -void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); + +//void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); #ifdef ERI_FDCNGVQ_LOW_ROM #ifdef ERI_MSVQ_CLEANUP -int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ - const float *u, /* i : target */ - const int16_t N, /* i : target length and IDCT synthesis length */ - - /* parameterization of segmented DCT domain storage */ - const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ - - const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ - const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ - float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ - - const float *midQ_truncQ, /* i: midQ vector */ - const float *dct_invScaleF, /* i: global inv scale factors*/ - const float *dct_scaleF, /* i: global scale factors*/ - const Word16 n_segm, /* i: number of segments */ - const Word16 *cols_per_segment, /* i: remaining length per segment */ - const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ - const Word16 *entries_per_segment, /* i: number of rows per segment */ - const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ - - const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ - const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ - const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ - const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ - const Word16 npost_check, /*i: number of neigbours to check , should be even */ - - float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ - int16_t *indices_st1_local, /*o: selected cand indices */ - float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ - float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ +int16_t msvq_stage1_dct_search( + /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ + + /* parameterization of segmented DCT domain storage */ + const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ + + const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ + const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ + float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + + const float *midQ_truncQ, /* i: midQ vector */ + const float *dct_invScaleF, /* i: global inv scale factors*/ + const float *dct_scaleF, /* i: global scale factors*/ + const Word16 n_segm, /* i: number of segments */ + const Word16 *cols_per_segment, /* i: remaining length per segment */ + const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ + const Word16 *entries_per_segment, /* i: number of rows per segment */ + const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ + + const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ + const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ + const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ + const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ + const Word16 npost_check, /*i: number of neigbours to check , should be even */ + + float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /*o: selected cand indices */ + float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ ) - -{ /* stage1 search in a segmentwise truncated dctN domain without weights */ +{ /* stage1 search in a segmentwise truncated dct N domain without weights */ float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; float u_mr[FDCNG_VQ_MAX_LEN]; @@ -122,21 +123,18 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate dctT2_N_apply_matrix( (const float *) u_mr_scaled, dct_target, min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix, max_dct_trunc, dcttype ); - mse = 0; /* init search state ptr's at the top */ set_f( dist1_ptr, FLT_MAX, maxC_st1 ); st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ - + set_f(mse_trunc_segm,0.0f,n_segm); for ( segm = 0; segm < n_segm; segm++ ) - { - /* point to a new paired location for each segment */ - st1_mse_pair += 2; /* req. ptr init +=2 */ - st1_idx_pair += 2; /* req. ptr init +=2 */ - p_max = 0; /* req. to point to one of 1 or 0 , this init can potentially be omitted here as p_max is always 1 or 0 */ + { /* point to a new paired location for each segment */ + st1_mse_pair += 2; /* req. ptr init */ + st1_idx_pair += 2; /* req. ptr init */ + p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here as p_max is always 1 or 0 */ - /* compute segment common trunction error in dctN domain */ - mse_trunc_segm[segm] = 0; + /* compute segment common trunction error in dctN domain */ mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] ); cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */ @@ -258,9 +256,9 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */ /* always extract full length signal(e.g. 24) to be able to update WB(e.g. N_in==21) candidate MSE values */ - /* in the case that only a part of the IDCTN vector is in final use */ + /* in the case that only a part of the IDCT N vector is in final use */ - /* synthesis not yet fully parameterized/generalized for other IDCT lengths */ + /* note: synthesis not yet fully parameterized/generalized for other IDCT lengths */ assert( N == 24 ); { for ( c = 0; c < maxC_st1; c++ ) @@ -270,7 +268,7 @@ int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate } return p_max; /*ptr to worst performing candidate */ -}; +} /* recalc MSE for fdcng WB(0..20) coeffs , @@ -303,7 +301,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( p_max_local = maximum( dist_ptr, maxC_st1, NULL ); return p_max_local; -}; +} #endif #endif -- GitLab From 3cf9cbe078d118ea1df7658e58e3caef12f49199 Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Fri, 5 May 2023 13:33:02 +0200 Subject: [PATCH 07/10] aligned removed ifdefs properly --- lib_com/options.h | 2 +- lib_com/prot.h | 3 ++- lib_enc/fd_cng_enc.c | 7 +------ lib_enc/lsf_msvq_ma_enc.c | 12 ++++-------- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 17529131ce..d841a798e2 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,7 +156,7 @@ #define FIX_419_ISM_BRATE_SW_DTX /* VA: issue 419: fix ISM Bitrate Switching with dtx */ #define FIX_422 /* FhG: Issue 422: re-introduce fix for noisy speech buffer in ParamISM */ -#define ERI_FDCNGVQ_LOW_ROM /* Eri: Contribution #31 Table ROM saving for IVAS FDCNG-VQ modes */ + #define ERI_MSVQ_CLEANUP /* Eri: Contribution #31 BE modularization of msvq encoder side DCT21&DCT24 within msvq_enc() */ diff --git a/lib_com/prot.h b/lib_com/prot.h index fc9ba74651..888e00747f 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8113,6 +8113,7 @@ void extend_dctN_input( const int16_t n_cols, /* i: number of columns == truncation length */ DCTTYPE dcttype ); /* i: matrix type */ +#ifdef ERI_MSVQ_CLEANUP int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ const float *u, /* i : target */ const int16_t N, /* i : target length and IDCT synthesis length */ @@ -8146,7 +8147,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( const int16_t maxC_st1, /* i : number of candidates in stage1 */ float *dist_ptr /* i/o: updated MSE vector for stage1 */ ); - +#endif void PulseResynchronization( const float *src_exc, /* i : Input excitation buffer */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index babfd4a164..468aca1cb5 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -1260,15 +1260,10 @@ void FdCngEncodeDiracMDCTStereoSID( } /* M/S transform on log envelopes */ -#ifdef ERI_FDCNGVQ_LOW_ROM convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ E[0] = sum_f( ms_ptr[0], NPART ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ -#else - convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); - - E[0] = sum_f( ms_ptr[0], NPART ); -#endif + /* Quantize M noise shape */ /* Normalize MSVQ input */ diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index f1eb1bae13..c9111fda35 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -53,7 +53,7 @@ //void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); -#ifdef ERI_FDCNGVQ_LOW_ROM + #ifdef ERI_MSVQ_CLEANUP int16_t msvq_stage1_dct_search( @@ -304,7 +304,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( } #endif -#endif + /*--------------------------------------------------------------------------* * msvq_enc() @@ -336,7 +336,6 @@ void msvq_enc( float resid_buf[2 * LSFMBEST_MAX * M_MAX], dist_buf[2 * LSFMBEST_MAX], Tmp[M_MAX]; int16_t idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX]; int16_t n, maxn, start; -#ifdef ERI_FDCNGVQ_LOW_ROM #ifndef ERI_MSVQ_CLEANUP /* buffers */ float dct_target[FDCNG_VQ_DCT_MAXTRUNC]; @@ -370,8 +369,7 @@ void msvq_enc( assert( maxC <= LSFMBEST_MAX ); assert( ( LSFMBEST_MAX * M_MAX ) > ( N * maxC ) ); /* top of resid_buf is resid[1] and used for stage#1 residuals (input target u), - we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs - */ + we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs */ st1_mse_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] ); /* reuse top of residual resid[0] scratch RAM for stage1 MSEs */ st1_syn_vec_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC; /* reuse top of resid[0] scratch RAM for residual */ @@ -380,7 +378,7 @@ void msvq_enc( dcttype = DCT_T2_24_XX; #endif -#endif + /*----------------------------------------------------------------* * Allocate memory for previous (parent) and current nodes. * Parent node is indexed [0], current node is indexed [1]. @@ -463,7 +461,6 @@ void msvq_enc( dist[1][j] = FLT_MAX; } -#ifdef ERI_FDCNGVQ_LOW_ROM #ifdef ERI_MSVQ_CLEANUP if ( !s && applyDCT_flag != 0 ) /* means: m==1 */ { @@ -807,7 +804,6 @@ void msvq_enc( /* update p_max, as it may potentially change, due to the core DCT24 search originally optimizing over longer basis vectors than 21 */ p_max = maximum( dist[1], maxC, NULL ); } -#endif #endif m = maxC; } /* for (m=1, s=0; s Date: Fri, 5 May 2023 13:58:03 +0200 Subject: [PATCH 08/10] clang format --- lib_com/prot.h | 50 ++++++------- lib_enc/fd_cng_enc.c | 6 +- lib_enc/lsf_msvq_ma_enc.c | 147 +++++++++++++++++++------------------- 3 files changed, 101 insertions(+), 102 deletions(-) diff --git a/lib_com/prot.h b/lib_com/prot.h index 888e00747f..69bcaa6647 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8114,30 +8114,30 @@ void extend_dctN_input( DCTTYPE dcttype ); /* i: matrix type */ #ifdef ERI_MSVQ_CLEANUP -int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ - const float *u, /* i : target */ - const int16_t N, /* i : target length and IDCT synthesis length */ - const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ - const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ - const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ - float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ - const float *midQ_truncQ, /* i: midQ vector */ - const float *dct_invScaleF, /* i: global inv scale factors*/ - const float *dct_scaleF, /* i: global scale factors*/ - const Word16 n_segm, /* i: number of segments */ - const Word16 *cols_per_segment, /* i: remaining length per segment */ - const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ - const Word16 *entries_per_segment, /* i: number of rows per segment */ - const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ - const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ - const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ - const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ - const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ - const Word16 npost_check, /*i: number of neigbours to check , should be even */ - float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ - int16_t *indices_st1_local, /*o: selected cand indices */ - float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ - float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ +int16_t msvq_stage1_dct_search( /* o : (p_max , best candidate sofar ) */ + const float *u, /* i : target */ + const int16_t N, /* i : target length and IDCT synthesis length */ + const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */ + const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */ + const int16_t max_dct_trunc, /* i: maximum of truncation lenghts */ + float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */ + const float *midQ_truncQ, /* i: midQ vector */ + const float *dct_invScaleF, /* i: global inv scale factors*/ + const float *dct_scaleF, /* i: global scale factors*/ + const Word16 n_segm, /* i: number of segments */ + const Word16 *cols_per_segment, /* i: remaining length per segment */ + const Word16 *trunc_dct_cols_per_segment, /* i: trunc length per segment */ + const Word16 *entries_per_segment, /* i: number of rows per segment */ + const Word16 *cum_entries_per_segment, /* i: number of cumulative entries */ + const Word8 *const W8Qx_dct_sections[], /*i: Word8(byte) segment table ptrs */ + const Word16 *col_syn_shift[], /*i: columnwise syn shift tables */ + const Word8 *segm_neighbour_fwd, /*i: circular neighbour list fwd */ + const Word8 *segm_neighbour_rev, /*i: circular neighbour list reverse */ + const Word16 npost_check, /*i: number of neigbours to check , should be even */ + float *st1_mse_ptr, /*i: dynRAM buffer for MSEs */ + int16_t *indices_st1_local, /*o: selected cand indices */ + float *st1_syn_vec_ptr, /*i/o: buffer for IDCT24 synthesis */ + float *dist1_ptr /*o: resulting stage 1 MSEs in DCT-N domain */ ); int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( @@ -8147,7 +8147,7 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( const int16_t maxC_st1, /* i : number of candidates in stage1 */ float *dist_ptr /* i/o: updated MSE vector for stage1 */ ); -#endif +#endif void PulseResynchronization( const float *src_exc, /* i : Input excitation buffer */ diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 468aca1cb5..d71c24d45c 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -1263,7 +1263,7 @@ void FdCngEncodeDiracMDCTStereoSID( convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ E[0] = sum_f( ms_ptr[0], NPART ); /* TBD Note: NPART should likely be N[0] if N[0] may change */ - + /* Quantize M noise shape */ /* Normalize MSVQ input */ @@ -1278,8 +1278,8 @@ void FdCngEncodeDiracMDCTStereoSID( /* MSVQ */ /* DCT domain compressed/truncated indices used for first stage */ /* mid quantization using stages #1 through 6 */ - if ( N[0] == FDCNG_VQ_MAX_LEN_WB ) - { + if ( N[0] == FDCNG_VQ_MAX_LEN_WB ) + { create_IDCT_N_Matrix( invTrfMatrix, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /* truncated DCT 21 analysis */ dctT2_N_apply_matrix( (const float *) ms_ptr[0], dct_target, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index c9111fda35..67ba2f350c 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -51,7 +51,7 @@ #include "ivas_prot.h" -//void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); +// void dctT2_N_apply_matrix( const float *input, float *output, const int16_t dct_dim, int16_t fdcngvq_dim, const float *idctT2_24_X_matrixQ16, const int16_t matrix_1st_dim, DCTTYPE dcttype ); #ifdef ERI_MSVQ_CLEANUP @@ -127,14 +127,14 @@ int16_t msvq_stage1_dct_search( set_f( dist1_ptr, FLT_MAX, maxC_st1 ); st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ - set_f(mse_trunc_segm,0.0f,n_segm); + set_f( mse_trunc_segm, 0.0f, n_segm ); for ( segm = 0; segm < n_segm; segm++ ) - { /* point to a new paired location for each segment */ + { /* point to a new paired location for each segment */ st1_mse_pair += 2; /* req. ptr init */ st1_idx_pair += 2; /* req. ptr init */ p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here as p_max is always 1 or 0 */ - /* compute segment common trunction error in dctN domain */ + /* compute segment common trunction error in dctN domain */ mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] ); cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */ @@ -304,7 +304,6 @@ int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb( } #endif - /*--------------------------------------------------------------------------* * msvq_enc() @@ -378,7 +377,7 @@ void msvq_enc( dcttype = DCT_T2_24_XX; #endif - + /*----------------------------------------------------------------* * Allocate memory for previous (parent) and current nodes. * Parent node is indexed [0], current node is indexed [1]. @@ -658,86 +657,37 @@ void msvq_enc( else /* non-DCT Stage #1 code below */ 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. */ - /* dist[0][0] */ - for ( j = 0; j < levels[s]; j++ ) { - en = 0.0f; - /* w,Tmp */ - /* Compute weighted codebook element and its energy */ - for ( c2 = 0; c2 < n; c2++ ) - { - Tmp[start + c2] = w[start + c2] * cbp[c2]; - en += cbp[c2] * Tmp[start + c2]; - } - cbp += maxn; /* pointer is incremented */ - - pTmp = &resid[0][0]; - /* Tmp */ - tmp = ( *pTmp++ ) * Tmp[0]; - for ( c2 = 1; c2 < N; c2++ ) - { - tmp += ( *pTmp++ ) * Tmp[c2]; - } - tmp = en - 2.0f * tmp; - tmp += dist[0][0]; - if ( tmp < dist[1][p_max] ) + /* 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. */ + /* dist[0][0] */ + for ( j = 0; j < levels[s]; j++ ) { - /* Replace worst */ - dist[1][p_max] = tmp; - indices[1][p_max * stages] = j; - parents[p_max] = 0; - - p_max = 0; - for ( c2 = 1; c2 < maxC; c2++ ) + en = 0.0f; + /* w,Tmp */ + /* Compute weighted codebook element and its energy */ + for ( c2 = 0; c2 < n; c2++ ) { - if ( dist[1][c2] > dist[1][p_max] ) - { - p_max = c2; - } + Tmp[start + c2] = w[start + c2] * cbp[c2]; + en += cbp[c2] * Tmp[start + c2]; } - } /* if (tmp <= dist[1][p_max]) */ - } /* for (j=0; j dist[1][p_max] ) + { + p_max = c2; + } + } + } /* if (tmp <= dist[1][p_max]) */ + } /* for(c=0; c Date: Fri, 5 May 2023 14:25:20 +0200 Subject: [PATCH 09/10] fixed ptr+=2 increment in new function --- lib_enc/lsf_msvq_ma_enc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 67ba2f350c..1be9a1f764 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -125,14 +125,13 @@ int16_t msvq_stage1_dct_search( /* init search state ptr's at the top */ set_f( dist1_ptr, FLT_MAX, maxC_st1 ); - st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr init +=2 */ - st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr init +=2 */ + st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr post upd +=2 */ + st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */ set_f( mse_trunc_segm, 0.0f, n_segm ); + for ( segm = 0; segm < n_segm; segm++ ) - { /* point to a new paired location for each segment */ - st1_mse_pair += 2; /* req. ptr init */ - st1_idx_pair += 2; /* req. ptr init */ - p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here as p_max is always 1 or 0 */ + { /* point to a new paired location for each segment */ + p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */ /* compute segment common trunction error in dctN domain */ mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] ); @@ -192,6 +191,9 @@ int16_t msvq_stage1_dct_search( /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */ } /* j in section */ + st1_mse_pair += 2; /* req. ptr init */ + st1_idx_pair += 2; /* req. ptr init */ + } /* next segment */ for ( j = 0; j < maxC_st1; j++ ) -- GitLab From d09f4d7e29244bbed323188eaa5bbd54f040ff4f Mon Sep 17 00:00:00 2001 From: Jonas Sv Date: Fri, 5 May 2023 14:32:56 +0200 Subject: [PATCH 10/10] clang format fix --- lib_enc/lsf_msvq_ma_enc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 1be9a1f764..0f7a798a75 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -130,8 +130,8 @@ int16_t msvq_stage1_dct_search( set_f( mse_trunc_segm, 0.0f, n_segm ); for ( segm = 0; segm < n_segm; segm++ ) - { /* point to a new paired location for each segment */ - p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */ + { /* point to a new paired location for each segment */ + p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */ /* compute segment common trunction error in dctN domain */ mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] ); -- GitLab