diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index efdbf571d87c05ebabb8866514b824b90c603739..a36b8410962f4244160e8b051456cae478089acc 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -920,4 +920,26 @@ void convert_coeffs_to_higher_res_fx( Word32 *out, /* o : converted output */ const Word16 len /* i : length of subframes */ ); + +void create_IDCT_N_Matrix_fx( + Word32 *inv_matrixFloatQ, /* i/o: RAM buffer */ + const Word16 N, /* i : DCT length, number of time samples */ + const Word16 n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ + const Word16 alloc_size /* i : RAM buffer size in elements */ +); + +void ivas_dirac_dec_get_frequency_axis_fx( + Word16 *frequency_axis, /* Q0 */ + const Word32 output_Fs, + const Word16 num_freq_bands +); + +void ivas_decision_matrix_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 *sharpFlag, /* o : formant sharpening flag */ + Word16 *core_switching_flag, /* o : ACELP->HQ switching frame flag */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 nchan_out /* i : Number of output channels */ +); + #endif diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index cba26dbc4cb6dc0d006066bc9b3c9a7d81427c3e..93d1c25379e27b6bcdc339ee7c7b45b999c9ec8a 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -43,6 +43,7 @@ #include "basop_proto_func.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" #include "prot_fx1.h" #endif @@ -2886,3 +2887,80 @@ void create_IDCT_N_Matrix( return; } + +#ifdef IVAS_FLOAT_FIXED +void create_IDCT_N_Matrix_fx( + Word32 *inv_matrixFloatQ, /* i/o: RAM buffer */ + const Word16 N, /* i : DCT length, number of time samples */ + const Word16 n_cols, /* i : number of dct coeffs (as DCT may be truncated) */ + const Word16 alloc_size /* i : RAM buffer size in elements */ +) +{ + Word16 c, c1, r, r_flip, W16_val; + Word16 len; + Word16 mat_cpy_size; + const Word16 *absval_ptr; + const Word8 *idx_ptr; + Word16 idx; + Word32( *ptr )[FDCNG_VQ_DCT_MAXTRUNC] = (void *) inv_matrixFloatQ; /* fixed number of columns pointers, to simplifies adressing in ANSIC */ + + absval_ptr = unique_idctT2_24coeffsQ16; + idx_ptr = idctT2_24_compressed_idx; + len = FDCNG_VQ_MAX_LEN; + + IF ( N == FDCNG_VQ_MAX_LEN_WB ) + { + absval_ptr = unique_idctT2_21coeffsQ16; + idx_ptr = idctT2_21_compressed_idx; + len = N; + } + + assert( alloc_size >= ( n_cols * len ) ); /* enough space for the full expanded IDCT matrix */ + assert( N <= len ); + + mat_cpy_size = ( n_cols ) * ( len >> 1 ); /* NB integer division of "len" */ + + IF ( NE_16( ( len & 1 ), 0 ) ) + { /* odd sized DCT with a non-reflected center row */ + mat_cpy_size = add( mat_cpy_size, n_cols ); + } + + FOR ( c = 0; c < mat_cpy_size; c++ ) + { + idx = (Word16) ( idx_ptr[c] ); + W16_val = absval_ptr[abs( idx )]; + + IF ( idx < 0 ) + { + W16_val = -( W16_val ); + } + /* (+1.52587890625e-05f) * 2 ^ 31 is equal to 32768 */ + inv_matrixFloatQ[c] = 32768 * ( W16_val ); /* scaling to 2 ^ 31*/ + } + + /* for even number of coeffs DCT24, + flip symmetry for odd, even is used to save 50% IDCT Table ROM */ + /* for an odd DCT center is not flipped e.g for DCT21 */ + + assert( n_cols == FDCNG_VQ_DCT_MAXTRUNC ); + assert( ( n_cols & 1 ) == 0 ); + + FOR ( c = 0; c < ( n_cols ); c += 2 ) + { + c1 = c + 1; + r_flip = len - 1; + FOR ( r = 0; r < ( len / 2 ); r_flip-- ) + { + r++; +#define WMC_TOOL_SKIP + ptr[r_flip][c] = ptr[r][c]; /* flipped */ + ptr[r_flip][c1] = -( ptr[r][c1] ); /* flipped and sign swapped */ + MOVE( 2 ); + MULT( 1 ); /* for negate */ +#undef WMC_TOOL_SKIP + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index e6e77c9f72056ca3033c4a760a19ca7c7b2e033a..8dc34d6c8ac1f1b181ac53916628134de6a561d5 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -45,6 +45,7 @@ #include "ivas_prot.h" #include "ivas_rom_dec.h" #include "prot_fx2.h" +#include "ivas_prot_fx.h" /*------------------------------------------------------------------- * Local constants @@ -2060,9 +2061,32 @@ void FdCngDecodeMDCTStereoSID( float *invTrfMatrix; float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; +#ifdef IVAS_FLOAT_FIXED + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 norm1, norm2; + float lr_ptr_fxfl[NPART]; +#endif invTrfMatrix = (float *) tmpRAM; +#ifdef IVAS_FLOAT_FIXED + invTrfMatrix_fx = (Word32 *)tmpRAM_fx; + create_IDCT_N_Matrix_fx(invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof(tmpRAM_fx) / (sizeof(Word32))); + + FOR(Word16 i = 0; i < FDCNG_VQ_MAX_LEN; i++) { + FOR(Word16 j = 0; j < FDCNG_VQ_DCT_MAXTRUNC; j++) { + Word16 index = i * FDCNG_VQ_DCT_MAXTRUNC + j; + invTrfMatrix[index] = fix_to_float(invTrfMatrix_fx[index], 31); // Q factor 31 + } + } + +#else create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); +#endif is_out_ms = 0; if ( hCPE->hCoreCoder[0]->cng_sba_flag ) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index bc7d3059d0cb2da7531fc39d81008c68c61cd1a7..1de3eabff384f62a43c12cb6ec10e58c6dba75f6 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -203,7 +203,11 @@ ivas_error ivas_core_dec( if ( st->bfi != 1 ) { +#ifdef IVAS_FLOAT_FIXED + ivas_decision_matrix_dec_fx( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); +#else ivas_decision_matrix_dec( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); +#endif synchonize_channels_mdct_sid( sts, n ); diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec.c index 11786e016ff7ea369d528a8513c8566cb8084706..38e15ba956189b5c7dc6816aa9dbcc8051f36d5f 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec.c @@ -38,6 +38,7 @@ #include "prot.h" #include "ivas_cnst.h" #include "wmc_auto.h" +#include "ivas_prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() @@ -46,6 +47,12 @@ * Read ACELP signaling bits from the bitstream * Set extension layers *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 get_next_index_4_by_15[16] = +{ + 0, 2184, 4369, 6553, 8738, 10922, 13107, 15291, 17476, 19660, 21845, 24029, 26214, 28398, 30583, 32768 +}; +#endif void ivas_decision_matrix_dec( Decoder_State *st, /* i/o: decoder state structure */ @@ -464,3 +471,530 @@ void ivas_decision_matrix_dec( return; } + +#ifdef IVAS_FLOAT_FIXED +void ivas_decision_matrix_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + Word16 *sharpFlag, /* o : formant sharpening flag */ + Word16 *core_switching_flag, /* o : ACELP->HQ switching frame flag */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 nchan_out /* i : Number of output channels */ +) +{ + Word16 tmp; + Word32 icbwe_brate; + + /* init */ + icbwe_brate = 0; + move32(); + st->core = -1; + move16(); + st->core_brate = 0; + move32(); + st->extl = -1; + move16(); + st->extl_brate = 0; + move32(); + st->ppp_mode_dec = 0; + move16(); + st->nelp_mode_dec = 0; + move16(); + st->igf = 0; + move16(); + st->vbr_hw_BWE_disable_dec = 0; + move16(); + + /*-----------------------------------------------------------------* + * Read SID signaling bits from the bitstream + *-----------------------------------------------------------------*/ + + test(); test(); test(); test(); + IF ( ( EQ_16( st->idchan, 0 ) && ( EQ_32( st->total_brate, FRAME_NO_DATA ) || EQ_32( st->total_brate, SID_2k40 ) ) ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && LE_32( st->total_brate, SID_2k40 ) ) ) + { + st->core = ACELP_CORE; + move16(); + st->core_brate = st->total_brate; + move32(); + + test(); test(); test(); test(); test(); + IF ( EQ_32( st->total_brate, SID_2k40 ) && !( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) ) + { + IF ( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + st->cng_type = get_next_indice( st, 1 ); + + IF ( EQ_16( st->cng_type, FD_CNG ) ) + { + st->bwidth = get_next_indice( st, 2 ); + } + } + IF ( get_next_indice( st, 1 ) ) + { + st->L_frame = L_FRAME16k; + move16(); + } + ELSE + { + st->L_frame = L_FRAME; + move16(); + } + } + ELSE IF ( EQ_32( st->total_brate, SID_2k40 ) && EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->cng_sba_flag, 0 ) ) + { + /* read channel coherence */ + Word16 index; + index = get_next_indice( st, 4 ); + st->hFdCngDec->hFdCngCom->coherence_fx = get_next_index_4_by_15[index]; + + /* TODO: remove floating point dependency */ + st->hFdCngDec->hFdCngCom->coherence_flt = get_next_index_4_by_15[index] / ( 1 << 15 ); + + /* read flag for no side noise shape */ + st->hFdCngDec->hFdCngCom->no_side_flag = get_next_indice( st, 1 ); + } + + test(); test(); test(); test(); test(); + IF ( ( GE_32( st->output_Fs, 32000 ) && GE_16( st->bwidth, SWB ) ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && EQ_16( nchan_out, 2 ) && LT_16( st->L_frame, L_FRAME16k ) ) ) + { + st->extl = SWB_CNG; + move16(); + } + + test(); test(); test(); + IF ( EQ_32( st->total_brate, FRAME_NO_DATA ) && st->prev_bfi && !st->bfi && GT_16( st->L_frame, L_FRAME16k ) ) + { + st->L_frame = st->last_CNG_L_frame; + move16(); + } + + return; + } + + /*---------------------------------------------------------------------* + * ACELP/HQ core selection + *---------------------------------------------------------------------*/ + + test(); test(); + IF ( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) + { + /* minimal signaling for the secondary channel, most of the parameters are deduced from the primary channel */ + st->core = ACELP_CORE; + move16(); + } + ELSE IF ( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) + { + /* ISM Low-rate mode -> always WB, ACELP core, IC coder_type */ + st->core = ACELP_CORE; + move16(); + } + ELSE IF ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->core = TCX_20_CORE; + move16(); + } + ELSE + { + st->core = ACELP_CORE; + move16(); + + test(); + IF ( EQ_16( st->element_mode, IVAS_CPE_TD ) || GE_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) + { + /* ACELP/transform core selection bit */ + IF ( get_next_indice( st, 1 ) ) + { + st->core = HQ_CORE; + move16(); + } + ELSE + { + st->core = ACELP_CORE; + move16(); + } + } + } + + /*-----------------------------------------------------------------* + * Read ACELP signaling bits from the bitstream + *-----------------------------------------------------------------*/ + + IF ( EQ_16( st->core, ACELP_CORE ) ) + { + test(); test(); + IF ( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) + { + /* ISM Low-rate mode */ + st->bwidth = WB; + move16(); + st->coder_type = INACTIVE; + move16(); + *sharpFlag = 0; + move16(); + } + ELSE IF ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + *sharpFlag = 0; + move16(); + IF ( EQ_16( st->coder_type, GENERIC ) || EQ_16( st->coder_type, VOICED ) ) + { + *sharpFlag = 1; + move16(); + } + + st->core_brate = st->total_brate; + move32(); + st->codec_mode = MODE1; + move16(); + + test(); test(); + IF ( EQ_16( st->idchan, 1 ) && ( EQ_16( st->tdm_LRTD_flag, 0 ) || LT_16( st->bits_frame_channel, IVAS_16k4 / FRAMES_PER_SEC ) ) ) + { + st->bwidth = WB; /* only WB in the secondary channel */ + move16(); + } + } + ELSE + { + IF ( LT_32( element_brate, FRMT_SHP_MIN_BRATE_IVAS ) ) + { + st->coder_type = get_next_indice( st, 3 ); + *sharpFlag = 0; + move16(); + + test(); test(); test(); + IF ( LT_32( element_brate, IVAS_24k4 ) && ( EQ_16( st->coder_type, VOICED ) || EQ_16( st->coder_type, GENERIC ) || EQ_16( st->coder_type, TRANSITION ) ) ) + { + *sharpFlag = 1; + move16(); + } + } + ELSE + { + /* get coder_type info */ + st->coder_type = get_next_indice( st, 3 ); + + /* get sharpening flag */ + *sharpFlag = get_next_indice( st, 1 ); + } + } + } + + /*-----------------------------------------------------------------* + * Set extension layers + *-----------------------------------------------------------------*/ + + IF ( EQ_16( st->core, ACELP_CORE ) ) + { + test(); test(); test(); test(); test(); test(); test(); + IF ( EQ_16( st->bwidth, WB ) && st->low_rate_mode ) + { + st->extl = WB_BWE; + move16(); + IF ( GE_32( st->total_brate, MIN_BRATE_WB_BWE ) ) + { + st->extl_brate = WB_BWE_0k35; + move32(); + } + } + ELSE IF ( EQ_16( st->bwidth, WB ) && ( LT_32( st->total_brate, MIN_BRATE_WB_BWE ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) ) ) + { + IF ( EQ_16( st->vbr_hw_BWE_disable_dec, 0 ) ) + { + st->extl = WB_BWE; + move16(); + } + } + ELSE IF ( EQ_16( st->bwidth, WB ) && GE_32( st->total_brate, MIN_BRATE_WB_BWE ) && !st->flag_ACELP16k ) + { + /* read the WB TBE/BWE selection bit */ + IF ( get_next_indice( st, 1 ) ) + { + st->extl = WB_BWE; + move16(); + st->extl_brate = WB_BWE_0k35; + move32(); + } + ELSE + { + st->extl = WB_TBE; + move16(); + test(); test(); + IF ( LT_32( st->total_brate, MIN_BRATE_WB_TBE_1k05 ) || ( EQ_16( st->element_mode, IVAS_CPE_TD ) && LT_32( st->total_brate, MIN_TDM_BRATE_WB_TBE_1k05 ) ) ) + { + st->extl_brate = WB_TBE_0k35; + move32(); + } + ELSE + { + st->extl_brate = WB_TBE_1k05; + move32(); + } + } + } + ELSE IF ( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) + { + IF ( GE_32( st->total_brate, MIN_BRATE_SWB_BWE ) || ( GE_32( st->total_brate, MIN_MIN_BRATE_LRTD_SWB_BWE ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->bwidth, SWB ) && st->tdm_LRTD_flag ) || ( LT_32( element_brate, IVAS_16k4 ) && GE_32( st->total_brate, MIN_MIN_BRATE_LRTD_SWB_BWE ) && EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->bwidth, SWB ) ) ) + { + /* read the SWB TBE/BWE selection bit */ + tmp = get_next_indice( st, 1 ); + + IF ( tmp ) + { + st->extl = SWB_BWE; + move16(); + st->extl_brate = SWB_BWE_1k6; + move32(); + } + ELSE + { + st->extl = SWB_TBE; + move32(); + st->extl_brate = SWB_TBE_1k6; + move32(); + IF ( GE_32( st->total_brate, MIN_BRATE_SWB_TBE_2k80 ) && st->flag_ACELP16k && EQ_16( st->element_mode, IVAS_SCE ) ) + { + st->extl_brate = SWB_TBE_2k8; + move32(); + } + ELSE IF ( EQ_16( st->tdm_LRTD_flag, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF ( LT_32( st->element_brate, IVAS_24k4 ) ) + { + st->extl_brate = SWB_TBE_1k10; + move32(); + } + ELSE + { + st->extl_brate = SWB_TBE_1k75; + move32(); + } + } + ELSE IF ( LT_32( st->total_brate, MIN_BRATE_SWB_TBE_1k60 ) ) + { + st->extl_brate = SWB_TBE_0k95; + move32(); + } + } + } + ELSE + { + st->extl = WB_BWE; + move16(); + st->extl_brate = 0; + move32(); + } + + /* set FB TBE and FB BWE extension layers */ + IF ( EQ_16( st->bwidth, FB ) ) + { + IF ( EQ_16( st->extl, SWB_BWE ) ) + { + st->extl = FB_BWE; + move16(); + st->extl_brate = FB_BWE_1k8; + move32(); + } + ELSE IF ( EQ_16( st->extl, SWB_TBE ) ) + { + st->extl = FB_TBE; + move16(); + st->extl_brate = FB_TBE_1k8; + move32(); + IF ( GE_32( st->total_brate, MIN_BRATE_SWB_TBE_2k80 ) && st->flag_ACELP16k && EQ_16( st->element_mode, IVAS_SCE ) ) + { + st->extl_brate = FB_TBE_3k0; + move32(); + } + } + } + /* set IC-BWE bitrate */ + test(); test(); + IF ( EQ_16( st->element_mode, IVAS_CPE_TD ) && !( GE_16( st->bwidth, SWB ) && st->tdm_LRTD_flag ) ) + { + icbwe_brate = STEREO_BITS_ICBWE * FRAMES_PER_SEC; + move32(); + IF ( EQ_16( st->flag_ACELP16k, 0 ) ) + { + icbwe_brate = ( STEREO_BITS_ICBWE - STEREO_ICBWE_SPBITS ) * FRAMES_PER_SEC; + move32(); + } + } + ELSE IF ( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + icbwe_brate = STEREO_BITS_ICBWE_DFT * FRAMES_PER_SEC; + move32(); + IF ( EQ_16( st->flag_ACELP16k, 0 ) ) + { + icbwe_brate = ( STEREO_BITS_ICBWE_DFT - STEREO_ICBWE_SPBITS ) * FRAMES_PER_SEC; + move32(); + } + } + + test(); test(); test(); test(); test(); test(); + IF ( GE_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( st->core, ACELP_CORE ) && ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && !( EQ_16( st->element_mode, IVAS_CPE_TD ) && st->tdm_LRTD_flag ) ) + { + icbwe_brate = L_add( icbwe_brate, STEREO_ICBWE_MSFLAG_BITS * FRAMES_PER_SEC ); + } + } + } + + /* set core bitrate */ + st->core_brate = L_sub( L_sub( st->total_brate, st->extl_brate ), icbwe_brate ); + + /*-----------------------------------------------------------------* + * Read transform core (TCX vs. HQ) signaling bit from the bitstream + *-----------------------------------------------------------------*/ + + test(); test(); test(); + IF ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( st->core, HQ_CORE ) ) + { + IF ( get_next_indice( st, 1 ) ) + { + st->core = TCX_20_CORE; + move16(); + } + ELSE + { + st->core = HQ_CORE; + move16(); + } + } + + test(); + IF ( NE_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->core, TCX_20_CORE ) ) + { + st->extl = IGF_BWE; + move16(); + st->extl_brate = 0; + move32(); + } + + /*-----------------------------------------------------------------* + * Read ACELP->HQ core switching flag + *-----------------------------------------------------------------*/ + + test(); + IF ( EQ_16( st->core, HQ_CORE ) || EQ_16( st->core, TCX_20_CORE ) ) + { + IF ( EQ_16( st->core, HQ_CORE ) ) + { + /* read ACELP->HQ core switching flag */ + *core_switching_flag = get_next_indice( st, 1 ); + } + ELSE + { + *core_switching_flag = 0; + move16(); + } + + IF ( EQ_16( *core_switching_flag, 1 ) ) + { + st->last_core_from_bs = ACELP_CORE; + move16(); + + IF ( EQ_16( st->core, st->last_core ) ) + { + /* A mismatch between the core_switching_flag and the st->core/st->last_core + indicates a frame was lost. if prev_bfi is not set the frame loss + occured during CNG and the prev_bfi needs to be set. */ + st->prev_bfi = 1; + move16(); + } + } + ELSE + { + st->last_core_from_bs = HQ_CORE; /* Could also be TCX, but it does not make any dIFference */ + move16(); + } + + st->last_L_frame_ori = st->last_L_frame; + move16(); + } + + /*-----------------------------------------------------------------* + * Set ACELP frame length + *-----------------------------------------------------------------*/ + + test(); test(); test(); test(); test(); test(); + IF ( EQ_32( st->core_brate, FRAME_NO_DATA ) ) + { + /* prevent "L_frame" changes in CNG segments */ + st->L_frame = st->last_L_frame; + move16(); + } + ELSE IF ( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->bwidth, WB ) && st->first_CNG && LT_16( st->hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) + { + /* prevent "L_frame" changes in SID frame after short segment of active frames */ + st->L_frame = st->last_CNG_L_frame; + move16(); + } + ELSE IF ( ( EQ_32( st->core_brate, SID_2k40 ) && GE_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, WB ) ) || st->flag_ACELP16k ) + { + st->L_frame = L_FRAME16k; + move16(); + } + ELSE + { + st->L_frame = L_FRAME; + move16(); + } + + IF ( EQ_16( st->L_frame, L_FRAME16k ) ) + { + st->nb_subfr = NB_SUBFR16k; + move16(); + } + ELSE + { + st->nb_subfr = NB_SUBFR; + move16(); + } + + /*-----------------------------------------------------------------* + * set inactive coder_type flag in ACELP core + *-----------------------------------------------------------------*/ + + st->inactive_coder_type_flag = 0; /* AVQ by default */ + move16(); + + IF ( LE_32( st->total_brate, MAX_GSC_INACTIVE_BRATE ) ) + { + st->inactive_coder_type_flag = 1; /* GSC */ + move16(); + } + + /*-----------------------------------------------------------------* + * Reconfigure in case when output_Fs < input_Fs + *-----------------------------------------------------------------*/ + + st->extl_orig = st->extl; + move16(); + st->extl_brate_orig = st->extl_brate; + move32(); + + + test(); test(); + IF ( EQ_32( st->output_Fs, 16000 ) && EQ_16( st->L_frame, L_FRAME16k ) && NE_16( st->extl, IGF_BWE ) ) + { + st->extl = -1; + move16(); + st->extl_brate = 0; + move32(); + } + + IF ( EQ_16( st->ini_frame, 0 ) ) + { + /* avoid switching of internal ACELP Fs in the very first frame */ + st->last_L_frame = st->L_frame; + move16(); + st->last_core = st->core; + move16(); + st->last_core_brate = st->core_brate; + move32(); + st->last_extl = st->extl; + move16(); + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 7e8acd1f3570f84c83a2df61167d2a1751d7dc6f..6a407c3e3614d5bf3a7e3251652d71683a71fc23 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -266,7 +266,17 @@ static ivas_error ivas_dirac_rend_config( } set_f( hDirACRend->frequency_axis, 0.0f, hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + Word16 *frequency_axis_fx = (Word16 *) malloc(hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ); + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hSpatParamRendCom->num_freq_bands ); + + FOR (Word16 i = 0; i < hSpatParamRendCom->num_freq_bands; i++) + { + hDirACRend->frequency_axis[i] = ( float ) frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( hDirACRend->frequency_axis, output_Fs, hSpatParamRendCom->num_freq_bands ); +#endif } if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirACRend->panningConf == DIRAC_PANNING_HOA3 && nchan_transport == 2 ) @@ -893,8 +903,17 @@ ivas_error ivas_dirac_dec_config( { float frequency_axis[CLDFB_NO_CHANNELS_MAX]; - ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); + + for (int i = 0; i < st_ivas->hSpatParamRendCom->num_freq_bands; i++) { + frequency_axis[i] = ( float ) frequency_axis_fx[i]; + } +#else + ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); +#endif if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index d2120bf2997682f1afc11ebbe93b0583d5ba68b6..270c4138b6242492c49a5f4e3bf7ccf31db19d4e 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -378,7 +378,16 @@ ivas_error ivas_param_mc_dec_open( hParamMC->h_freq_domain_decorr_ap_params = NULL; hParamMC->h_freq_domain_decorr_ap_state = NULL; +#ifdef IVAS_FLOAT_FIXED + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hParamMC->num_freq_bands ); + + for (int i = 0; i < hParamMC->num_freq_bands; i++) { + frequency_axis[i] = (float) frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, hParamMC->num_freq_bands ); +#endif if ( ( error = ivas_dirac_dec_decorr_open( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) @@ -883,7 +892,16 @@ ivas_error ivas_param_mc_dec_reconfig( hParamMC->h_freq_domain_decorr_ap_params = NULL; hParamMC->h_freq_domain_decorr_ap_state = NULL; +#ifdef IVAS_FLOAT_FIXED + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx(frequency_axis_fx, output_Fs, hParamMC->num_freq_bands); + + for (Word16 i = 0; i < hParamMC->num_freq_bands; i++) { + frequency_axis[i] = ( float ) frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, hParamMC->num_freq_bands ); +#endif if ( ( error = ivas_dirac_dec_decorr_open( &( hParamMC->h_freq_domain_decorr_ap_params ), &( hParamMC->h_freq_domain_decorr_ap_state ), hParamMC->num_freq_bands, hParamMC->num_outputs_diff, hParamMC->diff_proto_info->num_protos_diff, DIRAC_SYNTHESIS_COV_MC_LS, frequency_axis, nchan_transport, output_Fs ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 46e2208a6aa7aa4a2b562f80765f108de87c49c6..500b9730876ff6258bd0f5a8be0d447b1aedf292 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -252,7 +252,15 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( !hDiracDecBin->useTdDecorr && !( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) { +#ifdef IVAS_FLOAT_FIXED + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); + FOR(Word16 i = 0; i < nBins; i++) { + frequency_axis[i] = (float)frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); +#endif if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), &( hDiracDecBin->h_freq_domain_decorr_ap_state ), nBins, diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 09929453fff4fbc2f8b31df3a679a62159ecb4f7..36c0b13dfb145ab7e8b34e3b8f23775a6f4a87af 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -1431,6 +1431,26 @@ void ivas_dirac_dec_get_frequency_axis( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_dirac_dec_get_frequency_axis_fx( + Word16 *frequency_axis, /* Q0 */ + const Word32 output_Fs, + const Word16 num_freq_bands ) +{ + Word16 k, div_res, const_part, scale; + /* calc cldfb frequency axis */ + + const_part = BASOP_Util_Divide3216_Scale( output_Fs, shl( num_freq_bands, 1 ), &scale ); + const_part = shr( const_part, ( -1 - scale ) ); + for ( k = 0; k < num_freq_bands; k++ ) + { + /* frequency_axis[k] = ((float)k + 0.5f) * const_part; */ + frequency_axis[k] = add( i_mult( k, const_part ), shr( const_part, 1 ) ); + } + + return; +} +#endif /*------------------------------------------------------------------------- * initDiffuseResponses() diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 178d733d213d696f32a670a05102e5b9e4ef00f3..ccf6d9d4af7bd7b473217a376ed3ddefe6e07c0a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -45,6 +45,7 @@ #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" @@ -8634,7 +8635,16 @@ static ivas_error ivas_masa_ext_rend_dirac_rend_init( } set_f( hDirACRend->frequency_axis, 0.0f, hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + Word16 *frequency_axis_fx = ( Word16 * ) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ); + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, hSpatParamRendCom->num_freq_bands ); + + FOR(int i = 0; i < hSpatParamRendCom->num_freq_bands; i++) { + hDirACRend->frequency_axis[i] = (float)frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( hDirACRend->frequency_axis, output_Fs, hSpatParamRendCom->num_freq_bands ); +#endif if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 && nchan_transport == 2 ) { @@ -8992,7 +9002,16 @@ static ivas_error ivas_masa_ext_rend_parambin_init( } /* Always open frequency domain decorrelator */ +#ifdef IVAS_FLOAT_FIXED + Word16 frequency_axis_fx[CLDFB_NO_CHANNELS_MAX]; + ivas_dirac_dec_get_frequency_axis_fx( frequency_axis_fx, output_Fs, nBins ); + + for (int i = 0; i < nBins; i++) { + frequency_axis[i] = frequency_axis_fx[i]; + } +#else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); +#endif if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), &( hDiracDecBin->h_freq_domain_decorr_ap_state ), nBins,