Loading lib_com/ivas_prot_fx.h +22 −0 Original line number Diff line number Diff line Loading @@ -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 lib_com/lsf_tools.c +78 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 lib_dec/fd_cng_dec.c +24 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "ivas_prot.h" #include "ivas_rom_dec.h" #include "prot_fx2.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------- * Local constants Loading Loading @@ -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 ) Loading lib_dec/ivas_core_dec.c +4 −0 Original line number Diff line number Diff line Loading @@ -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 ); Loading lib_dec/ivas_decision_matrix_dec.c +534 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "prot.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() Loading @@ -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 */ Loading Loading @@ -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 Loading
lib_com/ivas_prot_fx.h +22 −0 Original line number Diff line number Diff line Loading @@ -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
lib_com/lsf_tools.c +78 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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
lib_dec/fd_cng_dec.c +24 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include "ivas_prot.h" #include "ivas_rom_dec.h" #include "prot_fx2.h" #include "ivas_prot_fx.h" /*------------------------------------------------------------------- * Local constants Loading Loading @@ -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 ) Loading
lib_dec/ivas_core_dec.c +4 −0 Original line number Diff line number Diff line Loading @@ -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 ); Loading
lib_dec/ivas_decision_matrix_dec.c +534 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include "prot.h" #include "ivas_cnst.h" #include "wmc_auto.h" #include "ivas_prot_fx.h" /*-----------------------------------------------------------------* * ivas_decision_matrix_dec() Loading @@ -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 */ Loading Loading @@ -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