Loading lib_com/prot_fx2.h +8 −0 Original line number Diff line number Diff line Loading @@ -6797,6 +6797,14 @@ void init_tcx_cfg_fx( Decoder_State *stdec ); void generate_comfort_noise_dec_hf_ivas_fx( Word32 **bufferReal, /* o : matrix to real part of input bands */ Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const Word16 cng_coh_flag /* i : CNG Flag for coherence handling */ ); /* Generate the comfort noise based on the target noise level */ void generate_masking_noise(Word16 *timeDomainBuffer, /* i/o: time-domain signal */ Word16 Q, Loading lib_dec/acelp_core_dec.c +82 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,10 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "prot_fx2.h" #endif #include "math.h" /*-------------------------------------------------------------------* * acelp_core_dec() Loading Loading @@ -1623,8 +1627,29 @@ ivas_error acelp_core_dec( /* check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { #ifdef IVAS_FLOAT_FIXED Word16 old_len_ana, old_len_bpf; Word16 new_len; // The following lines are to calculate the length of the buffers before and // after calling the function for fixed pt conversion. The calculations are taken // based on the logic used in resampleCldfb_ivas_fx old_len_ana = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; old_len_bpf = st->cldfbBPF->p_filter_length - st->cldfbBPF->no_channels; new_len = 9 * (int16_t)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f); floatToFixed_arrL(st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q11, old_len_ana); floatToFixed_arrL(st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, Q10, old_len_bpf); resampleCldfb_ivas_fx( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); resampleCldfb_ivas_fx( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); fixedToFloat_arrL(st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, Q11, new_len); fixedToFloat_arrL(st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, Q10, new_len); #else resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); #endif if ( st->ini_frame > 0 ) { Loading Loading @@ -1655,6 +1680,41 @@ ivas_error acelp_core_dec( if ( !( st->element_mode == IVAS_CPE_MDCT && st->bpf_off ) ) { #ifdef IVAS_FLOAT_FIXED ///////////////////////////////////////////////////////////////////////////// Word16 pst_old_syn_exp; Word16 tmp_syn_exp; Word16 tmp_syn_fx[1]; // temporary. just one element because retro_interp4_5 only accesses syn[0] // Get exponents. f2me_buf_16(st->hBPF->pst_old_syn, st->hBPF->pst_old_syn_fx, &pst_old_syn_exp, NBPSF_PIT_MAX); f2me_16(syn[0], &tmp_syn_fx[0], &tmp_syn_exp); tmp_syn_exp = s_max(tmp_syn_exp, pst_old_syn_exp); // max exp btween syn and pst_old_syn // Float to fix for (i = 0; i < NBPSF_PIT_MAX; i++) { st->hBPF->pst_old_syn_fx[i] = (Word16)(st->hBPF->pst_old_syn[i] * pow(2, 15 - tmp_syn_exp)); } tmp_syn_fx[0] = (Word16)(syn[0] * pow(2, 15 - tmp_syn_exp)); ///////////////////////////////////////////////////////////////////////////// test(); IF ( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) { IF ( EQ_16( st->L_frame, L_FRAME ) ) { retro_interp5_4_fx( st->hBPF->pst_old_syn_fx ); } ELSE IF ( EQ_16( st->L_frame, L_FRAME16k ) ) { retro_interp4_5_fx( tmp_syn_fx, st->hBPF->pst_old_syn_fx ); } } // Fixed to float me2f_buf_16(st->hBPF->pst_old_syn_fx, tmp_syn_exp, st->hBPF->pst_old_syn, NBPSF_PIT_MAX); #else if ( st->L_frame != st->last_L_frame && st->last_codec_mode != MODE2 ) { if ( st->L_frame == L_FRAME ) Loading @@ -1666,7 +1726,7 @@ ivas_error acelp_core_dec( retro_interp4_5( syn, st->hBPF->pst_old_syn ); } } #endif /* bass post-filter */ bass_psfilter( st->hBPF, st->Opt_AMR_WB, syn, st->L_frame, pitch_buf, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, st->coder_type, bpf_error_signal ); } Loading Loading @@ -1709,7 +1769,28 @@ ivas_error acelp_core_dec( /*WB/SWB-FD_CNG*/ if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) ) { #ifdef IVAS_FLOAT_FIXED /* Float to fixed */ f2me_buf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt, st->hFdCngDec->hFdCngCom->cngNoiseLevel, &st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, FFTCLDFBLEN); // NOTE: this should be removed later. st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp; Word16 tmpBufferScale = 0; generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); /* Fixed to float */ FOR(i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++) { FOR(Word16 j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++) { realBuffer[i][j] = me2f(realBuffer_fx[i][j], tmpBufferScale + 15); imagBuffer[i][j] = me2f(imagBuffer_fx[i][j], tmpBufferScale + 15); } } #else generate_comfort_noise_dec_hf_flt( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); #endif if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) { Loading lib_dec/fd_cng_dec_fx.c +129 −0 Original line number Diff line number Diff line Loading @@ -3547,6 +3547,135 @@ generate_comfort_noise_dec_hf ( } void generate_comfort_noise_dec_hf_ivas_fx( Word32 **bufferReal, /* o : matrix to real part of input bands */ Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const Word16 cng_coh_flag /* i : CNG Flag for coherence handling */ ) { Word16 i, j, s, sc, sn; Word16 scaleCLDFB; Word32 sqrtNoiseLevel; Word16 randGaussExp; Word16 cngNoiseLevelExp; Word16 *seed; Word16 *seed2; Word16 c1, c2; Word32 *ptr_level; Word32 *cngNoiseLevel; Word32 tmp1, tmp2; cngNoiseLevel = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; move16(); ptr_level = cngNoiseLevel; seed = &( hFdCngCom->seed ); /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); seed2 = &( hFdCngCom->seed ); c1 = 0; move16(); c2 = 0; move16(); sc = 0; move16(); IF( cng_coh_flag ) { seed2 = &( hFdCngCom->seed2 ); s = 0; move16(); c1 = Sqrt16( hFdCngCom->coherence_fx, &s ); c1 = shl( c1, s ); // Q15 s = 0; move16(); c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s ); c2 = shl( c2, s ); // Q15 } sn = 0; move16(); IF( s_and( cngNoiseLevelExp, 1 ) != 0 ) { sn = add( sn, 1 ); cngNoiseLevelExp = add( cngNoiseLevelExp, sn ); move16(); } randGaussExp = CNG_RAND_GAUSS_SHIFT; move16(); /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */ IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) { sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp ); move16(); assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 ); FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ ) { FOR( i = 0; i < hFdCngCom->numSlots; i++ ) { /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ s = 0; move16(); sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); IF( cng_coh_flag ) { tmp1 = rand_gauss( seed ); move16(); tmp2 = rand_gauss( seed2 ); move16(); bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); move32(); bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s ); move32(); tmp1 = rand_gauss( seed ); move16(); tmp2 = rand_gauss( seed2 ); move16(); bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); move32(); bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s ); move32(); } ELSE { /* Real part in CLDFB band */ bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); move32(); /* Imaginary part in CLDFB band */ bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); move32(); } } ptr_level = ptr_level + 1; } *bufferScale = sub( sc, 15 ); } return; } /* generate_masking_noise Loading Loading
lib_com/prot_fx2.h +8 −0 Original line number Diff line number Diff line Loading @@ -6797,6 +6797,14 @@ void init_tcx_cfg_fx( Decoder_State *stdec ); void generate_comfort_noise_dec_hf_ivas_fx( Word32 **bufferReal, /* o : matrix to real part of input bands */ Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const Word16 cng_coh_flag /* i : CNG Flag for coherence handling */ ); /* Generate the comfort noise based on the target noise level */ void generate_masking_noise(Word16 *timeDomainBuffer, /* i/o: time-domain signal */ Word16 Q, Loading
lib_dec/acelp_core_dec.c +82 −1 Original line number Diff line number Diff line Loading @@ -45,6 +45,10 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "prot_fx2.h" #endif #include "math.h" /*-------------------------------------------------------------------* * acelp_core_dec() Loading Loading @@ -1623,8 +1627,29 @@ ivas_error acelp_core_dec( /* check if the CLDFB works on the right sample rate */ if ( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ) != st->L_frame ) { #ifdef IVAS_FLOAT_FIXED Word16 old_len_ana, old_len_bpf; Word16 new_len; // The following lines are to calculate the length of the buffers before and // after calling the function for fixed pt conversion. The calculations are taken // based on the logic used in resampleCldfb_ivas_fx old_len_ana = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; old_len_bpf = st->cldfbBPF->p_filter_length - st->cldfbBPF->no_channels; new_len = 9 * (int16_t)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f); floatToFixed_arrL(st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q11, old_len_ana); floatToFixed_arrL(st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, Q10, old_len_bpf); resampleCldfb_ivas_fx( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); resampleCldfb_ivas_fx( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); fixedToFloat_arrL(st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, Q11, new_len); fixedToFloat_arrL(st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, Q10, new_len); #else resampleCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); resampleCldfb_ivas( st->cldfbBPF, st->L_frame * FRAMES_PER_SEC ); #endif if ( st->ini_frame > 0 ) { Loading Loading @@ -1655,6 +1680,41 @@ ivas_error acelp_core_dec( if ( !( st->element_mode == IVAS_CPE_MDCT && st->bpf_off ) ) { #ifdef IVAS_FLOAT_FIXED ///////////////////////////////////////////////////////////////////////////// Word16 pst_old_syn_exp; Word16 tmp_syn_exp; Word16 tmp_syn_fx[1]; // temporary. just one element because retro_interp4_5 only accesses syn[0] // Get exponents. f2me_buf_16(st->hBPF->pst_old_syn, st->hBPF->pst_old_syn_fx, &pst_old_syn_exp, NBPSF_PIT_MAX); f2me_16(syn[0], &tmp_syn_fx[0], &tmp_syn_exp); tmp_syn_exp = s_max(tmp_syn_exp, pst_old_syn_exp); // max exp btween syn and pst_old_syn // Float to fix for (i = 0; i < NBPSF_PIT_MAX; i++) { st->hBPF->pst_old_syn_fx[i] = (Word16)(st->hBPF->pst_old_syn[i] * pow(2, 15 - tmp_syn_exp)); } tmp_syn_fx[0] = (Word16)(syn[0] * pow(2, 15 - tmp_syn_exp)); ///////////////////////////////////////////////////////////////////////////// test(); IF ( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) { IF ( EQ_16( st->L_frame, L_FRAME ) ) { retro_interp5_4_fx( st->hBPF->pst_old_syn_fx ); } ELSE IF ( EQ_16( st->L_frame, L_FRAME16k ) ) { retro_interp4_5_fx( tmp_syn_fx, st->hBPF->pst_old_syn_fx ); } } // Fixed to float me2f_buf_16(st->hBPF->pst_old_syn_fx, tmp_syn_exp, st->hBPF->pst_old_syn, NBPSF_PIT_MAX); #else if ( st->L_frame != st->last_L_frame && st->last_codec_mode != MODE2 ) { if ( st->L_frame == L_FRAME ) Loading @@ -1666,7 +1726,7 @@ ivas_error acelp_core_dec( retro_interp4_5( syn, st->hBPF->pst_old_syn ); } } #endif /* bass post-filter */ bass_psfilter( st->hBPF, st->Opt_AMR_WB, syn, st->L_frame, pitch_buf, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, st->coder_type, bpf_error_signal ); } Loading Loading @@ -1709,7 +1769,28 @@ ivas_error acelp_core_dec( /*WB/SWB-FD_CNG*/ if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) ) { #ifdef IVAS_FLOAT_FIXED /* Float to fixed */ f2me_buf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt, st->hFdCngDec->hFdCngCom->cngNoiseLevel, &st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, FFTCLDFBLEN); // NOTE: this should be removed later. st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp; Word16 tmpBufferScale = 0; generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); /* Fixed to float */ FOR(i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++) { FOR(Word16 j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++) { realBuffer[i][j] = me2f(realBuffer_fx[i][j], tmpBufferScale + 15); imagBuffer[i][j] = me2f(imagBuffer_fx[i][j], tmpBufferScale + 15); } } #else generate_comfort_noise_dec_hf_flt( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); #endif if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) { Loading
lib_dec/fd_cng_dec_fx.c +129 −0 Original line number Diff line number Diff line Loading @@ -3547,6 +3547,135 @@ generate_comfort_noise_dec_hf ( } void generate_comfort_noise_dec_hf_ivas_fx( Word32 **bufferReal, /* o : matrix to real part of input bands */ Word32 **bufferImag, /* o : matrix to imaginary part of input bands */ Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ const Word16 cng_coh_flag /* i : CNG Flag for coherence handling */ ) { Word16 i, j, s, sc, sn; Word16 scaleCLDFB; Word32 sqrtNoiseLevel; Word16 randGaussExp; Word16 cngNoiseLevelExp; Word16 *seed; Word16 *seed2; Word16 c1, c2; Word32 *ptr_level; Word32 *cngNoiseLevel; Word32 tmp1, tmp2; cngNoiseLevel = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp; move16(); ptr_level = cngNoiseLevel; seed = &( hFdCngCom->seed ); /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); seed2 = &( hFdCngCom->seed ); c1 = 0; move16(); c2 = 0; move16(); sc = 0; move16(); IF( cng_coh_flag ) { seed2 = &( hFdCngCom->seed2 ); s = 0; move16(); c1 = Sqrt16( hFdCngCom->coherence_fx, &s ); c1 = shl( c1, s ); // Q15 s = 0; move16(); c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s ); c2 = shl( c2, s ); // Q15 } sn = 0; move16(); IF( s_and( cngNoiseLevelExp, 1 ) != 0 ) { sn = add( sn, 1 ); cngNoiseLevelExp = add( cngNoiseLevelExp, sn ); move16(); } randGaussExp = CNG_RAND_GAUSS_SHIFT; move16(); /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */ IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) { sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp ); move16(); assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 ); FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ ) { FOR( i = 0; i < hFdCngCom->numSlots; i++ ) { /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */ s = 0; move16(); sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); IF( cng_coh_flag ) { tmp1 = rand_gauss( seed ); move16(); tmp2 = rand_gauss( seed2 ); move16(); bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); move32(); bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s ); move32(); tmp1 = rand_gauss( seed ); move16(); tmp2 = rand_gauss( seed2 ); move16(); bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); move32(); bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s ); move32(); } ELSE { /* Real part in CLDFB band */ bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); move32(); /* Imaginary part in CLDFB band */ bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); move32(); } } ptr_level = ptr_level + 1; } *bufferScale = sub( sc, 15 ); } return; } /* generate_masking_noise Loading