diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 9a9b3417f2e0e8d73cbc388a8a1158a53604d072..f5cdaea66e3adf76b1a085da91235a9fd44d5ee2 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -1425,6 +1425,7 @@ enum #define NB_LEADER 36 #define NB_LDQ4 27 #define FAC_LOG2 3.321928095f +#define FAC_LOG2_BY10_Q16 21771 #define NSV_MAX 34 /* maximal number of sub-vectors used by the AVQ */ diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index bd27d2137a5234757c747e4b90270f0c69c67bbf..c3506838f6c0118e087a034043510fd2250b9b56 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -746,7 +746,7 @@ void edxt_fx( move32(); } - y[sub( Nm1, imult1616( Nm1, shl( kernelType, 1 ) ) )] = L_shr( re[0], 1 ); + y[sub( Nm1, imult1616( Nm1, shr( kernelType, 1 ) ) )] = L_shr( re[0], 1 ); move32(); } ELSE /* inverse II = III */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8d847926986ba33c4b22c5f9e902be4bf851faa6..c76143a5e4fdc46182c083be8c8dfe97936e2191 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -317,8 +317,8 @@ ivas_error pre_proc_ivas( const int16_t loc_harm, /* i : harmonicity flag */ const float cor_map_sum, /* i : speech/music clasif. parameter */ const int16_t vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO */ - const float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ - const float fft_buff[2 * L_FFT], /* i : FFT buffer */ + /*const*/ float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ + /*const*/ float fft_buff[2 * L_FFT], /* i : FFT buffer */ const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ const int16_t vad_hover_flag, /* i : VAD hangover flag */ const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ @@ -635,6 +635,7 @@ ivas_error ivas_core_dec( #endif +#ifndef IVAS_FLOAT_FIXED void encod_gen_2sbfr( Encoder_State *st, /* i/o: state structure */ const float speech[], /* i : input speech */ @@ -650,6 +651,7 @@ void encod_gen_2sbfr( const int16_t tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const float tdm_Pri_pitch_buf[] /* i : pitch values for primary channel */ ); +#endif void decod_gen_2sbfr( Decoder_State *st, /* i/o: decoder static memory */ @@ -799,6 +801,7 @@ int16_t ivas_acelp_tcx20_switching( const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ); +#ifndef IVAS_FLOAT_FIXED void ivas_decision_matrix_enc( Encoder_State *st, /* i/o: encoder state structure */ const int32_t element_brate, /* i : element bitrate */ @@ -806,6 +809,16 @@ void ivas_decision_matrix_enc( const float enerBuffer[], /* i : energy buffer */ const int16_t last_element_mode /* i : last element mode */ ); +#else +void ivas_decision_matrix_enc_fx( + Encoder_State *st, /* i : encoder state structure */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 fft_buff[], /* i : FFT buffer */ + const Word32 enerBuffer[], /* i : energy buffer */ + Word16 enerBuffer_exp, + const Word16 last_element_mode /* i : last element mode */ +); +#endif #ifdef IVAS_FLOAT_FIXED void ivas_signaling_enc_fx( @@ -8001,8 +8014,8 @@ void ivas_omasa_dirac_rend_jbm( #ifdef IVAS_FLOAT_FIXED void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( Decoder_Struct *st_ivas, - Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/ Word16 *cldfb_buf_q, const Word16 nBins, const Word16 subframe diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index d74647545f9b085d3ca1ada04c6dc3de2903efa5..59dc816a1f79dc167cd9a0accf34f749c7ecc119 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2653,6 +2653,14 @@ void ivas_param_mc_metadata_open_fx( HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC /* o : handle for the Parametric MC parameter coding state */ ); +Word16 mdct_classifier_ivas_fx( + Encoder_State *st, /* i/o: Encoder state variable */ + const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */ + const Word32 enerBuffer[], /* i : energy buffer */ + Word16 enerBuffer_exp, /* i: enenrgy buffer exponent */ + const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ +); + /*----------------------------------------------------------------------------------* * Range Coder prototypes *----------------------------------------------------------------------------------*/ @@ -2723,6 +2731,38 @@ void core_switching_pre_enc_ivas_fx( const Word16 active_cnt, /* i : active frame counter */ const Word16 last_element_mode /* i : last_element_mode */ ); + +void encod_gen_2sbfr( + Encoder_State *st, /* i/o: state structure */ + const Word16 speech[], /* i : input speech */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq[], /* i : LP coefficients */ + const Word16 *res, /* i : residual signal */ + Word16 *syn, /* i/o: core synthesis */ + Word16 *exc, /* i/o: current non-enhanced excitation */ + Word16 *exc2, /* i/o: current enhanced excitation */ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc, /* o : excitation for SWB TBE */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel */ + Word16 *Q_new ); + +void acelp_fast_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 cdk_index, /* i : codebook index */ + const Word16 dn_orig[L_SUBFR], + /* i : corr. between target and h[]. */ // Q_new + 1 + Word16 Q_dn, + const Word16 cn[L_SUBFR], + /* i : residual after long term prediction */ // Q_new + 1 + const Word16 H[L_SUBFR], + /* i : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1) + Word16 code[L_SUBFR], /* o : algebraic (fixed) codebook excitation */ + Word16 y[], /* o : filtered fixed codebook excitation */ + const Word16 L_subfr /* i : subframe length */ +); + #endif void ivas_mdct_quant_coder_fx( @@ -2740,16 +2780,43 @@ void ivas_mdct_tcx10_bit_distribution_fx( ); void QuantizeSpectrum_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - float gainlpc[], /* i : MDCT gains of the previous frame */ - float synth[], /* o : synthesis buffer */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - int16_t prm[], /* o : tcx parameters */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 A_fx[], /* i : quantized coefficients NxAz_q[M+1] */ + const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ + Word16 gainlpc_fx[], /* i : MDCT gains of the previous frame */ + Word16 gainlpc_e[], /* i : exponents of MDCT gains of the previous frame */ + Word16 synth[], /* o : synthesis buffer, Q0 */ + const Word16 nb_bits, /* i : bit budget */ + const Word16 tnsSize, /* i : number of tns parameters put into prm */ + Word16 prm[], /* o : tcx parameters */ + const Word16 frame_cnt, /* i : frame counter in the super_frame */ + CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ +); + +void InternalTCXDecoder_fx( + Encoder_State *st, /* i/o: state handle */ + const Word16 frame_cnt, /* i : frame counter in the super_frame */ + const Word16 L_frameTCX, /* i : full frame length */ + const Word16 L_frame, /* i : frame length */ + const Word16 L_spec, /* i : length of the coded spectrum */ + const Word16 tcx_offset, /* i : folding point offset relative to the end of the previous frame */ + const Word16 noiseFillingBorder, /* i : noise filling border */ + const Word32 *x_quant_fx, /* i : quantized spectrum */ + const Word32 ener_fx, /* i : energy of the quantized spectrum */ + const Word16 ener_e, /* i : energy of the quantized spectrum exponent */ + Word16 lf_deemph_fact_fx[], /* i/o: low frequency deemphasis factors */ + const Word16 fac_ns_fx, /* i : noise filling level, Q15 */ + const Word16 nf_seed, /* i : noise filling random seed, Q0 */ + const Word16 *A_fx, /* i : LPC representation of the FDNS gains */ + Word16 gainlpc_fx[], /* i/o: FDNS gains */ + Word16 gainlpc_e[], /* i/o: FDNS gains exponent */ + const Word16 hm_active, /* i : flag indicating if the harmonic model is active */ + Word16 gain_tcx_fx, /* i/o: global gain / quantized global gain */ + Word16 *gain_tcx_e, /* i/o: global gain / quantized global gain exponent */ + Word32 spectrum_fx[], /* o : dequantized spectrum */ + Word16 *spectrum_e, /* o : dequantized spectrum */ + Word16 synth[], /* o : time domain signal */ + Word16 *gain_tcx_q /* o : quantized global gain (at low bitrates) */ ); #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index d1892c0b1ea6a24fe27df4618ef54bce05d7ce43..f9b45da970a07f61f5cd8d069afc55278ee24d99 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1746,6 +1746,17 @@ void wtda_fx( const Word16 L /* i : length */ ); +#ifdef IVAS_FLOAT_FIXED +void wtda_ext_fx( + const Word16 *new_audio, /* i : input audio (Q_in) */ + Word16 *wtda_audio, /* o : windowed audio (Q_in) */ + const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ + const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ + const Word16 L, /* i : length */ + const UWord16 kernel_type /* i : transform kernel type (0 - 3) */ +); +#endif + /*========================================================================================================/ swb_bwe_com_lr_fx.c /========================================================================================================*/ @@ -3947,6 +3958,19 @@ void mdct_window_aldo( // tcx_utils.c Word16 getInvFrameLen( const Word16 L_frame ); /* returns 1/L_frame in Q21 format */ +#ifdef IVAS_FLOAT_FIXED +void tcx_get_windows( + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ + const Word16 left_mode, /* i: overlap mode of left window half */ + const Word16 right_mode, /* i: overlap mode of right window half */ + Word16 *left_overlap, /* o: left overlap length */ + const PWord16 **left_win, /* o: left overlap window */ + Word16 *right_overlap, /* o: right overlap length */ + const PWord16 **right_win, /* o: right overlap window */ + const Word8 fullband /* i: fullband flag */ +); +#endif + void WindowSignal( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word16 offset, /* i : left folding point offset relative to the i signal pointer */ @@ -7479,6 +7503,7 @@ void HQ_nbfec_init_fx( HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */ ); +void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ); // FEC_HQ_phase_ecu_fx.c void hq_ecu_fx( @@ -10770,4 +10795,18 @@ Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx( Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */ ); + +void FEC_encode_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation */ + const Word16 coder_type, /* i : type of coder */ + Word16 clas, /* i : signal clas for current frame */ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6 */ + const Word16 *res, /* i : LP residual signal frame */ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ + const Word16 L_frame, /* i : Frame length */ + const Word32 total_brate, /* i : total codec bitrate */ + const Word16 Q_synth /* i : input scaling */ +); #endif diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c index 19082fe248dfe07482fe38c342437d8e17495920..1d3ddc310bf3ecc764f550ed84ab3bf4adee2fd8 100644 --- a/lib_com/tcx_utils_fx.c +++ b/lib_com/tcx_utils_fx.c @@ -39,7 +39,7 @@ Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */ * * * ------------------------------------------------------------------ - */ -static void tcx_get_windows( +void tcx_get_windows( TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */ const Word16 left_mode, /* i: overlap mode of left window half */ const Word16 right_mode, /* i: overlap mode of right window half */ diff --git a/lib_com/wtda_fx.c b/lib_com/wtda_fx.c index b20771f8cec8d7bb6f612290256471ea1d07161e..12ca93032d7e69fa30d7062fb39fb10aed370992 100644 --- a/lib_com/wtda_fx.c +++ b/lib_com/wtda_fx.c @@ -508,3 +508,200 @@ void wtda_ext( } #endif + +#ifdef IVAS_FLOAT_FIXED +void wtda_ext_fx( + const Word16 *new_audio, /* i : input audio (Q_in) */ + Word16 *wtda_audio, /* o : windowed audio (Q_in) */ + const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */ + const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */ + const Word16 L, /* i : length */ + const UWord16 kernel_type /* i : transform kernel type (0 - 3) */ +) +{ + Word16 i, decimate, decay; + Word16 n, windecay48, windecay16; + const Word16 *allsig_l, *allsig_r; + Word16 win_right[R2_48]; + Word16 win_int_left[R1_16]; + Word16 win_left[R1_48]; + Word16 win_int_right[R2_16]; + + tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L ); + + decimate = 1; /* L_FRAME48k */ + move16(); + decay = 0; + move16(); + windecay48 = ( 2 * ( (Word64) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48; + move16(); + + test(); + IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) ) + { + decimate = 3; + move16(); + decay = 1; + move16(); + } + ELSE IF( EQ_16( L, L_FRAME8k ) ) + { + decimate = 6; + move16(); + decay = 2; + move16(); + } + + n = extract_l( Mpy_32_32( L, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); + move16(); + + windecay16 = ( 2 * ( L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16; + move16(); + + allsig_r = new_audio + n; + allsig_l = new_audio + n - L; + + IF( EQ_16( L, L_FRAME32k ) ) + { + IF( UL_and( kernel_type, 1 ) ) + { + FOR( i = 0; i < L / 2 - n; i += 2 ) + { + wtda_audio[i] = round_fx( L_mac( L_mult( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ), + allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in + move16(); + wtda_audio[i + 1] = round_fx( L_mac( L_mult( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ), + allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in + move16(); + } + } + ELSE + { + FOR( i = 0; i < L / 2 - n; i += 2 ) + { + wtda_audio[i] = round_fx( L_msu( L_mult( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ), + allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in + move16(); + wtda_audio[i + 1] = round_fx( L_msu( L_mult( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ), + allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in + move16(); + } + } + + FOR( i = L / 2 - n; i < L / 2; i += 2 ) + { + wtda_audio[i] = negate( allsig_r[L / 2 - i - 1] ); // q_in + move16(); + wtda_audio[i + 1] = negate( allsig_r[L / 2 - ( i + 1 ) - 1] ); // q_in + move16(); + } + + IF( GE_32( kernel_type, 2 ) ) + { + FOR( i = 0; i < n; i += 2 ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ), + new_audio[n - i - 1], MAX16B ) ); // q_in + move16(); + wtda_audio[i + L / 2 + 1] = round_fx( L_msu( L_mult( negate( allsig_l[i + 1] ), win_int_left[i / 2] ), + new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in + move16(); + } + + FOR( i = n; i < L / 2; i += 2 ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ), + allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in + move16(); + wtda_audio[i + L / 2 + 1] = round_fx( L_msu( L_mult( negate( allsig_l[i + 1] ), win_int_left[i / 2] ), + allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in + move16(); + } + } + ELSE + { + FOR( i = 0; i < n; i += 2 ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ), + new_audio[n - i - 1], MAX16B ) ); // q_in + move16(); + wtda_audio[i + L / 2 + 1] = round_fx( L_msu( L_mult( allsig_l[i + 1], win_int_left[i / 2] ), + new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in + move16(); + } + + FOR( i = n; i < L / 2; i += 2 ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ), + allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in + move16(); + wtda_audio[i + L / 2 + 1] = round_fx( L_msu( L_mult( allsig_l[i + 1], win_int_left[i / 2] ), + allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in + move16(); + } + } + } + ELSE + { + IF( UL_and( kernel_type, 1 ) ) + { + FOR( i = 0; i < L / 2 - n; i++ ) + { + wtda_audio[i] = round_fx( L_mac( L_mult( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ), + allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in + move16(); + } + } + ELSE + { + FOR( i = 0; i < L / 2 - n; i++ ) + { + wtda_audio[i] = round_fx( L_msu( L_mult( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ), + allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in + move16(); + } + } + + FOR( i = L / 2 - n; i < L / 2; i++ ) + { + wtda_audio[i] = negate( allsig_r[L / 2 - i - 1] ); // q_in + move16(); + } + + IF( GE_32( kernel_type, 2 ) ) + { + FOR( i = 0; i < n; i++ ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( negate( allsig_l[i] ), win_left[i * decimate + decay] ), + new_audio[n - i - 1], MAX16B ) ); // q_in + move16(); + } + + FOR( i = n; i < L / 2; i++ ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( negate( allsig_l[i] ), win_left[i * decimate + decay] ), + allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in + move16(); + } + } + ELSE + { + FOR( i = 0; i < n; i++ ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( allsig_l[i], win_left[i * decimate + decay] ), + new_audio[n - i - 1], MAX16B ) ); // q_in + move16(); + } + + FOR( i = n; i < L / 2; i++ ) + { + wtda_audio[i + L / 2] = round_fx( L_msu( L_mult( allsig_l[i], win_left[i * decimate + decay] ), + allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in + move16(); + } + } + } + + return; +} +#endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4055bde4c8cecf7530f0c1d69819ad44ad65135f..4575cf543928342a86540aee792b2d0767bed53b 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1339,7 +1339,7 @@ typedef struct ivas_masa_decoder_data_struct #ifndef IVAS_FLOAT_FIXED float dir_decode_quality; #else - Word16 dir_decode_quality_fx; /* Q15 */ + Word16 dir_decode_quality_fx; /* Q15 */ #endif } MASA_DECODER_DATA; @@ -1361,8 +1361,8 @@ typedef struct ivas_masa_ism_data_structure float energy_ratio_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; #else - Word32 energy_ratio_ism_fx[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; /* Q30 */ - Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ + Word32 energy_ratio_ism_fx[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX]; /* Q30 */ + Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ #endif int16_t azimuth_ism_edited[MAX_NUM_OBJECTS]; @@ -1377,14 +1377,14 @@ typedef struct ivas_masa_ism_data_structure float q_azimuth_old[MAX_NUM_OBJECTS]; float q_elevation_old[MAX_NUM_OBJECTS]; #else - Word32 q_azimuth_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ - Word32 q_elevation_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ + Word32 q_azimuth_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ + Word32 q_elevation_old_fx[MAX_NUM_OBJECTS]; /* Q22 */ #endif #ifndef IVAS_FLOAT_FIXED float ismPreprocMatrix[2][2][CLDFB_NO_CHANNELS_MAX]; #else - Word16 ismPreprocMatrix_fx[2][2][CLDFB_NO_CHANNELS_MAX]; /* Q15 */ + Word16 ismPreprocMatrix_fx[2][2][CLDFB_NO_CHANNELS_MAX]; /* Q15 */ #endif uint8_t objectsMoved; #ifndef IVAS_FLOAT_FIXED @@ -1393,10 +1393,10 @@ typedef struct ivas_masa_ism_data_structure float preprocEneTarget[CLDFB_NO_CHANNELS_MAX]; float preprocEneRealized[CLDFB_NO_CHANNELS_MAX]; #else - Word32 eneMoveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; - Word32 enePreserveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; - Word32 preprocEneTarget_fx[CLDFB_NO_CHANNELS_MAX]; - Word32 preprocEneRealized_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 eneMoveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ + Word32 enePreserveIIR_fx[2][CLDFB_NO_CHANNELS_MAX]; /*Q-22*/ + Word32 preprocEneTarget_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ + Word32 preprocEneRealized_fx[CLDFB_NO_CHANNELS_MAX]; /*Q-19*/ #endif #ifndef IVAS_FLOAT_FIXED diff --git a/lib_enc/FEC_enc.c b/lib_enc/FEC_enc.c index 308c3b02decc1443acd5cf7e5a45ddd3394bf643..fe61b552d52fbf9c35c2988c78e592f14ca22322 100644 --- a/lib_enc/FEC_enc.c +++ b/lib_enc/FEC_enc.c @@ -42,12 +42,182 @@ #include "rom_com.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" +#include "prot_fx.h" +#endif + /*-------------------------------------------------------------------* * FEC_encode() * * Encoder supplementary information for FEC *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void FEC_encode_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ + const Word16 *synth, /* i : pointer to synthesized speech for E computation */ + const Word16 coder_type, /* i : type of coder */ + Word16 clas, /* i : signal clas for current frame */ + const Word16 *fpit, /* i : close loop fractional pitch buffer Q6 */ + const Word16 *res, /* i : LP residual signal frame */ + Word16 *last_pulse_pos, /* i/o: Position of the last pulse */ + const Word16 L_frame, /* i : Frame length */ + const Word32 total_brate, /* i : total codec bitrate */ + const Word16 Q_synth /* i : input scaling */ +) +{ + Word16 tmpS, index; + Word16 maxi, sign, tmp_FER_pitch; + Word32 enr_q, Ltmp; + Word16 exp_enrq; + + tmpS = 0; + move16(); + enr_q = 1; + move16(); + sign = 0; + move16(); + test(); + test(); + IF( GT_16( coder_type, UNVOICED ) && LT_16( coder_type, AUDIO ) && acelp_cfg.FEC_mode > 0 ) + { + /*-----------------------------------------------------------------* + * encode signal class (not needed for VC mode since it is clearly voiced) (2 bits) + *-----------------------------------------------------------------*/ + IF( NE_16( coder_type, VOICED ) ) + { + /* encode signal clas with 2 bits */ + test(); + IF( EQ_16( clas, UNVOICED_CLAS ) ) + { + index = 0; + move16(); + } + ELSE IF( EQ_16( clas, VOICED_TRANSITION ) || EQ_16( clas, UNVOICED_TRANSITION ) ) + { + index = 1; + move16(); + } + ELSE IF( EQ_16( clas, VOICED_CLAS ) ) + { + index = 2; + move16(); + } + ELSE + { + index = 3; + move16(); + } + push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS ); + } + + /*-----------------------------------------------------------------* + * encode frame energy (5 bits) + *-----------------------------------------------------------------*/ + test(); + IF( GT_16( acelp_cfg.FEC_mode, 1 ) ) /* GENERIC and VOICED frames */ + { + /* frame energy (maximum energy per pitch period for voiced frames or mean energy per sample over 2nd halframe for unvoiced frames) */ + /*frame_ener( L_frame, clas, synth, fpit[(L_frame>>6)-1], &enr_q, 0 );*/ + Word32 synth32[L_FRAME16k]; + Copy_Scale_sig_16_32( synth, synth32, L_FRAME16k, 0 ); + fer_energy_fx( L_frame, clas, synth32, Q_synth, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), &enr_q, L_frame ); + exp_enrq = sub( 31, shl( Q_synth, 1 ) ); + IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ + { + exp_enrq = 31; + move16(); + } + /* linearly quantize the energy in the range 0 : FEC_ENR_STEP : 96 dB */ + /*tmpS = (short)( 10.0 * log10( enr_q + 0.001f ) / FEC_ENR_STEP )*/ /*To be converted fl_2_fx*/ + + Ltmp = Mpy_32_32( BASOP_Util_Log10( enr_q, exp_enrq ), 894784853 /* 10 / FEC_ENR_STEP Q28 */ ); // Q 25 + 28 - 31 = Q22 + IF( Ltmp < 0 ) + { + tmpS = extract_l( L_negate( L_shr( L_negate( Ltmp ), Q22 ) ) ); + } + ELSE + { + tmpS = extract_l( L_shr( Ltmp, Q22 ) ); + } + + tmpS = s_min( tmpS, FEC_ENR_QLIMIT ); + tmpS = s_max( tmpS, 0 ); + + push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR ); + } + /*-----------------------------------------------------------------* + * Encode last glottal pulse position (8 bits) + *-----------------------------------------------------------------*/ + test(); + IF( GT_16( acelp_cfg.FEC_mode, 2 ) ) /* GENERIC frames */ + { + /* retrieve the last glottal pulse position of the previous frame */ + /* use the current pitch information to scale or not the quantization */ + tmp_FER_pitch = shr( fpit[0], 6 ); /* take the 1st subframe pit, since it is easier to get on decoder side */ + sign = 0; + move16(); + maxi = *last_pulse_pos; + move16(); + IF( maxi < 0 ) + { + sign = 1; + move16(); + /*maxi = -maxi; */ + maxi = negate( maxi ); + } + + if ( GE_16( tmp_FER_pitch, 128 ) ) + { + maxi = shr( maxi, 1 ); + } + + if ( GT_16( maxi, 127 ) ) + { + /* better not use the glottal pulse position at all instead of using a wrong pulse */ + /* can happen only with pitch > 254 and max pit = 289 and should happen very rarely */ + maxi = 0; + move16(); + } + + if ( EQ_16( sign, 1 ) ) + { + maxi = add( maxi, 128 ); /* use 8 bits (MSB represent the sign of the pulse) */ + } + + push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS ); + } + maxi = 0; + move16(); + + /* If bitrate < 24k4, then the pitch + is not represented in the same domain (12.k instead of 16k) */ + test(); + IF( GE_16( clas, VOICED_CLAS ) && GE_32( total_brate, ACELP_24k40 ) ) + { + /*maxi = findpulse( L_frame, res, (short)(fpit[(L_frame>>6)-1]), 0, &sign ); */ + maxi = findpulse_fx( L_frame, res, shr_r( fpit[sub( shr( L_frame, 6 ), 1 )], 6 ), 0, &sign ); + if ( EQ_16( sign, 1 ) ) + { + /*maxi = -maxi;*/ + maxi = negate( maxi ); + } + } + + *last_pulse_pos = maxi; + move16(); + } + ELSE + { + *last_pulse_pos = 0; + move16(); + } + + return; +} +#endif void FEC_encode( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP */ @@ -181,7 +351,6 @@ void FEC_encode( return; } - /*-------------------------------------------------------------------* * FEC_lsf_estim_enc() * diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 64caa1e9930ea484127145df472a8c152ea87966..463fa1fc5fa14180233bb3eacfac717446859085 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -43,6 +43,7 @@ #include "prot.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_rom_com.h" @@ -80,13 +81,21 @@ ivas_error acelp_core_enc( float tdm_lsfQ_PCh[M] /* i : Q LSFs for primary channel */ ) { - Word16 i, nBits; /* reserved bits */ - LPD_state_HANDLE hLPDmem; /* i/o: acelp memories */ - float old_exc_flt[L_EXC], *exc; /* excitation signal buffer */ - float lsf_new[M]; /* ISFs at the end of the frame */ - float Aq[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ - float syn[L_FRAME16k]; /* synthesis signal buffer */ - float res[L_FRAME16k]; /* Residual signal for FER protection */ + Word16 i, nBits; /* reserved bits */ + LPD_state_HANDLE hLPDmem; /* i/o: acelp memories */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fixed converstions + float old_exc_flt[L_EXC] = { 0 }, *exc; /* excitation signal buffer */ + float lsf_new[M] = { 0 }; /* ISFs at the end of the frame */ + float Aq[NB_SUBFR16k * ( M + 1 )] = { 0 }; /* A(z) quantized for the 4 subframes */ + float syn[L_FRAME16k] = { 0 }; /* synthesis signal buffer */ + float res[L_FRAME16k] = { 0 }; /* Residual signal for FER protection */ +#else + float old_exc_flt[L_EXC], *exc; /* excitation signal buffer */ + float lsf_new[M]; /* ISFs at the end of the frame */ + float Aq[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ + float syn[L_FRAME16k]; /* synthesis signal buffer */ + float res[L_FRAME16k]; /* Residual signal for FER protection */ +#endif // IVAS_FLOAT_FIXED_CONVERSIONS float exc2[L_FRAME16k]; /* enhanced excitation */ float Es_pred; /* predicited scaled innovation energy */ float tmp_noise; /* NB post-filter long-term noise energy*/ @@ -130,9 +139,9 @@ ivas_error acelp_core_enc( Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ - // Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ - Word16 Es_pred_fx; /* predicited scaled innovation energy */ - Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ + Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ + Word16 Es_pred_fx; /* predicited scaled innovation energy */ + Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ // Word16 tc_subfr_fx; /* TC sub-frame indication */ Word16 old_bwe_exc_fx[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ Word16 Q_old_bwe_exc; @@ -163,9 +172,9 @@ ivas_error acelp_core_enc( // Word16 next_force_sf_bck_fx; // Word32 q_env_fx[NUM_ENV_CNG]; // Word16 coder_type; - // Word16 exc3_fx[L_FRAME16k]; - // Word16 syn1_fx[L_FRAME16k]; - // Word16* tdm_Pri_pitch_buf_fx; + Word16 exc3_fx[L_FRAME16k]; + Word16 syn1_fx[L_FRAME16k]; + Word16 *tdm_Pri_pitch_buf_fx; Word16 att_fx; Word16 lsp_new_fx[M]; /* i : LSPs at the end of the frame */ @@ -214,14 +223,19 @@ ivas_error acelp_core_enc( Word16 inp_buff[L_FRAME16k + M + 1]; Word16 *inp_fx; inp_fx = &inp_buff[M + 1]; - Word16 e_mem_w0 = 0, q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; + Word16 q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); Q_new = Q_factor_arr( &inp[-M - 1], L_FRAME16k + M + 1 ); - floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); Q_new = s_min( Q_new, q_comm_Bin - ( QSCALE - 2 ) ); + Q_new = s_min( Q_new, 5 ); + floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, Q_new + Q_SCALE - 2, 128 ); floatToFixed_arrL( st->Bin_E, st->Bin_E_fx, Q_new + Q_SCALE - 2, 256 ); st->stab_fac_fx = float_to_fix16( st->stab_fac, Q15 ); + IF( hStereoTD ) + { + floatToFixed_arr( hStereoTD->tdm_Pri_pitch_buf, hStereoTD->tdm_Pri_pitch_buf_fx, Q6, 4 ); + } #endif ivas_error error; @@ -306,6 +320,8 @@ ivas_error acelp_core_enc( } tmp_noise = 0; + tmp_noise_fx = 0; + move16(); tc_subfr = -1; move16(); position = -1; @@ -349,6 +365,7 @@ ivas_error acelp_core_enc( tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; tdm_Pri_pitch_buf = hStereoTD->tdm_Pri_pitch_buf; + tdm_Pri_pitch_buf_fx = hStereoTD->tdm_Pri_pitch_buf_fx; } ELSE { @@ -362,6 +379,7 @@ ivas_error acelp_core_enc( } tdm_Pitch_reuse_flag = 0; tdm_Pri_pitch_buf = NULL; + tdm_Pri_pitch_buf_fx = NULL; } move16(); move16(); @@ -374,8 +392,6 @@ ivas_error acelp_core_enc( test(); test(); - UNUSED_PARAM( bwe_exc_fx ); - UNUSED_PARAM( exc_fx ); IF( NE_16( st->last_L_frame, st->L_frame ) && ( st->last_core == ACELP_CORE || EQ_16( st->last_core, AMR_WB_CORE ) ) ) { /* in case of switching, do not apply BPF (flag employed also in updt_enc()) */ @@ -512,7 +528,17 @@ ivas_error acelp_core_enc( { if ( st->hTdCngEnc != NULL ) { - tmpF = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, exc, st->L_frame ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 tmpfx /*, CNG_att_fx*/; + st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q7 ); + Word16 Q_exc_l = Q_factor_arr( exc, st->L_frame ); + floatToFixed_arr( exc, exc_fx, Q_exc_l, st->L_frame ); +#endif + // tmpF = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, exc, st->L_frame ); + tmpfx = cng_energy_ivas_fx( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att_fx, exc_fx, st->L_frame, Q_exc_l ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + tmpF = fix16_to_float( tmpfx, Q8 ); +#endif i = (int16_t) ( ( tmpF + 2.0f ) * STEP_SID ); i = min( max( i, 0 ), 127 ); st->hTdCngEnc->old_enr_index = i; @@ -526,8 +552,26 @@ ivas_error acelp_core_enc( st->hTdCngEnc->burst_ho_cnt = 0; } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 Q_syn_l, Q_exc_l; + + Q_exc_l = Q_factor_arr( exc3, st->L_frame ); + floatToFixed_arr( exc3, exc3_fx, Q_exc_l, st->L_frame ); + + Q_syn_l = Q_factor_arr( hLPDmem->mem_syn3_flt, M ); + floatToFixed_arr( hLPDmem->mem_syn3_flt, hLPDmem->mem_syn3, Q_syn_l, M ); + + floatToFixed_arr( Aq, Aq_fx, NB_SUBFR16k * ( M + 1 ), Q12 ); +#endif /* synthesis at 12.8kHz sampling rate */ - syn_12k8( st->L_frame, Aq, exc3, syn1, hLPDmem->mem_syn3_flt, 1 ); + syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, Q_exc_l, Q_syn_l ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( Aq_fx, Aq, NB_SUBFR16k * ( M + 1 ), Q12 ); + fixedToFloat_arr( exc3_fx, exc, st->L_frame, Q_exc_l ); + fixedToFloat_arr( hLPDmem->mem_syn3, hLPDmem->mem_syn3_flt, Q_syn_l, M ); + fixedToFloat_arr( syn1_fx, syn1, Q_syn_l, st->L_frame ); +#endif /* reset the encoder */ CNG_reset_enc( st, pitch_buf, voice_factors, 0 ); @@ -581,8 +625,7 @@ ivas_error acelp_core_enc( { st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); st->hLPDmem->gc_threshold = float_to_fix16( st->hLPDmem->gc_threshold_flt, Q16 ); - f2me_buf_16( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, &st->hLPDmem->e_mem_syn, M ); - f2me_16( st->hLPDmem->mem_w0_flt, &st->hLPDmem->mem_w0, &e_mem_w0 ); + f2me_buf_16( &st->hLPDmem->mem_syn_flt[-1], &st->hLPDmem->mem_syn[-1], &st->hLPDmem->e_mem_syn, M + 1 ); // -1 to sync the exponent of mem_syn with mem_w0 } floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); @@ -600,17 +643,27 @@ ivas_error acelp_core_enc( st->lsfoldbfi1_fx[idx] = (Word16) ( st->lsfoldbfi1[idx] * 2.56f ); st->lsfoldbfi0_fx[idx] = (Word16) ( st->lsfoldbfi0[idx] * 2.56f ); } - Q_exc = Q_factor_arr( old_exc_flt, st->L_frame ); Q_old_bwe_exc = Q_factor_arr( old_bwe_exc, 1380 ); floatToFixed_arr( old_bwe_exc, old_bwe_exc_fx, Q_old_bwe_exc, 1380 ); + Q_exc = Q_factor_arr( old_exc_flt, st->L_frame ); hLPDmem->e_old_exc = Q_factor_arr( &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ) - 1; Q_exc = s_min( Q_exc, hLPDmem->e_old_exc ); - hLPDmem->e_old_exc = Q15 - hLPDmem->e_old_exc; + hLPDmem->e_old_exc = Q15 - Q_exc; floatToFixed_arr( &hLPDmem->old_exc_flt[-M - 1], &hLPDmem->old_exc[-M - 1], Q15 - hLPDmem->e_old_exc, L_EXC_MEM + M + 1 ); floatToFixed_arr16( old_exc_flt, old_exc_fx, Q_exc, st->L_frame ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); + + Word16 pitch_buf_fx[NB_SUBFR16k]; + Word16 voice_factors_fx[NB_SUBFR16k]; + floatToFixed_arr( voice_factors, voice_factors_fx, Q15, NB_SUBFR16k ); + st->hGSCEnc->Last_frame_ener_fx = floatToFixed_32( st->hGSCEnc->Last_frame_ener, Q4 ); + f2me_buf_16( st->hGSCEnc->last_exc_dct_in, st->hGSCEnc->last_exc_dct_in_fx, &st->hGSCEnc->Q_last_exc_dct_in, L_FRAME16k ); + st->hGSCEnc->Q_last_exc_dct_in = Q15 - st->hGSCEnc->Q_last_exc_dct_in; + st->hGSCEnc->last_ener_fx = (Word16) st->hGSCEnc->last_ener; + IF( st->hLPDmem ) + st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); #endif /*-----------------------------------------------------------------* * Configure ACELP bit allocation @@ -778,6 +831,22 @@ ivas_error acelp_core_enc( Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new + 1 ); push_indice( hBstr, IND_ES_PRED, i, nb_bits ); } + + /*------------------------------------------------------------* + * Encode excitation according to coding type + *------------------------------------------------------------*/ + Word16 Q_exc2 = add( Q_new, 1 ); + IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + { + IF( LE_16( st->coder_type, UNVOICED ) ) + { + tdm_low_rate_enc( st, Aq_fx, res_fx, syn_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, &Q_exc2 ); + } + ELSE /* GENERIC */ + { + encod_gen_2sbfr( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, &Q_exc2 ); + } + } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); tilt_code_bck = fix16_to_float( tilt_code_bck_fx, Q15 ); @@ -796,7 +865,7 @@ ivas_error acelp_core_enc( fixedToFloat_arr( lsp_new_bck_fx, lsp_new_bck, Q15, M ); fixedToFloat_arr( lsp_mid_bck_fx, lsp_mid_bck, Q15, M ); me2f_buf_16( mem_syn_bck_fx, st->hLPDmem->e_mem_syn, mem_syn_bck, M ); - mem_w0_bck = me2f( mem_w0_bck_fx, e_mem_w0 ); + mem_w0_bck = me2f( mem_w0_bck_fx, st->hLPDmem->e_mem_syn ); streaklimit = fixedToFloat( streaklimit_fx, Q15 ); fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); fixedToFloat_arr( lsp_mid_fx, lsp_mid, 15, M ); @@ -828,47 +897,24 @@ ivas_error acelp_core_enc( fixedToFloat_arr( old_bwe_exc_fx, old_bwe_exc, Q_old_bwe_exc, 1380 ); fixedToFloat_arr( res_fx, res, Q_new + 1, st->L_frame ); Es_pred = fix16_to_float( Es_pred_fx, Q8 ); -#endif -#endif - /*------------------------------------------------------------* - * Encode excitation according to coding type - *------------------------------------------------------------*/ - IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - IF( LE_16( st->coder_type, UNVOICED ) ) - { -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 pitch_buf_fx[NB_SUBFR]; - Word16 voice_factors_fx[NB_SUBFR16k]; - floatToFixed_arr( voice_factors, voice_factors_fx, Q15, NB_SUBFR16k ); - st->hGSCEnc->Last_frame_ener_fx = floatToFixed_32( st->hGSCEnc->Last_frame_ener, Q4 ); - f2me_buf_16( st->hGSCEnc->last_exc_dct_in, st->hGSCEnc->last_exc_dct_in_fx, &st->hGSCEnc->Q_last_exc_dct_in, L_FRAME16k ); - st->hGSCEnc->Q_last_exc_dct_in = Q15 - st->hGSCEnc->Q_last_exc_dct_in; - st->hGSCEnc->last_ener_fx = (Word16) st->hGSCEnc->last_ener; - IF( st->hLPDmem ) - st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); + me2f_buf_16( &st->hLPDmem->mem_w0, st->hLPDmem->e_mem_syn, &st->hLPDmem->mem_w0_flt, M + 1 ); + fixedToFloat_arr( exc_fx, exc, Q_exc, L_FRAME ); + fixedToFloat_arr( exc2_fx, exc2, Q_exc, L_FRAME16k ); + if ( st->hBWE_TD ) + fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_exc, L_FRAME32k ); + st->hGSCEnc->Last_frame_ener = fixedToFloat_32( st->hGSCEnc->Last_frame_ener_fx, Q4 ); + me2f_buf_16( st->hGSCEnc->last_exc_dct_in_fx, Q15 - st->hGSCEnc->Q_last_exc_dct_in, st->hGSCEnc->last_exc_dct_in, L_FRAME16k ); + fixedToFloat_arr( syn_fx, syn, Q_exc2, L_FRAME16k ); + fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, NB_SUBFR16k ); + fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR ); + tmp_noise = fix16_to_float( tmp_noise_fx, Q8 ); + IF( st->hLPDmem ) + st->hLPDmem->tilt_code_flt = fix16_to_float( st->hLPDmem->tilt_code, Q15 ); #endif - Word16 Q_exc2 = add( Q_new, 1 ); - tdm_low_rate_enc( st, Aq_fx, res_fx, syn_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, &Q_exc2 ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( exc_fx, exc, Q_exc, L_FRAME ); - if ( st->hBWE_TD ) - fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_exc, L_FRAME32k ); - st->hGSCEnc->Last_frame_ener = fixedToFloat_32( st->hGSCEnc->Last_frame_ener_fx, Q4 ); - me2f_buf_16( st->hGSCEnc->last_exc_dct_in_fx, Q15 - st->hGSCEnc->Q_last_exc_dct_in, st->hGSCEnc->last_exc_dct_in, L_FRAME16k ); - fixedToFloat_arr( syn_fx, syn, Q_exc2, L_FRAME16k ); - fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, NB_SUBFR16k ); - fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR ); - tmp_noise = fix16_to_float( tmp_noise_fx, Q8 ); - IF( st->hLPDmem ) - st->hLPDmem->tilt_code_flt = fix16_to_float( st->hLPDmem->tilt_code, Q15 ); #endif - } - else /* GENERIC */ - { - encod_gen_2sbfr( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); - } + if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + { } else if ( nelp_mode ) { @@ -959,8 +1005,7 @@ ivas_error acelp_core_enc( #else #ifdef IVAS_FLOAT_FIXED_CONVERSIONS // conv params from float to fix - Word16 Q_exc2 = Q_factor_arr( exc2, L_FRAME ); - Word16 exc2_fx[L_FRAME16k]; + Q_exc2 = Q_factor_arr( exc2, L_FRAME ); floatToFixed_arr( exc2, exc2_fx, Q_exc2, L_FRAME16k ); floatToFixed_arr( Aq, Aq_fx, 12, NB_SUBFR16k * ( M + 1 ) ); floatToFixed_arr( st->lspold_s, st->lspold_s_fx, 15, 16 ); @@ -995,8 +1040,18 @@ ivas_error acelp_core_enc( /*-----------------------------------------------------------------* * Encode supplementary information for Frame Error Concealment *-----------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 q_syn = Q_factor_arr( syn, L_FRAME16k ); + q_syn = min( q_syn, Q_factor_arr( res, L_FRAME16k ) ); + floatToFixed_arr16( syn, syn_fx, q_syn, L_FRAME16k ); + floatToFixed_arr16( pitch_buf, pitch_buf_fx, Q6, NB_SUBFR16k ); + floatToFixed_arr16( res, res_fx, q_syn, L_FRAME16k ); +#endif + FEC_encode_ivas_fx( hBstr, st->acelp_cfg, syn_fx, st->coder_type, st->clas, pitch_buf_fx, res_fx, &st->Last_pulse_pos, st->L_frame, st->total_brate, q_syn ); +#else FEC_encode( hBstr, st->acelp_cfg, syn, st->coder_type, st->clas, pitch_buf, res, &st->Last_pulse_pos, st->L_frame, st->total_brate ); +#endif if ( st->hBWE_TD != NULL ) { @@ -1044,7 +1099,37 @@ ivas_error acelp_core_enc( if ( !st->Opt_SC_VBR && ( st->idchan == 0 || st->element_mode != IVAS_CPE_TD || ( st->idchan == 1 && st->element_mode == IVAS_CPE_TD && st->tdm_LRTD_flag ) ) ) { /* Apply a non linearity to the SHB excitation */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + Word16 voice_factors_fx[NB_SUBFR16k]; + floatToFixed_arr16( voice_factors, voice_factors_fx, Q15, 5 ); + + st->hBWE_TD->bwe_non_lin_prev_scale_fx = floatToFixed( st->hBWE_TD->bwe_non_lin_prev_scale, Q30 ); + + Word32 bwe_exc_extended_fx[L_FRAME32k + NL_BUFF_OFFSET]; + Word16 q_bwe_exc = min( 14, Q_factor_arr( st->hBWE_TD->old_bwe_exc_extended, NL_BUFF_OFFSET ) ); + q_bwe_exc = min( q_bwe_exc, Q_factor_arr( bwe_exc, ( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ) - PIT16k_MAX * 2 ) ); + floatToFixed_arr16( bwe_exc, bwe_exc_fx, q_bwe_exc, ( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ) - PIT16k_MAX * 2 ); + floatToFixed_arr16( st->hBWE_TD->old_bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended_fx, q_bwe_exc, NL_BUFF_OFFSET ); + +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + + Copy_Scale_sig_16_32( st->hBWE_TD->old_bwe_exc_extended_fx, bwe_exc_extended_fx, NL_BUFF_OFFSET, 0 ); + non_linearity_ivas_fx( bwe_exc_fx, bwe_exc_extended_fx + NL_BUFF_OFFSET, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale_fx, q_bwe_exc, st->coder_type, voice_factors_fx, st->L_frame ); + // Q bwe_exc_extended_fx = 2 * Q bwe_exc_fx = 2 * q_bwe_exc + Copy_Scale_sig_32_16( bwe_exc_extended_fx + L_FRAME32k, st->hBWE_TD->old_bwe_exc_extended_fx, NL_BUFF_OFFSET, -q_bwe_exc ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + st->hBWE_TD->bwe_non_lin_prev_scale = fixedToFloat_32( st->hBWE_TD->bwe_non_lin_prev_scale_fx, Q30 ); + fixedToFloat_arrL( bwe_exc_extended_fx, bwe_exc_extended, 2 * q_bwe_exc, L_FRAME32k + NL_BUFF_OFFSET ); + fixedToFloat_arr( st->hBWE_TD->old_bwe_exc_extended_fx, st->hBWE_TD->old_bwe_exc_extended, q_bwe_exc, NL_BUFF_OFFSET ); + +#endif // IVAS_FLOAT_FIXED_CONVERSIONS +#else non_linearity( bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame ); +#endif // IVAS_FLOAT_FIXED } if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) @@ -1056,12 +1141,88 @@ ivas_error acelp_core_enc( /*-----------------------------------------------------------------* * Updates *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + Word16 pitch_buf_fx[NB_SUBFR16k]; + floatToFixed_arr16( pitch_buf, pitch_buf_fx, Q6, NB_SUBFR16k ); + floatToFixed_arr16( st->old_pitch_buf, st->old_pitch_buf_fx, Q6, 2 * NB_SUBFR16k ); + + Es_pred_fx = float_to_fix16( Es_pred, Q8 ); + floatToFixed_arr16( Aq, Aq_fx, 12, NB_SUBFR16k * ( M + 1 ) ); + floatToFixed_arr16( lsp_new, lsp_new_fx, 15, M ); + for ( i = 0; i < M; i++ ) + { + + lsf_new_fx[i] = (Word16) ( lsf_new[i] * 2.56f ); + }; + + Word16 q_old_exc = Q_factor_arr( old_exc_flt, L_EXC ); + floatToFixed_arr16( old_exc_flt, old_exc_fx, q_old_exc, L_EXC ); + st->hLPDmem->e_old_exc = sub( 15, q_old_exc ); + + Word16 q_old_bwe_exc; + IF( st->hBWE_TD != NULL ) + { + q_old_bwe_exc = Q_factor_arr( old_bwe_exc, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); + floatToFixed_arr16( old_bwe_exc, old_bwe_exc_fx, q_old_bwe_exc, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); + st->Q_exc = q_old_bwe_exc; + } + + IF( st->hGSCEnc != NULL ) + { + st->hGSCEnc->mid_dyn_fx = float_to_fix16( st->hGSCEnc->mid_dyn, Q7 ); + } + +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + + updt_enc_fx( st, old_exc_fx, pitch_buf_fx, Es_pred_fx, Aq_fx, lsf_new_fx, lsp_new_fx, old_bwe_exc_fx ); + +#endif // IVAS_FLOAT_FIXED updt_enc( st, old_exc_flt, pitch_buf, Es_pred, Aq, lsf_new, lsp_new, old_bwe_exc ); if ( st->hTdCngEnc != NULL && st->Opt_DTX_ON && st->core_brate > SID_2k40 ) { /* update CNG parameters in active frames */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + Word16 q_exc = Q_factor_arr( exc, L_EXC - L_EXC_MEM ); + q_exc = min( q_exc, Q_factor_arr( st->hTdCngEnc->cng_exc2_buf_flt, HO_HIST_SIZE * L_FFT ) ); + floatToFixed_arr16( exc, exc_fx, q_exc, L_EXC - L_EXC_MEM ); + floatToFixed_arr16( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, q_exc, HO_HIST_SIZE * L_FFT ); + + floatToFixed_arr32( st->hTdCngEnc->ho_ener_circ, st->hTdCngEnc->ho_ener_circ_fx, Q6, HO_HIST_SIZE ); + floatToFixed_arr32( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); + floatToFixed_arr16( st->hTdCngEnc->ho_lsp_circ, st->hTdCngEnc->ho_lsp_circ_fx, Q15, HO_HIST_SIZE * M ); + + // Backup + Word16 ho_circ_ptr = st->hTdCngEnc->ho_circ_ptr; + Word16 ho_circ_size = st->hTdCngEnc->ho_circ_size; + Word16 cng_buf_cnt = st->hTdCngEnc->cng_buf_cnt; + Word32 cng_brate_buf[HO_HIST_SIZE]; + for ( int j = 0; j < HO_HIST_SIZE; j++ ) + { + cng_brate_buf[j] = st->hTdCngEnc->cng_brate_buf[j]; + } + +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + + cng_params_upd_ivas_fx( lsp_new_fx, exc_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ_fx, q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + // Restore + st->hTdCngEnc->ho_circ_ptr = ho_circ_ptr; + st->hTdCngEnc->ho_circ_size = ho_circ_size; + st->hTdCngEnc->cng_buf_cnt = cng_buf_cnt; + for ( int j = 0; j < HO_HIST_SIZE; j++ ) + { + st->hTdCngEnc->cng_brate_buf[j] = cng_brate_buf[j]; + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS +#endif // IVAS_FLOAT_FIXED + cng_params_upd( lsp_new, exc, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ, &st->hTdCngEnc->ho_circ_size, st->hTdCngEnc->ho_lsp_circ, ENC, st->hTdCngEnc->ho_env_circ, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); if ( st->L_frame == L_FRAME ) diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index d4a5fefa4c1f7439c57e46662319abaf14d2a4b0..8692bb3d93d124d1b61dc8c8aa1e45ef3c2077b0 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -35,7 +35,9 @@ #include #include "cnst.h" #include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "rom_com.h" #include "wmc_auto.h" @@ -46,6 +48,9 @@ #define BETA_BN1 2.0f #define BETA_BN2 2.25f +#define BETA_BN1_FX 2 // Q0 +#define BETA_BN2_FX 9 // Q2 + #define L_SUBFR_MAX 2 * L_SUBFR #define MAX_NUM_INTER 5 #define MAX_PULSES_STEREO 5 @@ -110,6 +115,40 @@ static int16_t find_best_pulse( return m; } +static Word16 find_best_pulse_fx( + const Word16 L_subfr, + const Word16 nb_tracks, + const Word16 track, + const Word16 dn[], + const Word16 sign[], + Word16 *s ) +{ + Word16 m, i; + Word16 temp, max_val; + + max_val = MIN_16; + move16(); + m = track; + move16(); + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + temp = i_mult( dn[i], sign[i] ); + + IF( GE_16( temp, max_val ) ) + { + max_val = temp; + move16(); + m = i; + move16(); + } + } + + *s = sign[m]; + move16(); + + return m; +} + /*-------------------------------------------------------------------* * Function acelp_fast() @@ -749,3 +788,824 @@ void acelp_fast( return; } + +/*-------------------------------------------------------------------* + * Function acelp_fast() + * + * Fast algebraic codebook search. + * Supports 10, 15, 17, 20, 24, and 26 bits codebooks. + *-------------------------------------------------------------------*/ + +void acelp_fast_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 cdk_index, /* i : codebook index */ + const Word16 dn_orig[L_SUBFR], + /* i : corr. between target and h[]. */ // Q_new + 1 + Word16 Q_dn, + const Word16 cn[L_SUBFR], + /* i : residual after long term prediction */ // Q_new + 1 + const Word16 H[L_SUBFR], + /* i : impulse response of weighted synthesis filter */ // e(norm_s(H[0])+1) + Word16 code[L_SUBFR], + /* o : algebraic (fixed) codebook excitation */ // Q0 + Word16 y[], + /* o : filtered fixed codebook excitation */ // e(norm_s(H[0])+1) + const Word16 L_subfr /* i : subframe length */ +) +{ + Word16 i, j, q, bits, bits_track, nb_pos, nb_pulse, track, nb_iter, nb_tracks; + Word16 skip_track[MAX_NUM_INTER], skip_track_max; + PulseConfig config; + enum TRACKPOS codetrackpos; + Word16 m[MAX_PULSES_STEREO], s[MAX_PULSES_STEREO], m_max[MAX_PULSES_STEREO], s_max[MAX_PULSES_STEREO]; + Word16 track_order[NB_TRACK_FCB_4T * MAX_NUM_INTER], m0_track[NB_TRACK_FCB_4T]; + Word16 ind_stream[NPMAXPT * NB_TRACK_FCB_4T], idx; + Word16 G, G1, G2, G3, Gn, Gd, dn[L_SUBFR_MAX]; + Word16 tmpF, y_tmp[L_SUBFR_MAX]; + Word32 crit_num, crit_den, crit_num_max, crit_den_max; + Word16 h_buf[4 * L_SUBFR_MAX], *h, *h_inv, *p_hn, alp_buf[2 * L_SUBFR_MAX], *alp, *alp_pos0, *alp_pos1, *alp_pos2, *alp_pos3; + Word32 dndn_fx, cncn_fx, cncn_track[NB_TRACK_FCB_4T]; + Word16 dndn_e, cncn_e, cncn_track_e[NB_TRACK_FCB_4T]; + Word16 s_coef_fx, bn_orig_fx[L_SUBFR_MAX]; + Word16 max_val_fx, temp_fx, sign_fx[L_SUBFR_MAX], max_track[MAX_NUM_INTER]; + Word16 beta1_fx, beta2_fx; + Word16 exp; + + /*-----------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + nb_iter = NB_TRACK_FCB_4T; + move16(); + nb_tracks = NB_TRACK_FCB_4T; + move16(); + nb_pulse = 0; /* to avoid compilation warnings */ + move16(); + + IF( EQ_16( L_subfr, L_SUBFR ) ) + { + config = PulseConfTable[cdk_index]; + bits = config.bits; + move16(); + nb_pulse = config.nb_pulse; + move16(); + codetrackpos = config.codetrackpos; + move16(); + + IF( EQ_16( cdk_index, 2 ) ) + { + /* 12 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ + nb_tracks = NB_TRACK_FCB_2T; + move16(); + nb_iter = NB_TRACK_FCB_2T; + move16(); + } + ELSE IF( EQ_16( nb_pulse, 2 ) ) + { + /* 10 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */ + nb_iter = NB_TRACK_FCB_4T - 2; + move16(); + } + ELSE IF( EQ_16( nb_pulse, 3 ) ) + { + IF( EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) ) + { + /* 15 bits, 3 pulses, 4 tracks: 1110 (fixed track to first) */ + nb_iter = NB_TRACK_FCB_4T - 1; + move16(); + } + ELSE IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) ) + { + /* 17 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */ + nb_iter = NB_TRACK_FCB_4T; + move16(); + } + } + } + ELSE /* L_subfr == 2*L_SUBFFR */ + { + bits = cdk_index; + move16(); + codetrackpos = -1; /* to avoid compilation warnings */ + move16(); + + + IF( EQ_16( cdk_index, 14 ) ) + { + /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ + nb_pulse = 2; + move16(); + nb_iter = NB_TRACK_FCB_2T; + move16(); + codetrackpos = TRACKPOS_FIXED_TWO; + move16(); + nb_tracks = NB_TRACK_FCB_2T; + move16(); + } + ELSE IF( EQ_16( cdk_index, 12 ) ) + { + /* 12 bits, 2 pulses, 4 tracks: 1010 (used only even tracks) */ + nb_pulse = 2; + move16(); + nb_iter = NB_TRACK_FCB_4T - 2; + move16(); + codetrackpos = TRACKPOS_FIXED_EVEN; + move16(); + } + ELSE IF( EQ_16( cdk_index, 18 ) ) + { + /* 18 bits, 3 pulses, 4 tracks: 1110 (used first three tracks) */ + nb_pulse = 3; + move16(); + nb_iter = NB_TRACK_FCB_4T - 1; + move16(); + codetrackpos = TRACKPOS_FIXED_FIRST; + move16(); + } + ELSE IF( EQ_16( cdk_index, 20 ) ) + { + /* 20 bits, 3 pulses, 4 tracks (used all tracks): 1110, 1101, 1011, 0111 */ + nb_pulse = 3; + move16(); + nb_iter = NB_TRACK_FCB_4T; + move16(); + codetrackpos = TRACKPOS_FREE_THREE; + move16(); + } + ELSE IF( EQ_16( cdk_index, 24 ) ) + { + /* 24 bits, 4 pulses, 4 tracks: 1111 */ + nb_pulse = 4; + move16(); + nb_iter = NB_TRACK_FCB_4T; + move16(); + codetrackpos = TRACKPOS_FIXED_FIRST; + move16(); + } + } + + beta1_fx = BETA_BN1_FX; // Q0 + move16(); + beta2_fx = BETA_BN2_FX; // Q2 + move16(); + + IF( LE_16( cdk_index, 2 ) ) + { + beta1_fx = BETA_BN1_FX * 2; // Q0 + move16(); + beta2_fx = BETA_BN2_FX * 2; // Q2 + move16(); + } + + /*-----------------------------------------------------------------* + * Find signal bn[] and sign pre-selection vector sign[]. + *-----------------------------------------------------------------*/ + + exp = sub( Q31, shl( Q_dn, 1 ) ); + + dndn_fx = 21474836 /*0.01f in Q31 */; + move32(); + dndn_e = 0; + move16(); + FOR( i = 0; i < L_subfr; i++ ) + { + dndn_fx = BASOP_Util_Add_Mant32Exp( dndn_fx, dndn_e, L_mult0( dn_orig[i], dn_orig[i] ), exp, &dndn_e ); // Q(dndn_e) + } + + cncn_fx = 214748365 /* 0.1f in Q31 */; + move32(); + cncn_e = 0; + move16(); + + FOR( q = 0; q < nb_tracks; q++ ) + { + cncn_track[q] = 214748365 /* 0.1f in Q31 */; + move32(); + cncn_track_e[q] = 0; + move16(); + + FOR( i = 0; i < L_subfr; i += nb_tracks ) + { + cncn_track[q] = BASOP_Util_Add_Mant32Exp( cncn_track[q], cncn_track_e[q], L_mult0( cn[i + q], cn[i + q] ), exp, &cncn_track_e[q] ); // Q(cncn_track_e[q]) + move16(); + } + cncn_fx = BASOP_Util_Add_Mant32Exp( cncn_fx, cncn_e, cncn_track[q], cncn_track_e[q], &cncn_e ); // Q(cncn_e) + } + + Word16 tmp; + s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_fx, &tmp ); + tmp = add( tmp, sub( dndn_e, cncn_e ) ); + s_coef_fx = Sqrt16( s_coef_fx, &tmp ); // Q(tmp) + + + FOR( i = 0; i < L_subfr; i++ ) + { + bn_orig_fx[i] = add( mult( s_coef_fx, cn[i] ), shr( i_mult( beta1_fx, dn_orig[i] ), tmp ) ); // Q_dn - tmp + + IF( bn_orig_fx[i] >= 0 ) + { + sign_fx[i] = 1; + } + ELSE + { + sign_fx[i] = -1; + } + move16(); + } + + /*-----------------------------------------------------------------* + * Compute buffer h_buf[]. + *-----------------------------------------------------------------*/ + + h = h_buf; + h_inv = h_buf + shl( L_subfr, 1 ); + + FOR( i = 0; i < L_subfr; i++ ) + { + *h++ = 0; + move16(); + *h_inv++ = 0; + move16(); + } + + FOR( i = 0; i < L_subfr; i++ ) + { + h[i] = H[i]; + move16(); + h_inv[i] = -H[i]; + move16(); + } + + /*-----------------------------------------------------------------* + * Approximate FI[i][j] by alp[abs(i-j)] and compute buffer alp_buf[]. + *-----------------------------------------------------------------*/ + Word16 shift = add( shl( add( norm_s( H[0] ), 1 ), 1 ), 1 ); + alp = alp_buf + L_subfr; + + FOR( i = 0; i < L_subfr; i++ ) + { + *alp = 0; + move16(); + + FOR( j = i; j < L_subfr; j++ ) + { + *alp = shr( add( *alp, mult( H[j], H[j - i] ) ), 1 ); + move16(); + } + alp_buf[L_subfr - i] = *alp++; + move16(); + } + + alp = alp_buf + L_subfr; + + FOR( q = 0; q < nb_tracks; q++ ) + { + max_track[q] = 0; + move16(); + + FOR( i = q; i < L_subfr; i += nb_tracks ) + { + temp_fx = i_mult( bn_orig_fx[i], sign_fx[i] ); // Q_dn - tmp + + IF( GE_16( temp_fx, shr( max_track[q], tmp ) ) ) + { + max_track[q] = temp_fx; // Q_dn + move16(); + m0_track[q] = i; + move16(); + } + } + } + + /*-----------------------------------------------------------------* + * Track re-order + *-----------------------------------------------------------------*/ + + IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) ) + { + track_order[0] = 0; + move16(); + track_order[1] = 1; + move16(); + track_order[2] = 1; + move16(); + track_order[3] = 0; + move16(); + } + ELSE + { + test(); + test(); + /* skip certain tracks if number of pulses is lower than number of tracks */ + IF( EQ_16( nb_pulse, 2 ) && EQ_16( nb_tracks, NB_TRACK_FCB_4T ) ) + { + max_track[NB_TRACK_FCB_4T - 3] = shl( -1, Q_dn ); // Q_dn + move16(); + max_track[NB_TRACK_FCB_4T - 1] = shl( -1, Q_dn ); // Q_dn + move16(); + } + ELSE IF( EQ_16( nb_pulse, 3 ) && EQ_16( codetrackpos, TRACKPOS_FIXED_FIRST ) ) + { + max_track[NB_TRACK_FCB_4T - 1] = shl( -1, Q_dn ); // Q_dn + move16(); + } + + FOR( q = 0; q < nb_tracks; q++ ) + { + i = maximum_fx( max_track, nb_tracks, &tmpF ); + move16(); + track_order[q] = i; + move16(); + max_track[i] = shl( -1, Q_dn ); // Q_dn + move16(); + } + + track_order[4] = track_order[1]; // Q0 + move16(); + track_order[5] = track_order[0]; // Q0 + move16(); + track_order[6] = track_order[2]; // Q0 + move16(); + track_order[7] = track_order[3]; // Q0 + move16(); + + track_order[8] = track_order[2]; // Q0 + move16(); + track_order[9] = track_order[0]; // Q0 + move16(); + track_order[10] = track_order[1]; // Q0 + move16(); + track_order[11] = track_order[3]; // Q0 + move16(); + + track_order[12] = track_order[3]; // Q0 + move16(); + track_order[13] = track_order[0]; // Q0 + move16(); + track_order[14] = track_order[1]; // Q0 + move16(); + track_order[15] = track_order[2]; // Q0 + move16(); + + IF( EQ_16( cdk_index, 3 ) ) + { + track_order[12] = track_order[2]; // Q0 + move16(); + track_order[13] = track_order[1]; // Q0 + move16(); + track_order[14] = track_order[0]; // Q0 + move16(); + + track_order[16] = track_order[1]; // Q0 + move16(); + track_order[17] = track_order[2]; // Q0 + move16(); + track_order[18] = track_order[0]; // Q0 + move16(); + nb_iter = 5; + move16(); + } + ELSE IF( EQ_16( cdk_index, 4 ) ) + { + track_order[16] = track_order[2]; // Q0 + move16(); + track_order[17] = track_order[3]; // Q0 + move16(); + track_order[18] = track_order[1]; // Q0 + move16(); + track_order[19] = track_order[0]; // Q0 + move16(); + nb_iter = 5; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Main searching loop + *-----------------------------------------------------------------*/ + + crit_num_max = -32768; + move16(); + crit_den_max = 32767; + move16(); + skip_track_max = -1; + move16(); + + FOR( q = 0; q < nb_iter; q++ ) + { + /*-----------------------------------------------------------------* + * First pulse search + *-----------------------------------------------------------------*/ + + track = track_order[q * nb_tracks]; // Q0 + move16(); + m[0] = m0_track[track]; // Q0 + move16(); + s[0] = sign_fx[m[0]]; // Q0 + move16(); + + /*-----------------------------------------------------------------* + * Second pulse search + *-----------------------------------------------------------------*/ + + IF( EQ_16( nb_tracks, NB_TRACK_FCB_2T ) ) + { + Gn = i_mult( s[0], dn_orig[m[0]] ); // Q_dn + move16(); + Gd = alp[0]; // exp(shift) + move16(); + G = div_s( Gn, Gd ); // Q_dn - shift + G = i_mult( G, s[0] ); + + track = track_order[q * nb_tracks + 1]; // Q0 + move16(); + alp_pos0 = alp - m[0] + track; + + FOR( i = track; i < L_subfr; i += NB_TRACK_FCB_2T ) + { + dn[i] = sub( dn_orig[i], shl( mult( G, *alp_pos0 ), shift ) ); // Q_dn + move16(); + alp_pos0 = alp_pos0 + NB_TRACK_FCB_2T; + } + + m[1] = find_best_pulse_fx( L_subfr, NB_TRACK_FCB_2T, track, dn, sign_fx, &s[1] ); // Q0 + move16(); + } + ELSE + { + Gn = i_mult( s[0], dn_orig[m[0]] ); // Q_dn + Gd = alp[0]; // exp(shift) + move16(); + G = Gn; // Q_dn + move16(); + G = i_mult( G, s[0] ); + + track = track_order[q * nb_tracks + 1]; // Q0 + move16(); + alp_pos0 = alp - m[0] + track; // exp(shift) + + dndn_fx = 214748365 /* 0.1f in Q31 */; + move32(); + dndn_e = 0; + move16(); + + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + dn[i] = sub( mult( Gd, dn_orig[i] ), mult( G, *alp_pos0 ) ); // Q_dn - shift + move16(); + alp_pos0 += nb_tracks; + dndn_fx = BASOP_Util_Add_Mant32Exp( dndn_fx, dndn_e, L_mult0( dn[i], dn[i] ), add( exp, shl( shift, 1 ) ), &dndn_e ); // exp(dndn_e) + } + + s_coef_fx = BASOP_Util_Divide3232_Scale( dndn_fx, cncn_track[track], &tmp ); // exp(tmp) + tmp = add( tmp, sub( dndn_e, cncn_track_e[track] ) ); + s_coef_fx = Sqrt16( s_coef_fx, &tmp ); // exp(tmp) + tmp = sub( tmp, shift ); + max_val_fx = MIN_16; + move16(); + m[1] = track; // Q0 + move16(); + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + dn[i] = add( shl( mult( s_coef_fx, cn[i] ), tmp ), i_mult( beta2_fx, shr( dn[i], 2 ) ) ); // Q_dn + move16(); + temp_fx = i_mult( dn[i], sign_fx[i] ); // Q_dn + + IF( GE_16( temp_fx, max_val_fx ) ) + { + max_val_fx = temp_fx; // Q_dn + move16(); + m[1] = i; + move16(); + } + } + + s[1] = sign_fx[m[1]]; + move16(); + } + + /*-----------------------------------------------------------------* + * Third pulse search + *-----------------------------------------------------------------*/ + + IF( GE_16( nb_pulse, 3 ) ) + { + Gn = add( Gn, i_mult( s[1], dn_orig[m[1]] ) ); // Q_dn + Gd = add( Gd, add( alp[0], i_mult( i_mult( i_mult( 2, s[0] ), s[1] ), alp[m[0] - m[1]] ) ) ); // exp(shift) + G = Gn; // Q_dn + move16(); + G1 = i_mult( G, s[1] ); // Q_dn + G = i_mult( G, s[0] ); // Q_dn + + track = track_order[q * nb_tracks + 2]; // Q0 + move16(); + alp_pos0 = alp - m[0] + track; + alp_pos1 = alp - m[1] + track; + + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + dn[i] = sub( sub( mult( Gd, dn_orig[i] ), mult( G, *alp_pos0 ) ), mult( G1, *alp_pos1 ) ); // Q_dn - shift + move16(); + alp_pos0 += nb_tracks; + alp_pos1 += nb_tracks; + } + + m[2] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[2] ); // Q0 + move16(); + } + + /*-----------------------------------------------------------------* + * Fourth pulse search + *-----------------------------------------------------------------*/ + + IF( GE_16( nb_pulse, 4 ) ) + { + Gn = add( Gn, i_mult( s[2], dn_orig[m[2]] ) ); // Q_dn + Gd = add( Gd, add( add( alp[0], i_mult( i_mult( i_mult( 2, s[0] ), s[2] ), alp[m[0] - m[2]] ) ), i_mult( i_mult( i_mult( 2, s[1] ), s[2] ), alp[m[1] - m[2]] ) ) ); // exp(shift) + G = Gn; + move16(); + G1 = i_mult( G, s[1] ); + G2 = i_mult( G, s[2] ); + G = i_mult( G, s[0] ); + + track = track_order[q * nb_tracks + 3]; + move16(); + alp_pos0 = alp - m[0] + track; + alp_pos1 = alp - m[1] + track; + alp_pos2 = alp - m[2] + track; + + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + dn[i] = sub( sub( sub( mult( Gd, dn_orig[i] ), mult( G, *alp_pos0 ) ), mult( G1, *alp_pos1 ) ), mult( G2, *alp_pos2 ) ); // Q_dn - shift + move16(); + alp_pos0 += nb_tracks; + alp_pos1 += nb_tracks; + alp_pos2 += nb_tracks; + } + + m[3] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[3] ); + move16(); + } + ELSE + { + skip_track[q] = track_order[q * nb_tracks + 3]; + move16(); + } + + /*-----------------------------------------------------------------* + * Fifth pulse search + *-----------------------------------------------------------------*/ + + IF( GE_16( nb_pulse, 5 ) ) + { + Gn = add( Gn, i_mult( s[3], dn_orig[m[3]] ) ); // Q_dn + Gd = add( Gd, add( add( add( alp[0], i_mult( i_mult( i_mult( 2, s[0] ), s[3] ), alp[m[0] - m[3]] ) ), i_mult( i_mult( i_mult( 2, s[1] ), s[3] ), alp[m[1] - m[3]] ) ), i_mult( i_mult( i_mult( 2, s[2] ), s[3] ), alp[m[2] - m[3]] ) ) ); // Q_dn - shift + G = Gn; + G1 = i_mult( G, s[1] ); // Q_dn + G2 = i_mult( G, s[2] ); // Q_dn + G3 = i_mult( G, s[3] ); // Q_dn + G = i_mult( G, s[0] ); // Q_dn + + IF( EQ_16( cdk_index, 6 ) ) + { + track = 0; /* always track 0 */ + move16(); + + alp_pos0 = alp - m[0]; + alp_pos1 = alp - m[1]; + alp_pos2 = alp - m[2]; + alp_pos3 = alp - m[3]; + + FOR( i = track; i < L_subfr; i += nb_tracks ) + { + dn[i] = sub( sub( sub( sub( mult( Gd, dn_orig[i] ), mult( G, *alp_pos0 ) ), mult( G1, *alp_pos1 ) ), mult( G2, *alp_pos2 ) ), mult( G3, *alp_pos3 ) ); // Q_dn - shift + move16(); + alp_pos0 += nb_tracks; + alp_pos1 += nb_tracks; + alp_pos2 += nb_tracks; + alp_pos3 += nb_tracks; + } + + m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] ); + move16(); + } + ELSE /* cdk_index == 7 (26 bits codebook) */ + { + alp_pos0 = alp - m[0]; + alp_pos1 = alp - m[1]; + alp_pos2 = alp - m[2]; + alp_pos3 = alp - m[3]; + + FOR( i = 0; i < L_subfr; i++ ) + { + dn[i] = sub( sub( sub( sub( mult( Gd, dn_orig[i] ), mult( G, *alp_pos0 ) ), mult( G1, *alp_pos1 ) ), mult( G2, *alp_pos2 ) ), mult( G3, *alp_pos3 ) ); + move16(); + alp_pos0++; + alp_pos1++; + alp_pos2++; + alp_pos3++; + } + + Word32 L_tmp; + i = emaximum_fx( 0, dn, L_subfr, &L_tmp ); + track = i % nb_tracks; + move16(); + + m[4] = find_best_pulse_fx( L_subfr, nb_tracks, track, dn, sign_fx, &s[4] ); + move16(); + } + skip_track[q] = track; + move16(); + } + + /*-----------------------------------------------------------------* + * - Build the filtered codeword and criterion computing. + * - Memorize the best code positions & signs, and the best filtered codevector. + *-----------------------------------------------------------------*/ + + crit_num = 0; + move32(); + set16_fx( y_tmp, 0, L_subfr ); + + FOR( j = 0; j < nb_pulse; j++ ) + { + IF( s[j] > 0 ) + { + p_hn = h - m[j]; + } + ELSE + { + p_hn = h_inv - m[j]; + } + + FOR( i = 0; i < L_subfr; i++ ) + { + y_tmp[i] = add( y_tmp[i], *p_hn++ ); // exp(shift) + move16(); + } + + crit_num = L_add( crit_num, L_mult0( s[j], dn_orig[m[j]] ) ); // Q_dn + } + + crit_num = W_extract_l( W_mult_32_32( crit_num, crit_num ) ); // 2*Q_dn+1 + crit_den = sum2_fx( y_tmp, L_subfr ); // 2*exp(shift) + + IF( GE_32( Mpy_32_32( crit_num, crit_den_max ), Mpy_32_32( crit_den, crit_num_max ) ) ) + { + crit_num_max = crit_num; + move32(); + crit_den_max = crit_den; + move32(); + + FOR( j = 0; j < nb_pulse; j++ ) + { + m_max[j] = m[j]; + move16(); + s_max[j] = s[j]; + move16(); + } + + Copy( y_tmp, y, L_subfr ); // exp(shift) + skip_track_max = skip_track[q]; + move16(); + } + } + + /*-----------------------------------------------------------------* + * Reconstruct the best codevector, + * compute index of codevector and write it into the bitstream. + *-----------------------------------------------------------------*/ + + set16_fx( code, 0, L_subfr ); + FOR( q = 0; q < nb_pulse; q++ ) + { + code[m_max[q]] = add( code[m_max[q]], s_max[q] ); // Q0 + move16(); + } + + IF( EQ_16( bits, 12 ) || EQ_16( bits, 14 ) ) + { + /* 12 bits, 2 pulses, 2 tracks 11 used all tracks */ + i = 6; + move16(); + j = 0x800; + move16(); + q = 0x20; + move16(); + + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + /* 14 bits, 2 pulses, 2 tracks: 11 (used all tracks) */ + i = 7; + move16(); + j = 0x2000; + move16(); + q = 0x40; + move16(); + } + + IF( EQ_16( m_max[0] % NB_TRACK_FCB_2T, 1 ) ) + { + idx = add( shl( shr( m_max[1], 1 ), i ), shr( m_max[0], 1 ) ); + + if ( s_max[1] < 0 ) + { + idx = add( idx, j ); + } + + if ( s_max[0] < 0 ) + { + idx = add( idx, q ); + } + } + ELSE + { + idx = add( shl( shr( m_max[0], 1 ), i ), shr( m_max[1], 1 ) ); + + if ( s_max[0] < 0 ) + { + idx = add( idx, j ); + } + + if ( s_max[1] < 0 ) + { + idx = add( idx, q ); + } + } + + push_indice( hBstr, IND_ALG_CDBK_2T32, idx, bits ); + } + ELSE + { + /* compute index of codevector */ + set16_fx( ind_stream, -1, i_mult( NPMAXPT, nb_tracks ) ); + + bits_track = 4; + move16(); + nb_pos = NB_POS_FCB_4T; + move16(); + + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + bits_track = 5; + move16(); + nb_pos = NB_POS_FCB_4T_128; + move16(); + } + + FOR( q = 0; q < nb_pulse; q++ ) + { + i = i_mult( m_max[q] % NB_TRACK_FCB_4T, NPMAXPT ); /* track number */ + if ( ind_stream[i] >= 0 ) + { + i = add( i, 1 ); + } + ind_stream[i] = shr( m_max[q], 2 ); // / NB_TRACK_FCB_4T; /* pos of pulse */ + move16(); + + IF( s_max[q] < 0 ) + { + ind_stream[i] = add( ind_stream[i], nb_pos ); + move16(); + } + } + + test(); + IF( EQ_16( codetrackpos, TRACKPOS_FREE_THREE ) || EQ_16( codetrackpos, TRACKPOS_FREE_ONE ) ) + { + push_indice( hBstr, IND_ALG_CDBK_4T64, skip_track_max, 2 ); + } + + IF( LT_16( nb_pulse, 5 ) ) + { + FOR( q = 0; q < NB_TRACK_FCB_4T; q++ ) + { + j = i_mult( q, NPMAXPT ); + IF( NE_16( ind_stream[j], -1 ) ) + { + idx = quant_1p_N1_L_subfr( nb_pos, ind_stream[j], bits_track ); + push_indice( hBstr, IND_ALG_CDBK_4T64, idx, bits_track + 1 ); + } + } + } + ELSE + { + FOR( q = 0; q < NB_TRACK_FCB_4T; q++ ) + { + j = i_mult( q, NPMAXPT ); + IF( EQ_16( q, skip_track_max ) ) + { + idx = quant_2p_2N1( ind_stream[j], ind_stream[j + 1], bits_track ); + push_indice( hBstr, IND_ALG_CDBK_4T64, idx, ( 2 * bits_track ) + 1 ); + } + ELSE + { + idx = quant_1p_N1_L_subfr( nb_pos, ind_stream[j], bits_track ); + push_indice( hBstr, IND_ALG_CDBK_4T64, idx, bits_track + 1 ); + } + } + } + } + + return; +} diff --git a/lib_enc/cod_tcx_fx.c b/lib_enc/cod_tcx_fx.c index a364eea68cea150fcf254164475d6692a62bb1c3..0157c69714bb40fa365878893294baded3254f5c 100644 --- a/lib_enc/cod_tcx_fx.c +++ b/lib_enc/cod_tcx_fx.c @@ -15,6 +15,8 @@ //#include "basop_mpy.h" #include "prot_fx_enc.h" #ifdef IVAS_FLOAT_FIXED_CONVERSIONS +#include +#include "prot.h" #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "ivas_rom_com_fx.h" @@ -1601,118 +1603,81 @@ static void EstimateTCXNoiseLevel_ivas_fx( *-------------------------------------------------------------------*/ void QuantizeSpectrum_ivas_fx( - Encoder_State *st, /* i/o: encoder state structure */ - const float A[], /* i : quantized coefficients NxAz_q[M+1] */ - const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ - float gainlpc[], /* i : MDCT gains of the previous frame */ - float synth[], /* o : synthesis buffer */ - const int16_t nb_bits, /* i : bit budget */ - const int16_t tnsSize, /* i : number of tns parameters put into prm */ - int16_t prm[], /* o : tcx parameters */ - const int16_t frame_cnt, /* i : frame counter in the super_frame */ - CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ - const int16_t vad_hover_flag /* i : VAD hangover flag */ + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 A_fx[], /* i : quantized coefficients NxAz_q[M+1], Q = 14 - norm_s(A_fx[0]) */ + const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */ + Word16 gainlpc_fx[], /* i : MDCT gains of the previous frame */ + Word16 gainlpc_e[], /* i : exponents of MDCT gains of the previous frame */ + Word16 synth[], /* o : synthesis buffer, Q0 */ + const Word16 nb_bits, /* i : bit budget */ + const Word16 tnsSize, /* i : number of tns parameters put into prm */ + Word16 prm[], /* o : tcx parameters */ + const Word16 frame_cnt, /* i : frame counter in the super_frame */ + CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */ + const Word16 vad_hover_flag /* i : VAD hangover flag */ ) { - int16_t L_frameTCX; /* full frame length */ - int16_t L_frame; /* frame length */ - int16_t L_spec; /* length of the coded spectrum */ - int16_t tcx_offset; /* folding point offset relative to the end of the previous frame */ - int16_t noiseFillingBorder; /* noise filling border */ - float quantized_spectrum[N_MAX]; /* quantized MDCT spectrum */ + Word16 L_frameTCX; /* full frame length */ + Word16 L_frame; /* frame length */ + Word16 L_spec; /* length of the coded spectrum */ + Word16 tcx_offset; /* folding point offset relative to the end of the previous frame */ + Word16 noiseFillingBorder; /* noise filling border */ Word32 quantized_spectrum_fx[N_MAX]; /* quantized MDCT spectrum */ Word16 quantized_spectrum_e; /* quantized MDCT spectrum */ - float lf_deemph_fact[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */ Word16 lf_deemph_fact_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */ - int16_t hm_active; /* flag indicating if the harmonic model is active */ - float fac_ns; /* noise filling level */ + Word16 hm_active; /* flag indicating if the harmonic model is active */ Word16 fac_ns_fx; /* noise filling level, Q15 */ - int16_t nf_seed; /* noise filling random seed */ - float ener; /* energy of the quantized spectrum */ + Word16 nf_seed; /* noise filling random seed */ Word32 ener_fx; /* energy of the quantized spectrum */ Word16 ener_e; /* energy of the quantized spectrum */ - float gain_tcx; /* global gain */ Word16 gain_tcx_fx; /* global gain */ Word16 gain_tcx_e; /* global gain */ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + set32_fx( quantized_spectrum_fx, 0, N_MAX ); + /*-----------------------------------------------------------* * Quantize the MDCT spectrum * *-----------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 gainlpc_fx[FDNS_NPTS]; - Word16 gainlpc_e[FDNS_NPTS]; - st->hTcxEnc->spectrum_e[0] = 31 - ( Q_factor_arrL( st->hTcxEnc->spectrum[0], N_MAX ) - 4 ); - floatToFixed_arrL( st->hTcxEnc->spectrum[0], st->hTcxEnc->spectrum_fx[0], 31 - st->hTcxEnc->spectrum_e[0], N_MAX ); - st->hTcxEnc->spectrum_e[1] = st->hTcxEnc->spectrum_e[0]; - hTcxEnc->tcxltp_gain = float_to_fix16( hTcxEnc->tcxltp_gain_flt, Q15 ); - st->hTcxCfg->preemph_fac = float_to_fix16( st->hTcxCfg->preemph_fac_flt, Q15 ); - hTcxEnc->tcx_target_bits_fac = float_to_fix16( hTcxEnc->tcx_target_bits_fac_flt, Q14 ); - st->hTcxCfg->sq_rounding = float_to_fix16( st->hTcxCfg->sq_rounding_flt, Q15 ); - if ( gainlpc ) - { - Word16 x, y; - for ( int ii = 0; ii < FDNS_NPTS; ii++ ) - { - f2me_16( gainlpc[ii], &x, &y ); - gainlpc_fx[ii] = x; - gainlpc_e[ii] = y; - } - } - if ( st->hTdCngEnc != NULL ) - { - st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q12 ); - } -#endif -#ifdef IVAS_FLOAT_FIXED QuantizeTCXSpectrum_fx( st, frame_cnt, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], gainlpc_fx, gainlpc_e, Aqind, tnsSize, nb_bits, vad_hover_flag, &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum_fx, &quantized_spectrum_e, hm_cfg, &hm_active, lf_deemph_fact_fx, &nf_seed, &ener_fx, &ener_e, &gain_tcx_fx, &gain_tcx_e, prm ); -#else - QuantizeTCXSpectrum( st, frame_cnt, hTcxEnc->spectrum[frame_cnt], gainlpc, Aqind, tnsSize, nb_bits, vad_hover_flag, - &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum, hm_cfg, &hm_active, lf_deemph_fact, &nf_seed, &ener, &gain_tcx, prm ); -#endif -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - gain_tcx = me2f_16( gain_tcx_fx, gain_tcx_e ); - ener = me2f( ener_fx, ener_e ); - hTcxEnc->tcx_target_bits_fac_flt = me2f_16( hTcxEnc->tcx_target_bits_fac, Q15 - Q14 ); - fixedToFloat_arrL( quantized_spectrum_fx, quantized_spectrum, 31 - quantized_spectrum_e, L_spec ); - if ( lf_deemph_fact != NULL ) + + Word16 s = sub( getScaleFactor32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame ), 6 ); + scale_sig32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame, s ); + st->hTcxEnc->spectrum_e[frame_cnt] = sub( st->hTcxEnc->spectrum_e[frame_cnt], s ); + move16(); + + IF( NE_16( quantized_spectrum_e, hTcxEnc->spectrum_e[frame_cnt] ) ) { - fixedToFloat_arr( lf_deemph_fact_fx, lf_deemph_fact, Q14, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); + scale_sig32( quantized_spectrum_fx, s_max( L_frame, L_spec ), sub( quantized_spectrum_e, hTcxEnc->spectrum_e[frame_cnt] ) ); } -#endif + /*-----------------------------------------------------------* * Estimate and quantize noise factor * *-----------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st->hTcxEnc->measuredBwRatio = float_to_fix16( st->hTcxEnc->measuredBwRatio_flt, Q14 ); - st->hTcxEnc->tcxltp_gain = float_to_fix16( st->hTcxEnc->tcxltp_gain_flt, Q15 ); - st->hTcxEnc->noiseTiltFactor = float_to_fix16( st->hTcxEnc->noiseTiltFactor_flt, Q15 ); - st->hTcxEnc->spectrum_e[0] = 31 - ( Q_factor_arrL( st->hTcxEnc->spectrum[0], N_MAX ) - 4 ); - floatToFixed_arrL( st->hTcxEnc->spectrum[0], st->hTcxEnc->spectrum_fx[0], 31 - st->hTcxEnc->spectrum_e[0], N_MAX ); - floatToFixed_arrL( quantized_spectrum, quantized_spectrum_fx, 31 - st->hTcxEnc->spectrum_e[0], L_frame ); - f2me_16( gain_tcx, &gain_tcx_fx, &gain_tcx_e ); -#endif EstimateTCXNoiseLevel_ivas_fx( st, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], quantized_spectrum_fx, gain_tcx_fx, gain_tcx_e, L_frame, noiseFillingBorder, hm_active, &fac_ns_fx, &prm[1] ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fac_ns = fix16_to_float( fac_ns_fx, Q15 ); -#endif /*-----------------------------------------------------------* * Internal decoder * *-----------------------------------------------------------*/ - InternalTCXDecoder( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum, ener, lf_deemph_fact, fac_ns, nf_seed, A, gainlpc, hm_active, gain_tcx, hTcxEnc->spectrum[frame_cnt], synth, &prm[0] ); + InternalTCXDecoder_fx( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum_fx, ener_fx, ener_e, lf_deemph_fact_fx, fac_ns_fx, nf_seed, A_fx, gainlpc_fx, gainlpc_e, hm_active, gain_tcx_fx, &gain_tcx_e, hTcxEnc->spectrum_fx[frame_cnt], &hTcxEnc->spectrum_e[frame_cnt], synth, &prm[0] ); /* Update L_frame_past */ st->L_frame_past = L_frame; + move16(); /* Update overlap */ - if ( ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && frame_cnt > 0 ) || ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) + test(); + test(); + test(); + if ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) || EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) { st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); } @@ -4643,4 +4608,811 @@ void coder_tcx_post_ivas_fx( return; } + + +/*-------------------------------------------------------------------* + * InternalTCXDecoder_fx() + * + * + *-------------------------------------------------------------------*/ + +void InternalTCXDecoder_fx( + Encoder_State *st, /* i/o: state handle */ + const Word16 frame_cnt, /* i : frame counter in the super_frame */ + const Word16 L_frameTCX, /* i : full frame length */ + const Word16 L_frame, /* i : frame length */ + const Word16 L_spec, /* i : length of the coded spectrum */ + const Word16 tcx_offset, /* i : folding point offset relative to the end of the previous frame */ + const Word16 noiseFillingBorder, /* i : noise filling border */ + const Word32 *x_quant_fx, /* i : quantized spectrum, exponent same as spectrum_e */ + const Word32 ener_fx, /* i : energy of the quantized spectrum */ + const Word16 ener_e, /* i : exponent of energy of the quantized spectrum */ + Word16 lf_deemph_fact_fx[], /* i/o: low frequency deemphasis factors */ + const Word16 fac_ns_fx, /* i : noise filling level, Q15 */ + const Word16 nf_seed, /* i : noise filling random seed, Q0 */ + const Word16 *A_fx, /* i : LPC representation of the FDNS gains, Q = 14 - norm_s(A_fx[0]) */ + Word16 gainlpc_fx[], /* i/o: FDNS gains */ + Word16 gainlpc_e[], /* i/o: FDNS gains exponents */ + const Word16 hm_active, /* i : flag indicating if the harmonic model is active */ + Word16 gain_tcx_fx, /* i/o: global gain / quantized global gain */ + Word16 *gain_tcx_e, /* i/o: global gain / quantized global gain exponent */ + Word32 spectrum_fx[], /* o : dequantized spectrum */ + Word16 *spectrum_e, /* o : exponent of dequantized spectrum */ + Word16 synth[], /* o : time domain signal */ + Word16 *gain_tcx_q /* o : quantized global gain (at low bitrates), Q0 */ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 i, iStart, noiseTransWidth; + Word16 tcx_last_overlap_mode, overlap; + Word16 nz; /* non-zero length in ALDO window*/ + Word16 aldo; /* ALDO flag in current frame*/ + Word16 tmp1, tmp2, tmp3, tmp4, s; + Word16 *tmpP16; + Word16 q_spec, len; + Word32 tmp32; + Word32 xn_buf32[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 Aq_old_fx[M + 1]; + Word32 sns_interpolated_scalefactors_fx[FDNS_NPTS], A_fx32[M + 1]; + Word16 *xn_buf16 = (Word16 *) xn_buf32; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + Copy32( x_quant_fx, spectrum_fx, s_max( L_frame, L_spec ) ); + + /* Replication of ACELP formant enhancement for low rates */ + test(); + IF( st->total_brate < ACELP_13k20 || st->rf_mode ) + { + tcxFormantEnhancement( lf_deemph_fact_fx, gainlpc_fx, gainlpc_e, spectrum_fx, spectrum_e, L_frame, L_spec ); + } + + /*-----------------------------------------------------------* + * Noise Filling. * + *-----------------------------------------------------------*/ + + IF( fac_ns_fx > 0 ) + { + tmp1 = 0; + move16(); + test(); + if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ) + { + tmp1 = 1; + move16(); + } + iStart = tcxGetNoiseFillingTilt( A_fx, M, L_frame, tmp1, &hTcxEnc->noiseTiltFactor ); + + tmp1 = 0; + move16(); + test(); + test(); + if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) + { + tmp1 = 1; + move16(); + } + noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), hTcxEnc->tcxltp_gain, tmp1 ); + assert( st->element_mode != IVAS_CPE_MDCT ); + tcx_noise_filling( spectrum_fx, *spectrum_e, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns_fx, NULL, st->element_mode ); + } + + test(); + IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 ) + { + /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */ + s = sub( getScaleFactor32( spectrum_fx, L_spec ), 4 ); + tmp32 = L_deposit_l( 1 ); + + FOR( i = 0; i < L_spec; i++ ) + { + tmp1 = round_fx( L_shl( spectrum_fx[i], s ) ); + tmp32 = L_mac0( tmp32, tmp1, tmp1 ); + } + + tmp1 = BASOP_Util_Divide3232_Scale( ener_fx, tmp32, &tmp2 ); + tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) ); + tmp1 = Sqrt16( tmp1, &tmp2 ); + + gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); + *gain_tcx_e = add( *gain_tcx_e, tmp2 ); + move16(); + + QuantizeGain( L_spec, &gain_tcx_fx, gain_tcx_e, gain_tcx_q ); + } + + /*end of noise filling*/ + + /*-----------------------------------------------------------* + * Noise shaping in frequency domain (1/Wz) * + *-----------------------------------------------------------*/ + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + Copy_Scale_sig_16_32( A_fx, A_fx32, M + 1, add( norm_s( A_fx[0] ), 2 ) ); // Copying the Word16 A_fx buffer to a temporary Word32 buffer in Q16 + + q_spec = sub( 31, *spectrum_e ); + sns_interpolate_scalefactors_fx( sns_interpolated_scalefactors_fx, A_fx32, DEC ); + sns_shape_spectrum_fx( spectrum_fx, &q_spec, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors_fx, Q16, L_frame, &len ); + + test(); + test(); + IF( NE_16( len, L_frame ) && LT_16( q_spec, sub( 31, *spectrum_e ) ) ) + { + scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); + } + ELSE IF( NE_16( len, L_frame ) && GT_16( q_spec, sub( 31, *spectrum_e ) ) ) + { + scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); + q_spec = sub( 31, *spectrum_e ); + } + *spectrum_e = sub( 31, q_spec ); + move16(); + } + ELSE + { + mdct_shaping( spectrum_fx, L_frame, gainlpc_fx, gainlpc_e ); + } + /*-----------------------------------------------------------* + * Apply gain * + *-----------------------------------------------------------*/ + + IF( EQ_16( st->hTcxCfg->coder_type, INACTIVE ) ) + { + gain_tcx_fx = mult_r( gain_tcx_fx, st->hTcxCfg->na_scale ); + } + + FOR( i = 0; i < L_spec; i++ ) + { + spectrum_fx[i] = Mpy_32_16_1( spectrum_fx[i], gain_tcx_fx ); + move32(); + } + *spectrum_e = add( *spectrum_e, *gain_tcx_e ); + move16(); + + tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + + test(); + IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) ) + { + Word16 L = L_frame; + move16(); + + test(); + test(); + if ( ( ( st->hTcxCfg->fIsTNSAllowed != 0 ) && ( hTcxEnc->fUseTns[frame_cnt] != 0 ) ) || ( GT_16( L_spec, L_frame ) ) ) + { + L = L_spec; + move16(); + } + + tcxInvertWindowGrouping( st->hTcxCfg, + xn_buf32, + spectrum_fx, + L, + hTcxEnc->fUseTns[frame_cnt], + st->last_core, + tcx_last_overlap_mode, + frame_cnt, + 0 ); + } + + /*-----------------------------------------------------------* + * Temporal Noise Shaping Synthesis * + *-----------------------------------------------------------*/ + + IF( st->hTcxCfg->fIsTNSAllowed ) + { + test(); + SetTnsConfig( st->hTcxCfg, (Word16) EQ_16( st->core, TCX_20_CORE ), ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + + /* Apply TNS to get the reconstructed signal */ + IF( hTcxEnc->fUseTns[frame_cnt] != 0 ) + { + ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum_fx, 0 ); + + test(); + IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) ) + { + test(); + test(); + test(); + IF( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || + ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) ) + { + const Word16 L_win = shr( L_spec, 1 ); + /* undo rearrangement of LF sub-window lines for TNS synthesis filter */ + IF( GT_16( L_frame, L_spec ) ) + { + assert( 0 ); + } + ELSE + { + Copy32( spectrum_fx + 8, xn_buf32, L_win ); + Copy32( xn_buf32, spectrum_fx + L_win, 8 ); + Copy32( xn_buf32 + 8, spectrum_fx + 8, L_win - 8 ); + } + } + } + } + } + + + /*-----------------------------------------------------------* + * Compute inverse MDCT of spectrum[]. * + *-----------------------------------------------------------*/ + + E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old_fx, M ); + overlap = st->hTcxCfg->tcx_mdct_window_length; + nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS ); + aldo = 0; + move16(); + move16(); + + /* normalize spectrum to minimize IMDCT noise */ + s = getScaleFactor32( spectrum_fx, L_frame ); + FOR( i = 0; i < L_frame; i++ ) + { + spectrum_fx[i] = L_shl( spectrum_fx[i], s ); + move32(); + } + *spectrum_e = sub( *spectrum_e, s ); + move16(); + + test(); + IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) ) + { + IF( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) + { + Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2]; + Word16 L_win, L_spec_TCX5, L_ola, w; + + /* minimum or half overlap, two transforms, grouping into one window */ + L_win = shr( L_frame, 1 ); + L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 ); + L_ola = st->hTcxCfg->tcx_mdct_window_half_length; + move16(); + if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) + { + L_ola = st->hTcxCfg->tcx_mdct_window_min_length; + move16(); + } + + set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 ); + set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */ + + FOR( w = 0; w < 2; w++ ) + { + + IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) + { + TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), + win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode ); + } + ELSE + { + TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win, + L_ola, sub( L_win, L_ola ), L_ola, st->element_mode ); + } + + tmp1 = st->hTcxCfg->tcx_last_overlap_mode; + move16(); + test(); + test(); + if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( tcx_last_overlap_mode, 2 ) ) ) ) + { + tmp1 = MIN_OVERLAP; + move16(); + } + + tmp2 = 0; + move16(); + test(); + if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) ) + { + tmp2 = 1; + move16(); + } + + tmp3 = st->last_core; + move16(); + if ( w > 0 ) + { + tmp3 = 1; + move16(); + } + + tmp4 = 0; + move16(); + if ( tcx_offset < 0 ) + { + tmp4 = negate( tcx_offset ); + } + + tcx_windowing_synthesis_current_frame( win, + st->hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + L_ola, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + tmp2, + tmp1, + hTcxEnc->acelp_zir, + hTcxEnc->Txnq, + NULL, + Aq_old_fx, + st->hTcxCfg->tcx_mdct_window_trans, + L_win, + tmp4, + tmp3, + 0, + 0 ); + + tmp1 = add( tcx_offset, imult1616( w, L_win ) ); + move16(); + tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) ); + + IF( w > 0 ) + { + tcx_windowing_synthesis_past_frame( tmpP16, + st->hTcxCfg->tcx_aldo_window_1_trunc, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + L_ola, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + 2 ); + } + /* add part of current sub-window overlapping with previous window */ + FOR( i = 0; i < L_ola; i++ ) + { +#ifdef BASOP_NOGLOB + tmpP16[i] = add_sat( tmpP16[i], win[i] ); +#else + tmpP16[i] = add( tmpP16[i], win[i] ); +#endif + move16(); + } + /* copy new sub-window region not overlapping with previous window */ + Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win ); + } + /* To assure that no garbage values are copied to hLPDmem->Txnq */ + set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ), + 0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) ); + } + ELSE IF( s_and( frame_cnt == 0, ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) ) + { + /* special overlap attempt, two transforms, grouping into one window */ + Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2]; + Word16 L_win, L_spec_TCX5, L_ola, w; + + L_win = shr( L_frame, 1 ); + L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 ); + L_ola = st->hTcxCfg->tcx_mdct_window_min_length; + move16(); + + set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 ); + + /* Resize overlap (affect only asymmetric window)*/ + overlap = st->hTcxCfg->tcx_mdct_window_delay; + /* 1st TCX-5 window, special MDCT with minimum overlap on right side */ + TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), + win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode ); + + /* copy new sub-window region not overlapping with previous window */ + Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) ); + + /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */ + + TCX_MDCT_Inverse( spectrum_fx + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), + win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode ); + + tmp4 = 0; + move16(); + if ( tcx_offset < 0 ) + { + tmp4 = negate( tcx_offset ); + } + tcx_windowing_synthesis_current_frame( win, + st->hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + L_ola, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + 0, /* left_rect */ + 2, /* left_mode */ + hTcxEnc->acelp_zir, + hTcxEnc->Txnq, + NULL, + Aq_old_fx, + st->hTcxCfg->tcx_mdct_window_trans, + L_win, + tmp4, + 1, /* not LPDmem->mode */ + 0, + 0 ); + + + move16(); + tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) ); + + tcx_windowing_synthesis_past_frame( tmpP16, + st->hTcxCfg->tcx_aldo_window_1_trunc, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + L_ola, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + 2 ); + + /* add part of current sub-window overlapping with previous window */ + FOR( i = 0; i < L_ola; i++ ) + { +#ifdef BASOP_NOGLOB + tmpP16[i] = add_sat( tmpP16[i], win[i] ); +#else + tmpP16[i] = add( tmpP16[i], win[i] ); +#endif + move16(); + } + + /* copy new sub-window region not overlapping with previous window */ + Copy( win + L_ola, + xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ), + L_win ); + + /* extra folding-out on left side of win, for perfect reconstruction */ + FOR( w = shr( overlap, 1 ); w < overlap; w++ ) + { + xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] ); + move16(); + } + + tmp4 = 0; + move16(); + if ( tcx_offset < 0 ) + { + tmp4 = negate( tcx_offset ); + } + tcx_windowing_synthesis_current_frame( xn_buf16, + st->hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + overlap, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + st->last_core == ACELP_CORE, + 0, + hTcxEnc->acelp_zir, + hTcxEnc->Txnq, + NULL, + Aq_old_fx, + st->hTcxCfg->tcx_mdct_window_trans, + L_win, + tmp4, + st->last_core, + 0, + 0 ); + } + ELSE /* default, i.e. maximum overlap, single transform, no grouping */ + { + + TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), + xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); + + tmp1 = tcx_last_overlap_mode; + move16(); + test(); + test(); + if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) ) + { + tmp1 = 2; + move16(); + } + + tmp4 = 0; + move16(); + if ( tcx_offset < 0 ) + { + tmp4 = negate( tcx_offset ); + } + tcx_windowing_synthesis_current_frame( xn_buf16, + st->hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + overlap, /*hTcxCfg->tcx_mdct_window_length*/ + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + st->last_core == ACELP_CORE, + tmp1, + hTcxEnc->acelp_zir, + hTcxEnc->Txnq, + NULL, + Aq_old_fx, + st->hTcxCfg->tcx_mdct_window_trans, + shr( st->L_frame, 2 ), + tmp4, + st->last_core, + 0, + 0 ); + + } /* tcx_last_overlap_mode > 0 */ + } + ELSE /* frame is TCX-20 or not TCX-only */ + { + IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) + { + Word32 tmp_buf[L_FRAME_PLUS]; + Word16 Q; + + /* DCT */ + Q = sub( 31, *spectrum_e ); + edct_fx( spectrum_fx, tmp_buf, L_frame, &Q ); + + /* scale by sqrt(L / NORM_MDCT_FACTOR) */ + tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */ + tmp2 = 4; + move16(); + tmp1 = Sqrt16( tmp1, &tmp2 ); + + FOR( i = 0; i < L_frame; i++ ) + { + tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 ); + move32(); + } + Q = sub( Q, tmp2 ); + + + window_ola_fx( tmp_buf, + xn_buf16, + &Q, + hTcxEnc->old_out_fx, + &hTcxEnc->Q_old_out, + L_frame, + st->hTcxCfg->tcx_last_overlap_mode, + st->hTcxCfg->tcx_curr_overlap_mode, + 0, + 0, + NULL ); + + /* scale output */ + FOR( i = 0; i < L_frame; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shr_o( xn_buf16[i], Q, &Overflow ); +#else /* BASOP_NOGLOB */ + xn_buf16[i] = shr( xn_buf16[i], Q ); +#endif /* BASOP_NOGLOB */ + move16(); + } + + aldo = 1; + move16(); + } + ELSE + { + + TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), + xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode ); + + /*-----------------------------------------------------------* + * Windowing, overlap and add * + *-----------------------------------------------------------*/ + + /* Window current frame */ + tmp4 = 0; + move16(); + if ( tcx_offset < 0 ) + { + tmp4 = negate( tcx_offset ); + } + tcx_windowing_synthesis_current_frame( xn_buf16, + st->hTcxCfg->tcx_aldo_window_2, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + overlap, /*hTcxCfg->tcx_mdct_window_length*/ + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + st->last_core == ACELP_CORE, + st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ + hTcxEnc->acelp_zir, + hTcxEnc->Txnq, + NULL, + Aq_old_fx, + st->hTcxCfg->tcx_mdct_window_trans, + shr( st->L_frame, 1 ), + tmp4, + st->last_core, + 0, + 0 ); + } + } /* TCX-10 and TCX-only */ + + /* Window and overlap-add past frame if past frame is TCX */ + test(); + test(); + test(); + IF( ( st->last_core > ACELP_CORE ) && ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) ) + { + + IF( st->hTcxCfg->last_aldo != 0 ) + { + tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM ); + + tmp1 = sub( overlap, st->hTcxCfg->tcx_mdct_window_min_length ); + FOR( i = 0; i < tmp1; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( add( xn_buf16[i], shr( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + + /* fade truncated ALDO window */ + tmp1 = sub( overlap, shr( st->hTcxCfg->tcx_mdct_window_min_length, 1 ) ); + FOR( ; i < tmp1; i++ ) + { + tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[i - overlap + st->hTcxCfg->tcx_mdct_window_min_length].v.re ); +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + FOR( ; i < overlap; i++ ) + { + tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im ); +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( add( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + + FOR( ; i < L_frame; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + } + ELSE + { + test(); + test(); + test(); + if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( st->last_core != ACELP_CORE ) ) + { + tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */ + move16(); + } + + tmp1 = tcx_last_overlap_mode; + move16(); + test(); + if ( ( tcx_last_overlap_mode == 0 ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) ) + { + tmp1 = st->hTcxCfg->tcx_last_overlap_mode; + move16(); + } + + tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, tmp1 ); + + BASOP_SATURATE_WARNING_OFF_EVS; + FOR( i = 0; i < overlap; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + + IF( LT_16( i, L_frame ) ) + { + FOR( ; i < L_frame; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM ); +#else + xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + } + BASOP_SATURATE_WARNING_ON_EVS; + } + } + ELSE + { + IF( aldo == 0 ) + { + BASOP_SATURATE_WARNING_OFF_EVS; + FOR( i = 0; i < L_frame; i++ ) + { +#ifdef BASOP_NOGLOB + xn_buf16[i] = shl_o( xn_buf16[i], TCX_IMDCT_HEADROOM, &Overflow ); +#else /* BASOP_NOGLOB */ + xn_buf16[i] = shl( xn_buf16[i], TCX_IMDCT_HEADROOM ); +#endif + move16(); + } + BASOP_SATURATE_WARNING_ON_EVS; + } + } + + test(); + test(); + test(); + IF( ( aldo == 0 ) && + ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) || + NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) ) + { + /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/ + FOR( i = 0; i < nz; i++ ) + { + hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM ); + move16(); + } + Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap ); + set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz ); + + tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz, + st->hTcxCfg->tcx_aldo_window_1_trunc, + st->hTcxCfg->tcx_mdct_window_half, + st->hTcxCfg->tcx_mdct_window_minimum, + overlap, + st->hTcxCfg->tcx_mdct_window_half_length, + st->hTcxCfg->tcx_mdct_window_min_length, + st->hTcxCfg->tcx_curr_overlap_mode ); + + /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ + IF( EQ_16( st->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + { + FOR( i = 0; i < nz; i++ ) + { + hTcxEnc->old_out_fx[nz + overlap + i] = shr( mult_r( xn_buf16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM ); + move16(); + } + } + + hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM; + move16(); + } + st->hTcxCfg->last_aldo = aldo; + move16(); + + /* Update Txnq */ + IF( st->hTcxCfg->last_aldo == 0 ) + { + Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap ); + } + + tmp1 = L_frame; + move16(); + if ( EQ_16( st->core, TCX_20_CORE ) ) + { + tmp1 = st->L_frame; + move16(); + } + + /* Output */ + Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, tmp1 ); + + return; +} #endif diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c index 97ada614e79071ac7d96825d77f68570e6e8ead6..a00eb2551d4c0b000faa9f0bedbf91689690061f 100644 --- a/lib_enc/core_enc_ol.c +++ b/lib_enc/core_enc_ol.c @@ -263,9 +263,13 @@ void core_encode_openloop( /* reset TBE buffers previous frame frame wasn't ACELP*/ if ( st->last_core != ACELP_CORE ) { - TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #ifdef IVAS_FLOAT_FIXED TBEreset_enc_fx( st, st->bwidth ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); +#endif +#else + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #endif } diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index 6c0b66bb9123cc45acde7a1c3e55488e679bfa4c..72f9775f10cbf550ae94d4f77011756abccc6bc8 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -389,9 +389,13 @@ void core_coder_mode_switch( ( st->bwidth == SWB && st->last_extl != SWB_TBE ) || ( st->bwidth == FB && st->last_extl != FB_TBE ) ) { - TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #ifdef IVAS_FLOAT_FIXED TBEreset_enc_fx( st, st->bwidth ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); +#endif +#else + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #endif } else diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index 805f04b5e82a15793b9782bf3455499943944d13..b03654caa17552d0c3410abedc8b2c462da7e37d 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -790,8 +790,15 @@ void core_switching_post_enc( /* reset SWB TBE buffers */ if ( st->extl == WB_TBE && st->last_extl != WB_TBE ) { +#ifdef IVAS_FLOAT_FIXED + wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + set_f( st->hBWE_TD->mem_genSHBexc_filt_down_wb2, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( st->hBWE_TD->mem_genSHBexc_filt_down_wb3, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); +#endif +#else wb_tbe_extras_reset( st->hBWE_TD->mem_genSHBexc_filt_down_wb2, st->hBWE_TD->mem_genSHBexc_filt_down_wb3 ); - +#endif if ( st->last_extl != WB_BWE ) { set_f( st->hBWE_TD->decim_state1, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); @@ -807,8 +814,18 @@ void core_switching_post_enc( ( st->last_core == HQ_CORE || st->L_frame != st->last_L_frame || ( st->last_extl != SWB_TBE && st->last_extl != FB_TBE && st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) ) ) { set_f( st->hBWE_TD->state_ana_filt_shb, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); +#ifdef IVAS_FLOAT_FIXED + InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); + swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* To be removed later when the function is converted to fixed*/ InitSWBencBufferStates( st->hBWE_TD, NULL ); swb_tbe_reset( st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &( st->hBWE_TD->tbe_demph ), &( st->hBWE_TD->tbe_premph ), st->hBWE_TD->mem_stp_swb, &( st->hBWE_TD->gain_prec_swb ) ); +#endif +#else + InitSWBencBufferStates( st->hBWE_TD, NULL ); + swb_tbe_reset( st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &( st->hBWE_TD->tbe_demph ), &( st->hBWE_TD->tbe_premph ), st->hBWE_TD->mem_stp_swb, &( st->hBWE_TD->gain_prec_swb ) ); +#endif set_f( st->hBWE_TD->dec_2_over_3_mem, 0.0f, L_FILT_2OVER3 ); set_f( st->hBWE_TD->dec_2_over_3_mem_lp, 0.0f, L_FILT_2OVER3_LP ); } @@ -822,9 +839,13 @@ void core_switching_post_enc( } else if ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) { - TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #ifdef IVAS_FLOAT_FIXED TBEreset_enc_fx( st, st->bwidth ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); +#endif +#else + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); #endif } @@ -833,7 +854,14 @@ void core_switching_post_enc( { set_f( st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); st->hBWE_TD->fb_tbe_demph = 0; +#ifdef IVAS_FLOAT_FIXED + fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fb_tbe_reset_enc( st->hBWE_TD->elliptic_bpf_2_48k_mem, &st->hBWE_TD->prev_fb_energy ); +#endif +#else fb_tbe_reset_enc( st->hBWE_TD->elliptic_bpf_2_48k_mem, &st->hBWE_TD->prev_fb_energy ); +#endif } /* Fade towards init value for non HQ_CORE */ if ( st->hHQ_core != NULL ) diff --git a/lib_enc/corr_xh_fx.c b/lib_enc/corr_xh_fx.c index 86ba92c7a7c28d0cd2e92e551d1b6d195ab784c7..a999b893029c93c6cdfdb8018fa91c5a7ff9b5fa 100644 --- a/lib_enc/corr_xh_fx.c +++ b/lib_enc/corr_xh_fx.c @@ -80,3 +80,32 @@ void corr_xh_fx( } return; } + +void corr_xh_ivas_fx( + const Word16 *x, /* i : target signal Q_new - 1 */ + Word16 *y, /* o : correlation between x[] and h[] Q_new + 1 */ + const Word16 *h, /* i : impulse response (of weighted synthesis filter) e(norm_s(h1[0])+1) */ + const Word16 L_subfr /* i : length of the subframe */ +) +{ + Word16 i, j; + Word32 s; + Word32 y32[2 * L_SUBFR]; + + Word16 shift = add( norm_s( h[0] ), 1 ); + FOR( i = 0; i < L_subfr; i++ ) + { + s = 0; + move32(); + FOR( j = i; j < L_subfr; j++ ) + { + s = L_add( s, shl( mult( x[j], h[j - i] ), shift ) ); // Q_new - 1 + } + + y32[i] = s; // Q_new - 1 + move32(); + } + Copy_Scale_sig32_16( y32, y, L_subfr, 18 ); // Q_new + 1 + + return; +} diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c index 86dd4ad059e2731097f6c3d60e750311f0e3e070..f47d87bd15840a2cfcb256fd320495aa906c0a2b 100644 --- a/lib_enc/dtx.c +++ b/lib_enc/dtx.c @@ -753,7 +753,7 @@ void dtx_hangover_control( * * *-------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED void td_cng_enc_init( TD_CNG_ENC_HANDLE hTdCngEnc, /* i/o: DTX/TD CNG data handle */ const int16_t Opt_DTX_ON, /* i : flag indicating DTX operation */ @@ -806,6 +806,9 @@ void td_cng_enc_init( set_f( hTdCngEnc->exc_mem1, 0.0f, 30 ); set_f( hTdCngEnc->exc_mem2, 0.0f, 30 ); set_f( hTdCngEnc->old_env, 0.0f, NUM_ENV_CNG ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float fixed conversions + set_f( hTdCngEnc->cng_exc2_buf_flt, 0.0f, HO_HIST_SIZE * L_FFT ); +#endif /* SWB CNG/DTX */ hTdCngEnc->last_wb_cng_ener = -6.02f; @@ -820,7 +823,74 @@ void td_cng_enc_init( return; } +#else +void td_cng_enc_init( + TD_CNG_ENC_HANDLE hTdCngEnc, /* i/o: DTX/TD CNG data handle */ + const int16_t Opt_DTX_ON, /* i : flag indicating DTX operation */ + const int16_t max_bwidth /* i : maximum encoded bandwidth */ +) +{ + + hTdCngEnc->cng_seed = RANDOM_INITSEED; + hTdCngEnc->cng_ener_seed = RANDOM_INITSEED; + hTdCngEnc->cng_ener_seed1 = RANDOM_INITSEED; + hTdCngEnc->lp_ener = 0.0f; + hTdCngEnc->old_enr_index = -1; + hTdCngEnc->Enew = 0.0f; + + hTdCngEnc->lp_sp_enr = 0.0f; + hTdCngEnc->last_allow_cn_step = 0; + + hTdCngEnc->CNG_att = 0.0f; + + if ( Opt_DTX_ON ) + { + hTdCngEnc->cng_hist_ptr = -1; + set_f( hTdCngEnc->cng_lsp_hist, 0, DTX_HIST_SIZE * M ); + set_f( hTdCngEnc->cng_ener_hist, 0, DTX_HIST_SIZE ); + hTdCngEnc->ho_hist_ptr = -1; + hTdCngEnc->ho_sid_bw = 0; + set_f( hTdCngEnc->ho_lsp_hist, 0, HO_HIST_SIZE * M ); + set_f( hTdCngEnc->ho_ener_hist, 0, HO_HIST_SIZE ); + set_f( hTdCngEnc->ho_env_hist, 0, HO_HIST_SIZE * NUM_ENV_CNG ); + hTdCngEnc->ho_hist_size = 0; + hTdCngEnc->act_cnt = 0; + } + set_s( hTdCngEnc->ho_16k_lsp, 0, HO_HIST_SIZE ); + hTdCngEnc->act_cnt2 = 0; + hTdCngEnc->num_ho = 0; + + hTdCngEnc->ho_circ_ptr = -1; + set_f( hTdCngEnc->ho_lsp_circ, 0, HO_HIST_SIZE * M ); + set_f( hTdCngEnc->ho_ener_circ, 0, HO_HIST_SIZE ); + set_f( hTdCngEnc->ho_env_circ, 0, HO_HIST_SIZE * NUM_ENV_CNG ); + hTdCngEnc->ho_circ_size = 0; + hTdCngEnc->burst_ho_cnt = 0; + hTdCngEnc->cng_buf_cnt = 0; + + + set_f( hTdCngEnc->lp_env, 0.0f, 20 ); + set_f( hTdCngEnc->cng_res_env, 0.0f, 20 * 8 ); + set_f( hTdCngEnc->exc_mem, 0.0f, 24 ); + set_f( hTdCngEnc->exc_mem1, 0.0f, 30 ); + set_f( hTdCngEnc->exc_mem2, 0.0f, 30 ); + set_f( hTdCngEnc->old_env, 0.0f, NUM_ENV_CNG ); + + /* SWB CNG/DTX */ + hTdCngEnc->last_wb_cng_ener = -6.02f; + hTdCngEnc->last_shb_cng_ener = -6.02f; + hTdCngEnc->mov_wb_cng_ener = -6.02f; + hTdCngEnc->mov_shb_cng_ener = -6.02f; + hTdCngEnc->shb_cng_ini_cnt = 1; + hTdCngEnc->shb_NO_DATA_cnt = 0; + hTdCngEnc->last_SID_bwidth = min( max_bwidth, SWB ); + hTdCngEnc->last_vad = 0; + hTdCngEnc->last_idx_ener = 0; + + return; +} +#endif /*-------------------------------------------------------------------* * dtx_enc_init() diff --git a/lib_enc/fd_cng_enc_fx.c b/lib_enc/fd_cng_enc_fx.c index 33f693d4b0ea22a9d2ea1f7e1e3c71582d9a1afc..48df8f4e3f8cbef5283cb2052cdb1a4836147f6f 100644 --- a/lib_enc/fd_cng_enc_fx.c +++ b/lib_enc/fd_cng_enc_fx.c @@ -1644,3 +1644,99 @@ Word16 cng_energy_fx( } return enr; } + +/*-------------------------------------------------------------------* + * cng_energy_ivas_fx() + * + * + *-------------------------------------------------------------------*/ + +/*! r: CNG energy */ +Word16 cng_energy_ivas_fx( + const Word16 element_mode, /* i : element mode */ + const Word16 bwidth, /* i : audio bandwidh */ + const Word16 CNG_mode, /* i : mode for DTX configuration */ + const Word16 CNG_att, /* i : attenuation factor for CNG Q7 */ + const Word16 *exc, /* i : input signal */ + const Word16 len, /* i : vector length */ + const Word16 Q_new /* i : Input scaling */ +) +{ + Word16 i, maxv, scale; + Word16 hi, lo, enr, tmp16, att; + const Word16 *pt_res; + Word32 L_ener, L_tmp; + + maxv = 0; + move16(); + FOR( i = 0; i < len; i++ ) + { + maxv = s_max( maxv, abs_s( exc[i] ) ); + } + scale = norm_s( maxv ); + pt_res = exc; + L_ener = L_deposit_l( 1 ); + IF( EQ_16( len, L_FRAME ) ) + { + FOR( i = 0; i < 128; i++ ) + { + tmp16 = shl( *pt_res, scale ); + L_tmp = L_mult0( tmp16, tmp16 ); + pt_res++; + tmp16 = shl( *pt_res, scale ); + L_tmp = L_mac0( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */ + pt_res++; + L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */ + } + } + ELSE /* L_FRAME16k */ + { + FOR( i = 0; i < 160; i++ ) + { + tmp16 = shl( *pt_res, scale ); + L_tmp = L_mult0( tmp16, tmp16 ); + pt_res++; + tmp16 = shl( *pt_res, scale ); + L_tmp = L_mac0( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */ + pt_res++; + L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */ + } + } + + hi = norm_l( L_ener ); + lo = Log2_norm_lc( L_shl( L_ener, hi ) ); + hi = sub( 30, add( hi, shl( add( Q_new, scale ), 1 ) ) ); /* log2 exp in Q2*(Q_new+scale) */ + L_tmp = L_Comp( hi, lo ); /* Q16 */ + enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */ + + /* decrease the energy in case of WB input */ + test(); + IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) ) + { + // PMT(" IVAS CNG ener computing is missing") + enr = add( enr, mult( CNG_att, FAC_LOG2_BY10_Q16 ) ); /* Q8 (7+16-15) */ + } + ELSE IF( NE_16( bwidth, NB ) ) + { + IF( EQ_16( bwidth, WB ) ) + { + IF( CNG_mode >= 0 ) + { + /* Bitrate adapted attenuation */ + att = ENR_ATT_fx[CNG_mode]; + } + ELSE + { + /* Use least attenuation for higher bitrates */ + att = ENR_ATT_fx[4]; + } + } + ELSE + { + att = 384; + move16(); /*Q8*/ + } + enr = sub( enr, att ); + } + return enr; +} diff --git a/lib_enc/find_tar_fx.c b/lib_enc/find_tar_fx.c index 1fb28ca9752e1f632da001ddde6abae13863cd33..54cdec132b4e3d52c9aaa9ff629282b81945e37f 100644 --- a/lib_enc/find_tar_fx.c +++ b/lib_enc/find_tar_fx.c @@ -189,3 +189,182 @@ void find_targets_fx( return; } + +void find_targets_ivas_fx( + const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ + const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ + const Word16 i_subfr, /* i : subframe index */ + Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ + const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ + Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter */ +) +{ + Word16 i; + Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */ + Word16 scale, scaleq, j, d, s, s2, tmp; + Word16 Aqs[M + 1]; + Word32 Ltmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + /*------------------------------------------------------------------------* + * Find the target vector for excitation search: + * + * |------| res[n] + * speech[n]---| A(z) |-------- + * |------| | |--------| error[n] |------| + * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target + * exc |--------| |------| + * + * Instead of subtracting the zero-input response of filters from + * the weighted input speech, the above configuration is used to + * compute the target vector. + *-----------------------------------------------------------------------*/ + FOR( i = 0; i < M; i++ ) + { +#ifdef BASOP_NOGLOB + temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); +#else + temp[i] = sub( speech[i + i_subfr - M], mem_syn[i] ); +#endif + move16(); + } + Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); + + Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/ + + deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new -1 */ + + + /*-----------------------------------------------------------------* + * Find target in residual domain (cn[]) for innovation search + *--------------------------------------------------------------*/ + IF( cn != NULL ) + { + /* first half: xn[] --> cn[] */ + temp[0] = 0; + move16(); + preemph_copy_fx( xn, cn, tilt_fac, shr( L_subfr, 1 ), temp ); + syn_filt_s_lc_fx( 1, Ap, cn, temp, shr( L_subfr, 1 ) ); /* Q-1 -> Q-2 */ + Residu3_lc_fx( p_Aq, M, temp, cn, shr( L_subfr, 1 ), 1 ); /* Q-2 -> Q-1 */ + Scale_sig( cn, shr( L_subfr, 1 ), 1 ); + + /* second half: res[] --> cn[] (approximated and faster) */ + Copy( &res[i_subfr + shr( L_subfr, 1 )], cn + shr( L_subfr, 1 ), shr( L_subfr, 1 ) ); + } + + /*---------------------------------------------------------------* + * Compute impulse response, h1[], of weighted synthesis filter * + *---------------------------------------------------------------*/ + + scale = norm_s( Ap[0] ); + scaleq = norm_s( p_Aq[0] ); + d = sub( scaleq, scale ); + IF( d >= 0 ) + { + Copy( p_Aq, Aqs, M + 1 ); + s = add( scaleq, 1 ); + s2 = shr( 16384, d ); + } + ELSE + { + Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); + s = add( scale, 1 ); + s2 = 16384; + } + Overflow = 0; + move16(); + FOR( i = 0; i < M; i++ ) + { + Ltmp = L_mult( Ap[i], s2 ); + FOR( j = 1; j <= i; j++ ) + { +#ifdef BASOP_NOGLOB /* Critical Overflow , as well as those below*/ + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); +#else + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); +#endif + } +#ifdef BASOP_NOGLOB /* Critical Overflow */ + h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); +#else + h1[i] = round_fx( L_shl( Ltmp, s ) ); +#endif + } + Ltmp = L_mult( Ap[i], s2 ); + FOR( j = 1; j <= M; j++ ) + { +#ifdef BASOP_NOGLOB /* Critical Overflow */ + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); +#else + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); +#endif + } +#ifdef BASOP_NOGLOB /* Critical Overflow */ + h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); +#else + h1[M] = round_fx( L_shl( Ltmp, s ) ); +#endif + + // PMT("should we used extended basop here for when the L_subfr > L_SUBFR, to prevent saturation/overflow and the subsequent loop\n") + FOR( i = M + 1; i < L_subfr; i++ ) + { + Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); + FOR( j = 2; j <= M; j++ ) + { +#ifdef BASOP_NOGLOB /* Critical Overflow */ + Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); +#else + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); +#endif + } +#ifdef BASOP_NOGLOB /* Critical Overflow */ + h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); +#else + h1[i] = round_fx( L_shl( Ltmp, s ) ); +#endif + } + IF( Overflow ) + { + s2 = shr( s2, 1 ); + FOR( i = 0; i < M; i++ ) + { + Ltmp = L_mult( Ap[i], s2 ); + FOR( j = 1; j <= i; j++ ) + { + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + } +#ifdef BASOP_NOGLOB + h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) ); +#else + h1[i] = round_fx( L_shl( Ltmp, s ) ); +#endif + } + Ltmp = L_mult( Ap[i], s2 ); + FOR( j = 1; j <= M; j++ ) + { + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + } + h1[M] = round_fx( L_shl( Ltmp, s ) ); + FOR( i = M + 1; i < L_subfr; i++ ) + { + Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); + FOR( j = 2; j <= M; j++ ) + { + Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); + } + h1[i] = round_fx( L_shl( Ltmp, s ) ); + } + } + + tmp = 0; + Deemph2( h1, tilt_fac, L_subfr, &tmp ); + + return; +} diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index abb66a8b899578dc0ad57e6b4db41bedec9d0e72..a0398c50234d3bc3f2da578bda2199b8a4b9b764 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -7,6 +7,7 @@ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -1716,6 +1717,456 @@ void gain_enc_lbr_fx( return; } +void gain_enc_lbr_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 format */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ + const int16_t L_subfr /* i : subframe length */ +) +{ + + Word16 index = 0, size, nBits, n_pred, ctype; + const Word16 *b, *cdbk = 0; + Word16 gcode0, aux[10]; + Word16 coeff[5], exp_coeff[5]; + Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf; + Word32 L_tmp, L_tmp1, L_inov; + + L_subfr_sf = 6; + move16(); + if ( GT_16( L_subfr, L_SUBFR ) ) + { + L_subfr_sf = 7; + move16(); + } + /*-----------------------------------------------------------------* + * calculate the rest of the correlation coefficients + * c2 = , c3 = -2, c4 = 2, c5* = + * c5* - not necessary to calculate + *-----------------------------------------------------------------*/ + + coeff[0] = g_corr[0]; + move16(); + exp_coeff[0] = g_corr[1]; + move16(); + coeff[1] = negate( g_corr[2] ); + move16(); /* coeff[1] = -2 xn yy1 */ + exp_coeff[1] = add( g_corr[3], 1 ); + move16(); + + /* Compute scalar product */ +#ifdef DEBUG + if ( L_subfr != L_SUBFR ) + { + PMT( "Entire function needs review to accommode for L_subfr > L_SUBFR" ); + } +#endif + coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) ); + exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */ + move16(); + + /* Compute scalar product -2* */ + + coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) ); + exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */ + move16(); + + /* Compute scalar product 2* */ + + coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) ); + exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */ + move16(); + + /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/ + + /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt(Ecode);*/ + L_tmp = Dot_product12( code, code, L_subfr, &exp_code ); + L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */ + /* output gain_inov*/ + exp_inov = sub( exp_code, add( 18, L_subfr_sf ) ); + L_inov = Isqrt_lc( L_inov, &exp_inov ); + *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + + + /*-----------------------------------------------------------------* + * select the codebook, size and number of bits + * set the gains searching range + *-----------------------------------------------------------------*/ + + nBits = gains_mode[shr( i_subfr, L_subfr_sf )]; + move16(); + size = shl( 1, nBits ); + + ctype = shl( sub( coder_type, 1 ), 1 ); + + /*-----------------------------------------------------------------* + * calculate prediction of gcode + * search for the best codeword + *-----------------------------------------------------------------*/ + IF( i_subfr == 0 ) + { + b = b_1sfr_fx; + move16(); + n_pred = 2; + move16(); + + SWITCH( nBits ) + { + case 8: + { + cdbk = gp_gamma_1sfr_8b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 60 ); + } + move16(); + BREAK; + } + case 7: + { + cdbk = gp_gamma_1sfr_7b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 27 ); + } + move16(); + BREAK; + } + case 6: + { + cdbk = gp_gamma_1sfr_6b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 10 ); + } + move16(); + BREAK; + } + } + + /* calculate predicted gain */ + aux[0] = 4096; + move16(); + aux[1] = shl( ctype, 12 ); + + /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode)); + gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode)); + gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */ + + exp_code = sub( exp_code, 18 + 6 + 1 ); + exp = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, exp ) ); + exp = sub( exp_code, exp ); + L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/ + + L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 320 ); /*Q14, 20 in Q4*/ + L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q14*/ + + gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + + L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + + gc_mem[0] = *gain_code; + move16(); /*Q16*/ + gp_mem[0] = *gain_pit; + move16(); /*Q14*/ + } + ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + b = b_2sfr_fx; + move16(); + n_pred = 4; + move16(); + + switch ( nBits ) + { + case 7: + { + cdbk = gp_gamma_2sfr_7b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 30 ); + } + BREAK; + } + case 6: + { + cdbk = gp_gamma_2sfr_6b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 12 ); + } + BREAK; + } + } + + /* calculate predicted gain */ + aux[0] = 4096; + move16(); + aux[1] = shl( ctype, 12 ); + move16(); + + /*aux[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + exp = norm_l( gc_mem[0] ); + frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux[3] = shr( gp_mem[0], 2 ); + move16(); /*Q12*/ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + gc_mem[1] = *gain_code; + move32(); + gp_mem[1] = *gain_pit; + move16(); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + b = b_3sfr_fx; + move16(); + n_pred = 6; + move16(); + IF( EQ_16( nBits, 7 ) ) + { + cdbk = gp_gamma_3sfr_7b_fx; + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 28 ); + } + } + ELSE + { + cdbk = gp_gamma_3sfr_6b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 11 ); + } + } + /* calculate predicted gain */ + aux[0] = 4096; + move16(); + aux[1] = shl( ctype, 12 ); + move16(); + + /*aux[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + exp = norm_l( gc_mem[0] ); + frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + exp = norm_l( gc_mem[1] ); + frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux[4] = shr( gp_mem[0], 2 ); + move16(); /*Q12*/ + aux[5] = shr( gp_mem[1], 2 ); + move16(); /*Q12*/ + + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + /*----------------------------------------------------------------* + * Find the best quantizer + * ~~~~~~~~~~~~~~~~~~~~~~~ + * Before doing the computation we need to align exponents of coeff[] + * to be sure to have the maximum precision. + * + * In the table the pitch gains are in Q14, the code gains are in Q9 and + * are multiply by gcode0 which have been multiply by 2^exp_gcode0. + * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code + * we divide by 2^15. + * Considering all the scaling above we have: + * + * exp_code = exp_gcode0-9+15 = exp_gcode0+6 + * + * g_pitch*g_pitch = -14-14+15 + * g_pitch = -14 + * g_code*g_code = (2*exp_code)+15 + * g_code = exp_code + * g_pitch*g_code = -14 + exp_code +15 + * + * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13 + * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14 + * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code) + * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code + * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code + *----------------------------------------------------------------*/ + + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + + gc_mem[2] = *gain_code; + move32(); + gp_mem[2] = *gain_pit; + move16(); + } + ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) ) + { + b = b_4sfr_fx; + move16(); + n_pred = 8; + move16(); + IF( EQ_16( nBits, 7 ) ) + { + cdbk = gp_gamma_4sfr_7b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 25 ); + } + } + ELSE + { + cdbk = gp_gamma_4sfr_6b_fx; + move16(); + if ( EQ_16( clip_gain, 1 ) ) + { + size = sub( size, 11 ); + } + } + /* calculate predicted gain */ + aux[0] = 4096; + move16(); + aux[1] = shl( ctype, 12 ); + move16(); + + /*aux[2] = (float)log10(gc_mem[0]); + = log2(gc_mem[0])*log10(2);*/ + exp = norm_l( gc_mem[0] ); + frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + /*aux[3] = (float)log10(gc_mem[1]); + = log2(gc_mem[1])*log10(2);*/ + exp = norm_l( gc_mem[1] ); + frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + /*aux[4] = (float)log10(gc_mem[2]); + = log2(gc_mem[2])*log10(2);*/ + exp = norm_l( gc_mem[2] ); + frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) ); + exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/ + L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */ + aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */ + move16(); + + aux[5] = shr( gp_mem[0], 2 ); + move16(); /*Q12*/ + aux[6] = shr( gp_mem[1], 2 ); + move16(); /*Q12*/ + aux[7] = shr( gp_mem[2], 2 ); + move16(); /*Q12*/ + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, dotp(b, aux, n_pred) + * = pow(2, 3.321928*dotp(b, aux, n_pred) + *-----------------------------------------------------------------*/ + L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/ + L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */ + L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); + } + + /* *norm_gain_code = *gain_code / *gain_inov; */ + exp = sub( norm_s( *gain_inov ), 1 ); + exp = s_max( exp, 0 ); + + tmp = div_s( shr( 8192, exp ), *gain_inov ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + move32(); + { + push_indice( hBstr, IND_GAIN, index, nBits ); + } + return; +} + /*-------------------------------------------------------------------* * gain_enc_amr_wb() * diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 47b00e2c763a9cba8b27a9f3f76baa2d6500db81..7c2358ca9a1d85feef0fe7b3bea3c296b175261a 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -751,6 +751,10 @@ ivas_error init_encoder( st->EnergyLT = 0.0f; st->Energy_Old = 0; st->TransientHangOver = 0; +#ifdef IVAS_FLOAT_FIXED + st->last_enerBuffer_exp = 0; + move16(); +#endif /*-----------------------------------------------------------------* * Channel-aware mode @@ -831,6 +835,10 @@ ivas_error init_encoder( /* MDCT classifier */ MDCT_classifier_reset( st->hTcxEnc ); +#ifdef IVAS_FLOAT_FIXED + MDCT_classifier_reset_fx( st->hTcxEnc ); +#endif + if ( ( st->hTcxCfg = (TCX_CONFIG_HANDLE) malloc( sizeof( TCX_config ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hTcxCfg\n" ) ); diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index bb573b1c421e7674dbcaeb10e8f2eea1a7dddb00..448c95ab6e0d768aaea8ca1a5526c199fc01e974 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -6,10 +6,12 @@ #include "cnst.h" /* Common constants */ //#include "prot_fx.h" /* Function prototypes */ #include "basop_util.h" -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ /*==============================================================================*/ @@ -419,3 +421,389 @@ Word16 inov_encode_fx( return stack_pulses; } + +#ifdef IVAS_FLOAT_FIXED +Word16 inov_encode_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 last_L_frame, /* i : length of the last frame */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 tc_subfr, /* i : TC subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12*/ + const Word16 gain_pit, /* i : adaptive excitation gain Q14*/ + Word16 *cn, /* i/o: target vector in residual domain Q_new*/ + const Word16 *exc, /* i : pointer to excitation signal frame Q_new*/ + Word16 *h2, /* i/o: weighted filter input response Q12*/ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15*/ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + const Word16 *xn2, /* i : target vector for innovation search Q_new-1+shift*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word16 *y2, /* o : zero-memory filtered algebraic excitation Q9*/ + Word16 *unbits, /* o : number of unused bits for PI */ + const Word16 L_subfr, /* i : subframe length */ + Word16 shift, + Word16 Q_new ) +{ + Word16 dn[2 * L_SUBFR]; + Word16 nBits, cmpl_flag; + Word16 stack_pulses; + Word16 g1, g2; + Word16 Rw[L_SUBFR]; + Word16 acelpautoc; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + Word16 i, k; +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void) last_L_frame; +#endif + stack_pulses = 0; + move16(); + + IF( EQ_16( L_frame, L_FRAME ) ) + { + g1 = FORMANT_SHARPENING_G1; + move16(); + g2 = FORMANT_SHARPENING_G2; + move16(); + } + ELSE + { + g1 = FORMANT_SHARPENING_G1_16k; + move16(); + g2 = FORMANT_SHARPENING_G2_16k; + move16(); + } + + /*----------------------------------------------------------------* + * Update target vector for codebook search in residual domain + * Preemphasize the impulse response and include fixed-gain pitch contribution into impulse resp. h1[] (pitch sharpenning) + * Correlation between target xn2[] and impulse response h1[] + *----------------------------------------------------------------*/ + + test(); + test(); + IF( GT_32( core_brate, ACELP_13k20 ) && !Opt_AMR_WB && EQ_16( L_subfr, L_SUBFR ) ) + { + acelpautoc = 1; + move16(); + + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); + /* h2: Q11, Rw: (Rw_e)Q */ + /* Rw_e = */ E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); + + E_ACELP_conv( xn2, h2, cn ); + + /* dn_e -> Rw_e*Q_xn */ + /*dn_e = */ E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); + } + ELSE + { + acelpautoc = 0; + move16(); + updt_tar_fx( cn, cn, &exc[i_subfr], gain_pit, L_subfr ); + /* scaling of cn[] to limit dynamic at 12 bits */ + Scale_sig( cn, L_subfr, shift ); + + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); + corr_xh_ivas_fx( xn2, dn, h2, L_subfr ); // Q(dn) = Q_new+1 + } + + /*-----------------------------------------------------------------* + * Set complexity reduction flag to limit the number of iterations + * in algebraic innovation search + *-----------------------------------------------------------------*/ + cmpl_flag = 0; + move16(); + test(); + IF( st_fx->acelp_cfg.fcb_mode ) + { + /* set number of iterations in TD stereo, secondary channel */ + if ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) + { + cmpl_flag = 1; + move16(); + } + } + ELSE IF( EQ_16( L_frame, L_FRAME ) && EQ_16( coder_type, TRANSITION ) ) + { + test(); + test(); + if ( EQ_32( core_brate, ACELP_8k00 ) && i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) + { + cmpl_flag = 3; + move16(); + } + test(); + test(); + test(); + test(); + test(); + if ( EQ_32( core_brate, ACELP_11k60 ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || EQ_16( tc_subfr, TC_0_0 ) || ( EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( tc_subfr, TC_0_64 ) ) ) ) + { + cmpl_flag = 3; + move16(); + } + test(); + test(); + test(); + test(); + if ( ( EQ_32( core_brate, ACELP_13k20 ) || EQ_32( core_brate, ACELP_12k15 ) ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || LE_16( tc_subfr, TC_0_64 ) ) ) + { + cmpl_flag = 3; + move16(); + } + } + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + IF( LE_32( core_brate, ACELP_32k ) ) + { + cmpl_flag = 4; + move16(); + + test(); + IF( EQ_16( coder_type, TRANSITION ) && GT_16( bwidth, WB ) ) + { + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } + } + } + ELSE IF( LE_32( core_brate, ACELP_48k ) ) + { + cmpl_flag = 3; + move16(); + + IF( EQ_16( coder_type, TRANSITION ) ) + { + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } + } + } + ELSE + { + cmpl_flag = 4; + move16(); + + IF( EQ_16( coder_type, TRANSITION ) ) + { + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } + } + + if ( EQ_16( coder_type, INACTIVE ) ) + { + cmpl_flag = 4; + move16(); + } + } + } + + test(); + test(); + test(); + IF( NE_16( L_frame, st_fx->last_L_frame ) && GT_32( core_brate, ACELP_13k20 ) && ( LT_32( core_brate, ACELP_32k ) || EQ_16( bwidth, WB ) ) ) + { + if ( GT_16( cmpl_flag, 1 ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + } + + /*-----------------------------------------------------------------* + * Find and encode the algebraic innovation + *-----------------------------------------------------------------*/ + + set16_fx( y2, 0, L_SUBFR ); + + IF( !Opt_AMR_WB ) + { + IF( st_fx->acelp_cfg.fcb_mode ) + { // PMTE() +#if 1 + //#ifdef IVAS_CODE + Word16 idx = 0, idx2 = 0; + move16(); + move16(); + + IF( i_subfr != 0 ) + { + idx = idiv1616( i_subfr, L_subfr ); + idx2 = idiv1616( i_subfr, L_SUBFR ); + } + + IF( LT_16( st_fx->acelp_cfg.fixed_cdk_index[idx], ACELP_FIXED_CDK_NB ) ) + { + Word16 wordcnt, bitcnt; + Word16 prm[8]; + + test(); + test(); + test(); + IF( st_fx->acelp_cfg.fixed_cdk_index[idx] >= 0 ) + { + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[idx]; + move16(); + + IF( EQ_16( nBits, 8 ) ) + { + acelp_1t64_fx( hBstr, dn, h2, code, y2, L_subfr ); + } + ELSE + { + acelp_fast_fx( hBstr, nBits, dn, add( Q_new, 1 ), cn, h2, code, y2, L_subfr ); + } + } + ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 7 ) ) || ( st_fx->idchan == 0 && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 3 ) ) ) + { + IF( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] == 0 ) + { + acelp_1t64_fx( hBstr, dn, h2, code, y2, L_subfr ); + } + ELSE + { + acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, add( Q_new, 1 ), cn, h2, code, y2, L_SUBFR ); + } + } + ELSE + { + E_ACELP_4t_fx( dn, cn, h2, Rw, (Word8) acelpautoc, code, st_fx->acelp_cfg.fixed_cdk_index[idx2], prm, L_frame, last_L_frame, st_fx->total_brate, i_subfr, cmpl_flag ); + + wordcnt = shr( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 4 ); + move16(); + bitcnt = s_and( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 15 ); + move16(); + + FOR( i = 0; i < wordcnt; i++ ) + { + push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], 16 ); + } + IF( bitcnt ) + { + push_indice( hBstr, IND_ALG_CDBK_4T64, prm[i], bitcnt ); + } + + /* Generate weighted code */ + set16_fx( y2, 0, L_SUBFR ); + FOR( i = 0; i < L_SUBFR; i++ ) + { + /* Code is sparse, so check which samples are non-zero */ + IF( code[i] != 0 ) + { + FOR( k = 0; k < L_SUBFR - i; k++ ) + { + y2[i + k] += code[i] * h2[k]; + } + } + } + } + } + ELSE + { + set16_fx( code, 0, L_SUBFR ); + set16_fx( y2, 0, L_SUBFR ); + } + } +#ifdef DEBUGGING + else + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); + } +#endif +#endif + } + ELSE + { + nBits = st_fx->acelp_cfg.fixed_cdk_index[shr( i_subfr, 6 )]; + move16(); + + + IF( EQ_16( nBits, 7 ) ) + { + acelp_1t64_fx( hBstr, dn, h2, code, y2, L_SUBFR ); + } + ELSE IF( EQ_16( nBits, 12 ) ) + { + acelp_2t32_fx( hBstr, dn, h2, code, y2 ); + } + ELSE + { + *unbits = add( *unbits, acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, nBits, cmpl_flag, Opt_AMR_WB ) ); + move16(); + } + } + } + ELSE + { + IF( EQ_32( core_brate, ACELP_6k60 ) ) + { + acelp_2t32_fx( hBstr, dn, h2, code, y2 ); + } + ELSE IF( ( EQ_32( core_brate, ACELP_8k85 ) ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 20, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_12k65 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 36, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_14k25 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 44, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_15k85 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 52, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_18k25 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 64, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_19k85 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 72, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_23k05 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, cmpl_flag, Opt_AMR_WB ); + } + ELSE IF( EQ_32( core_brate, ACELP_23k85 ) ) + { + acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, 1, Opt_AMR_WB ); + } + } + + + /*----------------------------------------------------------------* + * Pitch sharpening + *----------------------------------------------------------------*/ + + cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, code, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); + + return stack_pulses; +} + +#endif diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 7893c4994c65c6f401ad7549e31494771ef3747b..97a04df0dc67ffe79178f81c253a685060effeda 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -97,7 +97,11 @@ ivas_error ivas_core_enc( float *new_swb_speech; float new_swb_speech_buffer[L_FRAME48k + STEREO_DFT_OVL_MAX]; float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float fixed conversions + float voice_factors[CPE_CHANNELS][NB_SUBFR16k] = { 0 }; +#else float voice_factors[CPE_CHANNELS][NB_SUBFR16k]; +#endif #ifdef IVAS_FLOAT_FIXED Word32 *new_swb_speech_fx; Word16 shb_speech_fx[L_FRAME16k]; @@ -111,7 +115,11 @@ ivas_error ivas_core_enc( Word16 new_swb_speech_buffer_fx1[L_FRAME48k + STEREO_DFT_OVL_MAX]; #endif int16_t Voicing_flag[CPE_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float fixed conversions + float pitch_buf[CPE_CHANNELS][NB_SUBFR16k] = { 0 }; +#else float pitch_buf[CPE_CHANNELS][NB_SUBFR16k]; +#endif #ifdef IVAS_FLOAT_FIXED Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k]; /* Q6 */ #endif @@ -725,7 +733,14 @@ ivas_error ivas_core_enc( { if ( st->hBWE_TD != NULL ) { +#ifdef IVAS_FLOAT_FIXED + InitSWBencBufferStates_fx( st->hBWE_TD, shb_speech_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS InitSWBencBufferStates( st->hBWE_TD, shb_speech ); +#endif +#else + InitSWBencBufferStates( st->hBWE_TD, shb_speech ); +#endif } } diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 50123f85702d0b21526a4d4fa0a1f4e14ebf91e3..8a10571be7297e9a03a0d985d24c7167cd6db013 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -40,7 +40,7 @@ #include "prot.h" #include "wmc_auto.h" #include "prot_fx.h" - +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * pre_proc_ivas() @@ -50,31 +50,31 @@ *--------------------------------------------------------------------*/ ivas_error pre_proc_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const int32_t element_brate, /* i : element bitrate */ - const int32_t last_element_brate, /* i : last element bitrate */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float *ener, /* o : residual energy from Levinson-Durbin */ - float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ - float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ - float epsP[M + 1], /* i/o: LP prediction errors */ - float lsp_new[M], /* i/o: LSPs at the end of the frame */ - float lsp_mid[M], /* i/o: LSPs in the middle of the frame */ - float *new_inp_resamp16k, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ - int16_t *Voicing_flag, /* o : voicing flag for HQ FEC */ - const float old_wsp[], /* i : weighted input signal buffer */ - const int16_t loc_harm, /* i : harmonicity flag */ - const float cor_map_sum, /* i : speech/music clasif. parameter */ - const int16_t vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO */ - const float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ - const float fft_buff[2 * L_FFT], /* i : FFT buffer */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int16_t vad_hover_flag, /* i : VAD hangover flag */ - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + Encoder_State *st, /* i/o: encoder state structure */ + const int16_t last_element_mode, /* i : last element mode */ + const int32_t element_brate, /* i : element bitrate */ + const int32_t last_element_brate, /* i : last element bitrate */ + const int16_t input_frame, /* i : frame length */ + float old_inp_12k8[], /* i/o: buffer of old input signal */ + float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ + float **inp, /* o : ptr. to inp. signal in the current frame*/ + float *ener, /* o : residual energy from Levinson-Durbin */ + float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ + float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ + float epsP[M + 1], /* i/o: LP prediction errors */ + float lsp_new[M], /* i/o: LSPs at the end of the frame */ + float lsp_mid[M], /* i/o: LSPs in the middle of the frame */ + float *new_inp_resamp16k, /* o : new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ + int16_t *Voicing_flag, /* o : voicing flag for HQ FEC */ + const float old_wsp[], /* i : weighted input signal buffer */ + const int16_t loc_harm, /* i : harmonicity flag */ + const float cor_map_sum, /* i : speech/music clasif. parameter */ + const int16_t vad_flag_dtx, /* i : HE-SAD flag with additional DTX HO */ + /*const*/ float enerBuffer[CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ + /*const*/ float fft_buff[2 * L_FFT], /* i : FFT buffer */ + const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ + const int16_t vad_hover_flag, /* i : VAD hangover flag */ + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ) { int16_t L_look, element_mode, lMemRecalc_12k8; @@ -228,8 +228,63 @@ ivas_error pre_proc_ivas( } /* core selection */ +#ifndef IVAS_FLOAT_FIXED ivas_decision_matrix_enc( st, element_brate, fft_buff, enerBuffer, last_element_mode ); +#else + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 fft_buff_fx[2 * L_FFT]; + Word32 enerBuffer_fx[CLDFB_NO_CHANNELS_MAX]; + + Word16 q_fft_buff; + + q_fft_buff = Q_factor_arr( fft_buff, ( 2 * L_FFT ) ); + + if ( q_fft_buff >= 2 ) + { + q_fft_buff -= 3; + } + else + { + q_fft_buff -= 4; + } + + floatToFixed_arr( fft_buff, fft_buff_fx, q_fft_buff, ( 2 * L_FFT ) ); + + Word16 e_enerBuffer; + + f2me_buf( enerBuffer, enerBuffer_fx, &e_enerBuffer, (Word32) CLDFB_NO_CHANNELS_MAX ); + + Word16 tmp_shift = find_guarded_bits_fx( 5 ); // Computing guraded bits necessary in the energyBuffer + + scale_sig32( enerBuffer_fx, CLDFB_NO_CHANNELS_MAX, -tmp_shift ); // Computing the shift as per guarded bits in the energyBuffer + e_enerBuffer += tmp_shift; // Shifting the exponent of energyBuffer with the tmp_shift + + floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, Q_factor_arrL( st->Bin_E_old, 129 ), 129 ); + + if ( st->element_mode != IVAS_SCE && !st->low_rate_mode && !( st->total_brate > MAX_ACELP_BRATE ) && st->element_mode != IVAS_CPE_MDCT && st->coder_type != INACTIVE && st->sp_aud_decision1 != 0 && st->sp_aud_decision2 != 0 && st->sp_aud_decision1 != 1 && st->sp_aud_decision2 != 0 && !( st->element_mode == IVAS_CPE_TD || st->sp_aud_decision0 == 0 ) ) + { + if ( st->hTcxEnc != NULL ) + { + st->hTcxEnc->clas_sec_old_fx = float_to_fix16( st->hTcxEnc->clas_sec_old_flt, Q13 ); + } + } + +#endif + ivas_decision_matrix_enc_fx( st, element_brate, fft_buff_fx, enerBuffer_fx, e_enerBuffer, last_element_mode ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + if ( st->element_mode != IVAS_SCE && !st->low_rate_mode && !( st->total_brate > MAX_ACELP_BRATE ) && st->element_mode != IVAS_CPE_MDCT && st->coder_type != INACTIVE && st->sp_aud_decision1 != 0 && st->sp_aud_decision2 != 0 && st->sp_aud_decision1 != 1 && st->sp_aud_decision2 != 0 && !( st->element_mode == IVAS_CPE_TD || st->sp_aud_decision0 == 0 ) ) + { + if ( st->hTcxEnc != NULL ) + { + st->hTcxEnc->clas_sec_old_flt = fix16_to_float( st->hTcxEnc->clas_sec_old_fx, Q13 ); + } + } +#endif + +#endif if ( st->L_frame == L_FRAME16k && ( st->coder_type == VOICED || st->coder_type == UNVOICED ) ) /* VOICED and UNVOICED are not supported in ACELP@16k */ { st->coder_type = GENERIC; diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 5167fe3f3bffcab1708f19f9ca08ccbed435c34c..8fca12d6cad5bfeec45eb7a202eb86865e0628bf 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -80,17 +80,22 @@ ivas_error ivas_cpe_enc( float old_inp_12k8[CPE_CHANNELS][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ float old_inp_16k[CPE_CHANNELS][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ #else - float old_inp_12k8[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ - float old_inp_16k[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ + float old_inp_12k8[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ #endif #ifdef IVAS_FLOAT_FIXED Word32 old_inp_12k8_fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ Word32 old_inp_16k_fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ #endif - float ener[CPE_CHANNELS]; /* residual energy from Levinson-Durbin */ - float relE[CPE_CHANNELS]; /* frame relative energy */ - float A[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ - float Aw[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ + float ener[CPE_CHANNELS]; /* residual energy from Levinson-Durbin */ + float relE[CPE_CHANNELS]; /* frame relative energy */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float A[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* A(z) unquantized for subframes */ + float Aw[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* weighted A(z) unquantized for subframes */ +#else + float A[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ + float Aw[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ +#endif float epsP[CPE_CHANNELS][M + 1]; /* LP prediction errors */ float lsp_new[CPE_CHANNELS][M]; /* LSPs at the end of the frame */ float lsp_mid[CPE_CHANNELS][M]; /* ISPs in the middle of the frame */ diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index a8f4d8aa189988c1fb68562069f1094b82ddfa0e..b3ae38f109ba56f8e67fc35de1d1c70744066365 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -39,7 +39,10 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" - +#include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ /*-----------------------------------------------------------------* * ivas_decision_matrix_enc() @@ -69,6 +72,7 @@ * Note: in MDCT stereo mode, TCX core is selected for all content * -------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ivas_decision_matrix_enc( Encoder_State *st, /* i : encoder state structure */ const int32_t element_brate, /* i : element bitrate */ @@ -338,7 +342,406 @@ void ivas_decision_matrix_enc( return; } +#else +void ivas_decision_matrix_enc_fx( + Encoder_State *st, /* i : encoder state structure */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 fft_buff[], /* i : FFT buffer */ + const Word32 enerBuffer[], /* i : energy buffer */ + Word16 enerBuffer_exp, + const Word16 last_element_mode /* i : last element mode */ +) +{ + Word32 icbwe_brate; + /* init */ + icbwe_brate = 0; + move32(); + + /* initialization */ + st->core = -1; + move16(); + + st->extl = -1; + move16(); + + st->extl_brate = 0; + move16(); + + IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + st->igf = 0; + move16(); + } + + test(); + test(); + + /* SID and FRAME_NO_DATA frames */ + IF( st->Opt_DTX_ON && ( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, FRAME_NO_DATA ) ) ) + { + st->core = ACELP_CORE; + move16(); + + test(); + IF( GE_32( st->input_Fs, 32000 ) || GE_16( st->bwidth, SWB ) ) + { + st->extl = SWB_CNG; + move16(); + } + st->rf_mode = 0; + move16(); + + return; + } + + /*---------------------------------------------------------------------* + * Select the core + *---------------------------------------------------------------------*/ + + test(); + test(); + test(); + + IF( EQ_16( st->element_mode, IVAS_SCE ) && st->low_rate_mode ) + { + /* ISM low-rate mode */ + st->core = ACELP_CORE; + move16(); + + st->coder_type = INACTIVE; + move16(); + } + ELSE IF( GT_32( st->total_brate, MAX_ACELP_BRATE ) ) + { + /* highest bitrates */ + st->core = TCX_20_CORE; + move16(); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + /* in MDCT stereo set TCX core */ + st->core = TCX_20_CORE; + move16(); + } + ELSE IF( EQ_16( st->coder_type, INACTIVE ) ) + { + /* inactive frames */ + test(); + IF( EQ_16( st->cng_type, FD_CNG ) && GE_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) + { + st->core = TCX_20_CORE; + move16(); + } + ELSE + { + st->core = ACELP_CORE; + move16(); + } + } + ELSE IF( st->sp_aud_decision1 == 0 && st->sp_aud_decision2 == 0 ) + { + /* speech */ + st->core = ACELP_CORE; + move16(); + } + ELSE IF( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) + { + /* music w. GSC core */ + st->core = ACELP_CORE; + + move16(); + } + ELSE /* sp_aud_decision1 == 1 && *sp_aud_decision2 == 1 */ + { + /* music w. TCX or HQ core */ + st->core = TCX_20_CORE; + move16(); + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) || st->sp_aud_decision0 == 0 ) + { + st->core = TCX_20_CORE; + move16(); + } + ELSE + { + /* select TCX core or HQ core using bits_frame_nominal to match the TCX configuration bitrate */ + st->core = mdct_classifier_ivas_fx( st, fft_buff, enerBuffer, enerBuffer_exp, ( st->bits_frame_nominal * FRAMES_PER_SEC ) ); + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + + /* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */ + IF( ( ( EQ_16( st->last_core, ACELP_CORE ) && EQ_16( last_element_mode, IVAS_CPE_TD ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) ) || ( EQ_16( st->tdm_LRTD_flag, 1 ) && LE_32( st->total_brate, IVAS_16k4 ) ) ) && EQ_16( st->core, TCX_20_CORE ) && LE_32( st->total_brate, MAX_ACELP_BRATE ) ) /* Override TCX in case of LRTD && primary channel has low bitrate*/ + { + st->core = ACELP_CORE; + move16(); + } + + test(); + IF( st->is_ism_format && st->tcxonly ) + { + st->core = TCX_20_CORE; + move16(); + } + + /* TCX not available at low bitrates -> replace it by GSC */ + + test(); + IF( EQ_16( st->core, TCX_20_CORE ) && LT_32( st->total_brate, STEREO_TCX_MIN_RATE ) ) + { + st->core = ACELP_CORE; + st->coder_type = AUDIO; + st->sp_aud_decision2 = 0; + + move16(); + move16(); + move16(); + + IF( st->low_rate_mode ) + { + st->coder_type = INACTIVE; + move16(); + } + } + + /* sanity check to avoid too low ACELP bitrate in case of "limitation to avoid too high bitrate in one active TCX channel" at element_brate = 32000 */ + test(); + test(); + test(); + test(); + IF( st->is_ism_format && st->flag_ACELP16k && !st->low_rate_mode && EQ_16( st->core, ACELP_CORE ) && LT_32( st->total_brate, add( ACELP_16k_LOW_LIMIT, FB_TBE_1k8 ) ) ) + { + st->core = TCX_20_CORE; + move16(); + } + + /*---------------------------------------------------------------------* + * Select ACELP and GSC extension layer + *---------------------------------------------------------------------*/ + + IF( EQ_16( st->core, ACELP_CORE ) ) + { + /* WB */ + IF( EQ_16( st->bwidth, WB ) ) + { + test(); + test(); + test(); + test(); + IF( LT_32( st->total_brate, MIN_BRATE_WB_BWE ) || ( EQ_16( st->idchan, 1 ) && EQ_16( st->element_mode, IVAS_CPE_TD ) ) ) + { + st->extl = WB_BWE; + move16(); + } + ELSE IF( GE_16( extract_l( st->total_brate ), MIN_BRATE_WB_BWE ) && !st->flag_ACELP16k ) + { + test(); + test(); + IF( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || EQ_16( st->coder_type, INACTIVE ) ) + { + 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(); + } + } + } + } + + /* SWB and FB */ + ELSE IF( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GE_32( st->total_brate, MIN_BRATE_SWB_BWE ) /*&& (NE_16(*coder_type, AUDIO) || GE_32(st->total_brate, add(MIN_BWE_PRI_BRATE, 600)))*/ + || ( 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 ) ) ) + { + test(); + test(); + test(); + IF( ( ( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || EQ_16( st->coder_type, INACTIVE ) ) && !st->GSC_noisy_speech ) /* Note: SWB BWE is not used for GSC noisy speech */ ) + { + st->extl = SWB_BWE; + move16(); + + st->extl_brate = SWB_BWE_1k6; + move32(); + + IF( EQ_16( st->bwidth, FB ) ) + { + st->extl = FB_BWE; + move16(); + + st->extl_brate = FB_BWE_1k8; + move32(); + } + } + ELSE + { + st->extl = SWB_TBE; + move16(); + st->extl_brate = SWB_TBE_1k6; + move32(); + + test(); + test(); + test(); + 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(); + } + + IF( EQ_16( st->bwidth, FB ) ) + { + st->extl = FB_TBE; + move16(); + + st->extl_brate = FB_TBE_1k8; + move32(); + + test(); + test(); + 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(); + } + } + } + } + ELSE + { + st->extl = WB_BWE; + move16(); + + st->extl_brate = 0; + move32(); + } + + /* set IC-BWE bitrate */ + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && ( st->idchan == 0 ) && !st->tdm_LRTD_flag ) + { + icbwe_brate = STEREO_BITS_ICBWE * FRAMES_PER_SEC; + move32(); + + IF( 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( st->flag_ACELP16k == 0 ) + { + icbwe_brate = ( STEREO_BITS_ICBWE_DFT - STEREO_ICBWE_SPBITS ) * FRAMES_PER_SEC; + move32(); + } + } + + 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 ); + move32(); + } + } + } + + /* set core bitrate */ + + st->core_brate = L_sub( L_sub( st->total_brate, st->extl_brate ), icbwe_brate ); + move32(); + + IF( st->ini_frame == 0 ) + { + /* avoid core switching in the very first frame */ + st->last_core = st->core; + move16(); + + st->last_core_brate = st->core_brate; + move32(); + + st->last_extl = st->extl; + 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(); + } + + return; +} +#endif /*---------------------------------------------------------------------* * ivas_signaling_enc() diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 80ace46765266d44ec4818bfa9f1a6e6d735873c..d56ae05d05cabda06598ab9e1e4c369ede9f8395 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -431,18 +431,24 @@ ivas_error ivas_ism_enc( Encoder_State *st; Word16 sce_id; #ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion - float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ - float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ + float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ + float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ #else - float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ - float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP]; /* buffer of input signal @ 16kHz */ + float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP]; /* buffer of input signal @ 16kHz */ +#endif + Word16 vad_flag[MAX_NUM_OBJECTS]; /* VAD flag */ + float ener[MAX_NUM_OBJECTS][1]; /* residual energy from Levinson-Durbin */ + float relE[MAX_NUM_OBJECTS][1]; /* frame relative energy */ + Word16 relE_fx[MAX_NUM_OBJECTS][1]; + /* frame relative energy, Q8 */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float A[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* A(z) unquantized for subframes */ + float Aw[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* weighted A(z) unquantized for subframes */ +#else + float A[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ + float Aw[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ #endif - Word16 vad_flag[MAX_NUM_OBJECTS]; /* VAD flag */ - float ener[MAX_NUM_OBJECTS][1]; /* residual energy from Levinson-Durbin */ - float relE[MAX_NUM_OBJECTS][1]; /* frame relative energy */ - Word16 relE_fx[MAX_NUM_OBJECTS][1]; /* frame relative energy, Q8 */ - float A[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ - float Aw[MAX_NUM_OBJECTS][1][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ float epsP[MAX_NUM_OBJECTS][1][M + 1]; /* LP prediction errors */ float lsp_new[MAX_NUM_OBJECTS][1][M]; /* LSPs at the end of the frame */ float lsp_mid[MAX_NUM_OBJECTS][1][M]; /* ISPs in the middle of the frame */ diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 89b0070ae8f3c16366c026638f18c312525ea7e5..815db85b4b13e11f0923e000f2b63b66b4334be5 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -429,6 +429,77 @@ static int16_t kernel_switch_detect( #endif +#ifdef IVAS_FLOAT_FIXED +static void kernel_switch_trafo_fx( + const Word32 *x, /* Input (Q_in) */ + Word32 *y, /* Output (Q_in - 1) */ + const Word16 l, + const Word16 m, + const Word16 r, + const UWord16 kernelType ) +{ + Word16 i; + Word32 inputBuffer[N_MAX]; + Word16 tmp, exp_tmp; + Word32 factor; + + /* Init */ + FOR( i = 0; i < m / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 + i] = L_negate( x[l + m / 2 - 1 - i] ); // Q_in + move32(); + } + + IF( GE_32( kernelType, MDCT_II ) ) + { + FOR( i = 0; i < l / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 + m / 2 + i] = L_sub( L_negate( x[i] ), x[l - 1 - i] ); // Q_in + move32(); + } + } + ELSE + { + FOR( i = 0; i < l / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 + m / 2 + i] = L_sub( x[i], x[l - 1 - i] ); // Q_in + move32(); + } + } + + FOR( i = 0; i < m / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 - 1 - i] = L_negate( x[l + m / 2 + i] ); // Q_in + move32(); + } + + IF( UL_and( kernelType, 1 ) ) + { + FOR( i = 0; i < r / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 - 1 - m / 2 - i] = L_add( L_negate( x[l + m + i] ), x[l + m + r - 1 - i] ); // Q_in + move32(); + } + } + ELSE + { + FOR( i = 0; i < r / 2; i++ ) + { + inputBuffer[m / 2 + r / 2 - 1 - m / 2 - i] = L_negate( L_add( x[l + m + i], x[l + m + r - 1 - i] ) ); // Q_in + move32(); + } + } + + edxt_fx( inputBuffer, y, add( shr( l, 1 ), add( m, shr( r, 1 ) ) ), kernelType, FALSE ); // Q_in + + tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, add( shr( l, 1 ), add( m, shr( r, 1 ) ) ), &exp_tmp ); + tmp = Sqrt16( tmp, &exp_tmp ); + factor = L_shl( L_deposit_h( tmp ), sub( exp_tmp, 1 ) ); // Q30 + v_multc_fixed( y, factor, y, add( shr( l, 1 ), add( m, shr( r, 1 ) ) ) ); // (Q_in, Q30) -> Q_in - 1 + + return; +} +#else static void kernel_switch_trafo( const float *x, float *y, @@ -469,8 +540,237 @@ static void kernel_switch_trafo( return; } +#endif + + +#ifdef IVAS_FLOAT_FIXED +static void kernel_switch_update_transforms_fx( + Word32 *sigR, /* i/o: MDCT samples of the given channel (*q_sig) */ + Word32 *sigI, /* i/o: MDST samples of the given channel (*q_sig) */ + Word16 *q_sig, /* i/o: Common Q of MDCT and MDST samples of the given channel */ + const Word16 tcxTransType, /* i : TCX transform type, cf also above */ + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration handle, pointer */ + const Word16 bwidthSwCnt, /* i : bandwidth switching counter in st */ + const UWord16 kernelType, /* i : TCX transform kernel type (0 - 3) */ + Word16 *tcxTimeSignal, /* i : hTcxEnc->new_speech_TCX buf in st */ + const Word16 *speech_TCX, /* i : hTcxEnc->speech_TCX buffer in st */ + Word32 *windowedTimeSignal, /* i/o: windowed input and scratch buffer (*q_windowedTimeSignal) */ + Word16 *q_windowedTimeSignal, /* i/o: Q of windowed input and scratch buffer */ + const Word16 L_subframe /* i : transform length (number of bins) */ +) +{ + Word16 s, nSubframes; + + s = L_subframe; + move16(); + IF( EQ_16( tcxTransType, TCX_20 ) ) + { + nSubframes = 1; + move16(); + } + ELSE + { + nSubframes = NB_DIV; + move16(); + } + + IF( kernelType == MDCT_IV ) /* no updates required here! */ + { + return; + } + + IF( EQ_32( kernelType, MDST_IV ) ) /* swap real and imag. parts */ + { + FOR( s = L_subframe - 1; s >= 0; s-- ) + { + const Word32 sigTemp = L_negate( sigR[s] ); + + sigR[s] = sigI[s]; + move32(); + sigI[s] = sigTemp; + move32(); + } + + return; + } + + /* MDCT/MDST-II as real part, keep imag. part for speedup */ + test(); + IF( EQ_16( tcxTransType, TCX_20 ) && NE_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) + { + Word16 n, q_com; + Word16 windowedTimeSignal_16[2 + L_FRAME48k]; + Word16 tmp, exp_tmp; + Word32 factor; + + n = extract_l( Mpy_32_32( s, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) ); + Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), -Q1 ); // Q0 -> Q-1 + wtda_ext_fx( tcxTimeSignal, windowedTimeSignal_16, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), s, kernelType ); // Q-1 + Scale_sig( &tcxTimeSignal[n - s], shl( s, 1 ), Q1 ); // Q-1 -> Q0 + + Copy_Scale_sig_16_32_no_sat( windowedTimeSignal_16, windowedTimeSignal, s, Q16 ); // Q15 + scale_sig32( windowedTimeSignal, s, -Q8 /* guard bits */ ); // Q7 + edxt_fx( windowedTimeSignal, sigR, s, kernelType, FALSE ); + + tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, s, &exp_tmp ); + tmp = Sqrt16( tmp, &exp_tmp ); + factor = L_shl( L_deposit_h( tmp ), sub( exp_tmp, Q1 ) ); // Q30 + v_multc_fixed( sigR, factor, sigR, s ); // (Q7, Q30) -> Q6 + + q_com = L_norm_arr( sigR, s ); + q_com = s_min( add( q_com, Q6 ), *q_sig ); + scale_sig32( sigR, s, sub( q_com, Q6 ) ); // q_com + scale_sig32( sigI, s, sub( q_com, *q_sig ) ); // q_com + *q_sig = q_com; + move16(); + } + ELSE /* 2 TCX5 subframes or 1 TCX10 or 1 transitory TCX20 */ + { + const Word16 minWindowLen = sub( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); + Word16 i, leftOverlap = 0, rightOverlap = 0; + PWord16 const *left_win; + PWord16 const *right_win; + move16(); + move16(); + + tcx_get_windows( hTcxCfg, extract_l( windowedTimeSignal[0] ), extract_l( windowedTimeSignal[1] ), &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); + test(); + test(); + test(); + IF( speech_TCX != NULL && NE_16( tcxTransType, TCX_20 ) && windowedTimeSignal[0] == FULL_OVERLAP && GT_16( sub( s, leftOverlap ), minWindowLen ) ) + { + Word16 tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); + Word32 L_tmp; + IF( GE_32( kernelType, MDCT_II ) ) + { + FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ + { + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal + move32(); + } + FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ + { + L_tmp = L_mult( speech_TCX[-1 - i], hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal + move32(); + } + } + ELSE + { + FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */ + { + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal + move32(); + } + FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */ + { + L_tmp = L_mult( negate( speech_TCX[-1 - i] ), hTcxCfg->tcx_aldo_window_1_FB[leftOverlap / 2 + minWindowLen - i] ); // (Q0, Q15) -> Q16 + L_tmp = Mpy_32_16_1( L_tmp, hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16, Q15) -> Q16 + L_tmp = L_shl( L_tmp, sub( *q_windowedTimeSignal, Q16 ) ); // *q_windowedTimeSignal + windowedTimeSignal[2 + leftOverlap + i] = L_add( windowedTimeSignal[2 + leftOverlap + i], L_tmp ); // *q_windowedTimeSignal + move32(); + } + } + } + + IF( EQ_16( tcxTransType, TCX_5 ) ) + { + Word16 tcx5Win[N_TCX10_MAX / 2 + L_MDCT_OVLP_MAX]; /* temporary buffer for TCX5 windowing */ + Word32 tcx5Win_32[N_TCX10_MAX / 2 + L_MDCT_OVLP_MAX]; /* temporary buffer for TCX5 windowing */ + Word16 windowedTimeSignal_16[2 + L_FRAME48k]; + Word16 q_shift, q_com; + + assert( L_subframe == nSubframes * hTcxCfg->tcx5SizeFB ); + + /* Outer left folding */ + IF( GE_32( kernelType, MDCT_II ) ) + { + FOR( i = 0; i < leftOverlap / 2; i++ ) + { + windowedTimeSignal[2 + leftOverlap / 2 + i] = L_add( windowedTimeSignal[2 + leftOverlap / 2 + i], windowedTimeSignal[2 + leftOverlap / 2 - 1 - i] ); // *q_windowedTimeSignal + move32(); + } + } + ELSE + { + FOR( i = 0; i < leftOverlap / 2; i++ ) + { + windowedTimeSignal[2 + leftOverlap / 2 + i] = L_sub( windowedTimeSignal[2 + leftOverlap / 2 + i], windowedTimeSignal[2 + leftOverlap / 2 - 1 - i] ); // *q_windowedTimeSignal + move32(); + } + } + s = hTcxCfg->tcx5SizeFB; /* obtain 1st TCX5 again */ + move16(); + nSubframes = shl( nSubframes, 1 ); + Copy_Scale_sig_32_16( windowedTimeSignal + 2, windowedTimeSignal_16 + 2, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), -Q16 ); // *q_windowedTimeSignal - Q16 + WindowSignal( hTcxCfg, shr( leftOverlap, 1 ), RECTANGULAR_OVERLAP, MIN_OVERLAP, &leftOverlap, &rightOverlap, windowedTimeSignal_16 + 2, &s, tcx5Win, 0, 1 ); // *q_windowedTimeSignal - Q16 + Copy_Scale_sig_16_32_no_sat( tcx5Win, tcx5Win_32, add( s, shr( add( leftOverlap, rightOverlap ), 1 ) ), Q16 ); // *q_windowedTimeSignal + + q_shift = -Q7; + move16(); + scale_sig32( tcx5Win_32, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift + kernel_switch_trafo_fx( tcx5Win_32, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift + + /* Move both sigR and sigI to common Q */ + q_com = s_min( *q_sig, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ); + scale_sig32( sigR, s, sub( q_com, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ) ); + scale_sig32( sigR + s, sub( L_subframe, s ), sub( q_com, *q_sig ) ); + scale_sig32( sigI, L_subframe, sub( q_com, *q_sig ) ); + *q_sig = q_com; + move16(); + IF( UL_and( kernelType, 1 ) ) /* 2nd TCX5 is kernelType 3 */ + { + FOR( i = L_subframe - 1; i >= s; i-- ) + { + const Word32 sigTemp = L_negate( sigR[i] ); + sigR[i] = sigI[i]; + move32(); + sigI[i] = sigTemp; + move32(); + } + } + } + ELSE /* tcxTransType != TCX_5 */ + { + Word16 q_shift, q_com; + q_shift = -Q7; + move16(); + scale_sig32( windowedTimeSignal + 2, add( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), q_shift ); // *q_windowedTimeSignal + q_shift + kernel_switch_trafo_fx( windowedTimeSignal + 2, sigR, leftOverlap, sub( s /* L_subfr. */, shr( add( leftOverlap, rightOverlap ), 1 ) ), rightOverlap, kernelType ); // *q_windowedTimeSignal + q_shift + + /* Move both sigR and sigI to common Q */ + q_com = s_min( *q_sig, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ); + scale_sig32( sigR, s, sub( q_com, sub( add( *q_windowedTimeSignal, q_shift ), Q1 ) ) ); + scale_sig32( sigR + s, sub( L_subframe, s ), sub( q_com, *q_sig ) ); + scale_sig32( sigI, L_subframe, sub( q_com, *q_sig ) ); + *q_sig = q_com; + move16(); + } + } + + /* high-band gain control, in case of bandwidth switching */ + IF( bwidthSwCnt > 0 ) + { + Word16 tmp, exp_tmp; + Word32 factor; + tmp = BASOP_Util_Divide1616_Scale( bwidthSwCnt, BWS_TRAN_PERIOD, &exp_tmp ); + factor = L_shl( L_deposit_h( tmp ), exp_tmp ); // Q31 + v_multc_fixed( sigR + L_FRAME16k / nSubframes, factor, sigR + L_FRAME16k / nSubframes, sub( s, idiv1616( L_FRAME16k, nSubframes ) ) ); // *q_sig + } + + return; +} +#else static void kernel_switch_update_transforms( float *sigR, /* i/o: MDCT samples of the given channel */ float *sigI, /* i/o: MDST samples of the given channel */ @@ -574,6 +874,7 @@ static void kernel_switch_update_transforms( return; } +#endif static void applyStereoPreProcessingCplx( @@ -1089,10 +1390,99 @@ void ivas_mdct_core_whitening_enc( hTcxEnc0->kernel_symmetry_past = hTcxEnc0->kernel_type[n] & 1; hTcxEnc1->kernel_symmetry_past = hTcxEnc1->kernel_type[n] & 1; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word32 windowedSignal_fx[L_FRAME48k]; + set32_fx( windowedSignal_fx, 0, L_FRAME48k ); + + q_com = L_get_q_buf1( hTcxEnc0->spectrum[n], hTcxEnc0->L_frameTCX / nSubframes ); + q_com = s_min( q_com, L_get_q_buf1( mdst_spectrum[0][n], hTcxEnc0->L_frameTCX / nSubframes ) ); + floatToFixed_arrL32( hTcxEnc0->spectrum[n], hTcxEnc0->spectrum_fx[n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); + floatToFixed_arrL32( mdst_spectrum[0][n], mdst_spectrum_fx[0][n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); + + Word16 nl = (int16_t) ( (float) ( hTcxEnc0->L_frameTCX / nSubframes ) * N_ZERO_MDCT_NS / FRAME_SIZE_NS ); + floatToFixed_arr( &hTcxEnc0->new_speech_TCX_flt[nl - ( hTcxEnc0->L_frameTCX / nSubframes )], + &hTcxEnc0->new_speech_TCX[nl - ( hTcxEnc0->L_frameTCX / nSubframes )], + 0, + 2 * hTcxEnc0->L_frameTCX / nSubframes ); + + if ( n == 0 ) + { + floatToFixed_arr( &hTcxEnc0->speech_TCX_flt[-( sts[0]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + &hTcxEnc0->speech_TCX[-( sts[0]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + 0, + sts[0]->hTcxCfg->tcx_mdct_window_min_lengthFB ); + } + + Word16 leftOverlap = 0, rightOverlap = 0; + PWord16 const *left_win; + PWord16 const *right_win; + Word16 q_windowedSignal, len_windowSignal; + + windowedSignal_fx[0] = ( Word16 ) * ( windowedSignal[0] + n * L_FRAME48k ); + windowedSignal_fx[1] = ( Word16 ) * ( windowedSignal[0] + n * L_FRAME48k + 1 ); + if ( ( hTcxEnc0->transform_type[n] == TCX_5 ) || ( n == 0 /* speech_TCX != NULL*/ && NE_16( hTcxEnc0->transform_type[n], TCX_20 ) && windowedSignal_fx[0] == FULL_OVERLAP && GT_16( sub( L_subframeTCX / nSubframes, leftOverlap ), sts[0]->hTcxCfg->tcx_mdct_window_min_lengthFB - 1 ) ) ) + { + tcx_get_windows( sts[0]->hTcxCfg, extract_l( windowedSignal_fx[0] ), extract_l( windowedSignal_fx[1] ), &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); + len_windowSignal = ( L_subframeTCX / nSubframes ) + ( leftOverlap + rightOverlap ) / 2; + q_windowedSignal = Q_factor_arrL( windowedSignal[0] + n * L_FRAME48k + 2, len_windowSignal ) - 1; + floatToFixed_arrL32( windowedSignal[0] + n * L_FRAME48k + 2, windowedSignal_fx + 2, q_windowedSignal, len_windowSignal ); + } +#endif + kernel_switch_update_transforms_fx( hTcxEnc0->spectrum_fx[n], mdst_spectrum_fx[0][n], &q_com, hTcxEnc0->transform_type[n], sts[0]->hTcxCfg, sts[0]->bwidth_sw_cnt, hTcxEnc0->kernel_type[n], + hTcxEnc0->new_speech_TCX, ( n == 1 ? NULL : hTcxEnc0->speech_TCX ), windowedSignal_fx, &q_windowedSignal, L_subframeTCX / nSubframes ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL32( hTcxEnc0->spectrum_fx[n], hTcxEnc0->spectrum[n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); + fixedToFloat_arrL32( mdst_spectrum_fx[0][n], mdst_spectrum[0][n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); +#endif +#else kernel_switch_update_transforms( hTcxEnc0->spectrum[n], mdst_spectrum[0][n], hTcxEnc0->transform_type[n], sts[0]->hTcxCfg, sts[0]->bwidth_sw_cnt, hTcxEnc0->kernel_type[n], hTcxEnc0->new_speech_TCX_flt, ( n == 1 ? NULL : hTcxEnc0->speech_TCX_flt ), windowedSignal[0] + n * L_FRAME48k, L_subframeTCX / nSubframes ); +#endif +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + // Word32 windowedSignal_fx[L_FRAME48k]; + set32_fx( windowedSignal_fx, 0, L_FRAME48k ); + + q_com = L_get_q_buf1( hTcxEnc1->spectrum[n], hTcxEnc1->L_frameTCX / nSubframes ); + q_com = s_min( q_com, L_get_q_buf1( mdst_spectrum[1][n], hTcxEnc1->L_frameTCX / nSubframes ) ); + floatToFixed_arrL32( hTcxEnc1->spectrum[n], hTcxEnc1->spectrum_fx[n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); + floatToFixed_arrL32( mdst_spectrum[1][n], mdst_spectrum_fx[1][n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); + + nl = (int16_t) ( (float) ( hTcxEnc1->L_frameTCX / nSubframes ) * N_ZERO_MDCT_NS / FRAME_SIZE_NS ); + floatToFixed_arr( &hTcxEnc1->new_speech_TCX_flt[nl - ( hTcxEnc1->L_frameTCX / nSubframes )], + &hTcxEnc1->new_speech_TCX[nl - ( hTcxEnc1->L_frameTCX / nSubframes )], + 0, + 2 * hTcxEnc1->L_frameTCX / nSubframes ); + + if ( n == 0 ) + { + floatToFixed_arr( &hTcxEnc1->speech_TCX_flt[-( sts[1]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + &hTcxEnc1->speech_TCX[-( sts[1]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + 0, + sts[1]->hTcxCfg->tcx_mdct_window_min_lengthFB ); + } + + windowedSignal_fx[0] = ( Word16 ) * ( windowedSignal[1] + n * L_FRAME48k ); + windowedSignal_fx[1] = ( Word16 ) * ( windowedSignal[1] + n * L_FRAME48k + 1 ); + if ( ( hTcxEnc1->transform_type[n] == TCX_5 ) || ( n == 0 /* speech_TCX != NULL*/ && NE_16( hTcxEnc1->transform_type[n], TCX_20 ) && windowedSignal_fx[0] == FULL_OVERLAP && GT_16( sub( L_subframeTCX / nSubframes, leftOverlap ), sts[1]->hTcxCfg->tcx_mdct_window_min_lengthFB - 1 ) ) ) + { + tcx_get_windows( sts[1]->hTcxCfg, extract_l( windowedSignal_fx[0] ), extract_l( windowedSignal_fx[1] ), &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); + len_windowSignal = ( L_subframeTCX / nSubframes ) + ( leftOverlap + rightOverlap ) / 2; + q_windowedSignal = Q_factor_arrL( windowedSignal[1] + n * L_FRAME48k + 2, len_windowSignal ) - 1; + floatToFixed_arrL32( windowedSignal[1] + n * L_FRAME48k + 2, windowedSignal_fx + 2, q_windowedSignal, len_windowSignal ); + } +#endif + kernel_switch_update_transforms_fx( hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[1][n], &q_com, hTcxEnc1->transform_type[n], sts[1]->hTcxCfg, sts[1]->bwidth_sw_cnt, hTcxEnc1->kernel_type[n], + hTcxEnc1->new_speech_TCX, ( n == 1 ? NULL : hTcxEnc1->speech_TCX ), windowedSignal_fx, &q_windowedSignal, L_subframeTCX / nSubframes ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL32( hTcxEnc1->spectrum_fx[n], hTcxEnc1->spectrum[n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); + fixedToFloat_arrL32( mdst_spectrum_fx[1][n], mdst_spectrum[1][n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); +#endif +#else kernel_switch_update_transforms( hTcxEnc1->spectrum[n], mdst_spectrum[1][n], hTcxEnc1->transform_type[n], sts[1]->hTcxCfg, sts[1]->bwidth_sw_cnt, hTcxEnc1->kernel_type[n], hTcxEnc1->new_speech_TCX_flt, ( n == 1 ? NULL : hTcxEnc1->speech_TCX_flt ), windowedSignal[1] + n * L_FRAME48k, L_subframeTCX / nSubframes ); +#endif } for ( n = 0; n < nSubframes; n++ ) { @@ -1153,8 +1543,55 @@ void ivas_mdct_core_whitening_enc( hTcxEncCh->kernel_type[n] = ( hTcxEncCh->kernel_symmetry_past && sts[ch]->element_mode == IVAS_CPE_MDCT ? 3 - mct_on : 0 ); hTcxEncCh->kernel_symmetry_past = hTcxEncCh->kernel_type[n] & 1; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word32 windowedSignal_fx[L_FRAME48k]; + set32_fx( windowedSignal_fx, 0, L_FRAME48k ); + + q_com = L_get_q_buf1( hTcxEncCh->spectrum[n], hTcxEncCh->L_frameTCX / nSubframes ); + q_com = s_min( q_com, L_get_q_buf1( mdst_spectrum[ch][n], hTcxEncCh->L_frameTCX / nSubframes ) ); + floatToFixed_arrL32( hTcxEncCh->spectrum[n], hTcxEncCh->spectrum_fx[n], q_com, hTcxEncCh->L_frameTCX / nSubframes ); + floatToFixed_arrL32( mdst_spectrum[ch][n], mdst_spectrum_fx[ch][n], q_com, hTcxEncCh->L_frameTCX / nSubframes ); + + Word16 nl = (int16_t) ( (float) ( hTcxEncCh->L_frameTCX / nSubframes ) * N_ZERO_MDCT_NS / FRAME_SIZE_NS ); + floatToFixed_arr( &hTcxEncCh->new_speech_TCX_flt[nl - ( hTcxEncCh->L_frameTCX / nSubframes )], + &hTcxEncCh->new_speech_TCX[nl - ( hTcxEncCh->L_frameTCX / nSubframes )], + 0, + 2 * hTcxEncCh->L_frameTCX / nSubframes ); + + if ( n == 0 ) + { + floatToFixed_arr( &hTcxEncCh->speech_TCX_flt[-( sts[ch]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + &hTcxEncCh->speech_TCX[-( sts[ch]->hTcxCfg->tcx_mdct_window_min_lengthFB - 0 )], + 0, + sts[ch]->hTcxCfg->tcx_mdct_window_min_lengthFB ); + } + + Word16 leftOverlap = 0, rightOverlap = 0; + PWord16 const *left_win; + PWord16 const *right_win; + Word16 q_windowedSignal, len_windowSignal; + + windowedSignal_fx[0] = ( Word16 ) * ( windowedSignal[ch] + n * L_FRAME48k ); + windowedSignal_fx[1] = ( Word16 ) * ( windowedSignal[ch] + n * L_FRAME48k + 1 ); + if ( ( hTcxEncCh->transform_type[n] == TCX_5 ) || ( n == 0 /* speech_TCX != NULL*/ && NE_16( hTcxEncCh->transform_type[n], TCX_20 ) && windowedSignal_fx[0] == FULL_OVERLAP && GT_16( sub( L_subframeTCX / nSubframes, leftOverlap ), sts[ch]->hTcxCfg->tcx_mdct_window_min_lengthFB - 1 ) ) ) + { + tcx_get_windows( sts[ch]->hTcxCfg, extract_l( windowedSignal_fx[0] ), extract_l( windowedSignal_fx[1] ), &leftOverlap, &left_win, &rightOverlap, &right_win, 1 ); + len_windowSignal = ( L_subframeTCX / nSubframes ) + ( leftOverlap + rightOverlap ) / 2; + q_windowedSignal = Q_factor_arrL( windowedSignal[ch] + n * L_FRAME48k + 2, len_windowSignal ) - 1; + floatToFixed_arrL32( windowedSignal[ch] + n * L_FRAME48k + 2, windowedSignal_fx + 2, q_windowedSignal, len_windowSignal ); + } +#endif + kernel_switch_update_transforms_fx( hTcxEncCh->spectrum_fx[n], mdst_spectrum_fx[ch][n], &q_com, hTcxEncCh->transform_type[n], sts[ch]->hTcxCfg, sts[ch]->bwidth_sw_cnt, hTcxEncCh->kernel_type[n], + hTcxEncCh->new_speech_TCX, ( n /*1*/ ? NULL : hTcxEncCh->speech_TCX ), windowedSignal_fx, &q_windowedSignal, L_subframeTCX / nSubframes ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL32( hTcxEncCh->spectrum_fx[n], hTcxEncCh->spectrum[n], q_com, hTcxEncCh->L_frameTCX / nSubframes ); + fixedToFloat_arrL32( mdst_spectrum_fx[ch][n], mdst_spectrum[ch][n], q_com, hTcxEncCh->L_frameTCX / nSubframes ); +#endif +#else kernel_switch_update_transforms( hTcxEncCh->spectrum[n], mdst_spectrum[ch][n], hTcxEncCh->transform_type[n], sts[ch]->hTcxCfg, sts[ch]->bwidth_sw_cnt, hTcxEncCh->kernel_type[n], hTcxEncCh->new_speech_TCX_flt, ( n /*1*/ ? NULL : hTcxEncCh->speech_TCX_flt ), windowedSignal[ch] + n * L_FRAME48k, L_subframeTCX / nSubframes ); +#endif } } } diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index ef5328d2b9641565559e752c8cf1720dbf1e2b43..4adcc2ed3f80b890c641cfd1c925378e8a047bca 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -69,13 +69,18 @@ ivas_error ivas_sce_enc( float old_inp_12k8[1][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ float old_inp_16k[1][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ #else - float old_inp_12k8[1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ - float old_inp_16k[1][L_INP]; /* buffer of input signal @ 16kHz */ + float old_inp_12k8[1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[1][L_INP]; /* buffer of input signal @ 16kHz */ +#endif + float ener[1]; /* residual energy from Levinson-Durbin */ + float relE[1]; /* frame relative energy */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float A[1][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* A(z) unquantized for subframes */ + float Aw[1][NB_SUBFR16k * ( M + 1 )] = { 0 }; /* weighted A(z) unquantized for subframes */ +#else + float A[1][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ + float Aw[1][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ #endif - float ener[1]; /* residual energy from Levinson-Durbin */ - float relE[1]; /* frame relative energy */ - float A[1][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ - float Aw[1][NB_SUBFR16k * ( M + 1 )]; /* weighted A(z) unquantized for subframes */ float epsP[1][M + 1]; /* LP prediction errors */ float lsp_new[1][M]; /* LSPs at the end of the frame */ float lsp_mid[1][M]; /* ISPs in the middle of the frame */ diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 173ac1be12b2debb2c2bd44b6474f72791158034..01585ded06a168522115e27e450ac8a82cf4dec3 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -522,17 +522,18 @@ typedef struct stereo_td_enc_data_structure Word16 tdm_SM_modi_flag; /* Flag that indicates to modify ratio */ Word16 tdm_SM_reset_flag; /* Flag that indicates to reset the parameters for SM mode */ - Word16 tdm_FD2LRTD_SW_cnt; /* Count the number of frames following a FD to LRTD switching */ - Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ - Word16 prev_fr_LRTD_TD_dec; /* At the beginning of a frame, contains the previous LRTD decision that might have been modified during last frame */ - Word16 tdm_inst_ratio_idx; /* Instantaneous correlation ratio index */ - Word16 tdm_last_inst_ratio_idx; /* previous frame instantaneous correlation ratio index */ - Word16 tdm_vad_hangover_cnt; /* Count the number of frames where hangover_cnt >= 5 in both primary and secondary channel */ - Word16 tdm_ini_frame_cnt; /* Count the number of frame to decide how to evaluate the local VAD of primary and secondary channel */ - Word16 tdm_last_LRTD_frame_cnt; /* Count the number of frame since the last LRTD frame */ - Word16 tdm_last_LRTD_PriCh_cnt; /* Count the number of frame since the primary channel changed */ - Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ - Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; /* Q6 */ + Word16 tdm_FD2LRTD_SW_cnt; /* Count the number of frames following a FD to LRTD switching */ + Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ + Word16 prev_fr_LRTD_TD_dec; /* At the beginning of a frame, contains the previous LRTD decision that might have been modified during last frame */ + Word16 tdm_inst_ratio_idx; /* Instantaneous correlation ratio index */ + Word16 tdm_last_inst_ratio_idx; /* previous frame instantaneous correlation ratio index */ + Word16 tdm_vad_hangover_cnt; /* Count the number of frames where hangover_cnt >= 5 in both primary and secondary channel */ + Word16 tdm_ini_frame_cnt; /* Count the number of frame to decide how to evaluate the local VAD of primary and secondary channel */ + Word16 tdm_last_LRTD_frame_cnt; /* Count the number of frame since the last LRTD frame */ + Word16 tdm_last_LRTD_PriCh_cnt; /* Count the number of frame since the primary channel changed */ + Word16 flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ + // Word32 tdm_Pri_pitch_buf_fx[NB_SUBFR]; + Word16 tdm_Pri_pitch_buf_fx[NB_SUBFR]; // Q6 } STEREO_TD_ENC_DATA, *STEREO_TD_ENC_DATA_HANDLE; diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 8f840c4208d428417f3d61deca46acb72dff8c8f..68f49408a3ab119929d3cea9add2f9e67441cb4a 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -279,8 +279,6 @@ void stereo_tcx_core_enc( /*LPC*/ float lsf[M]; - float A_q[M + 1]; - float gainlpc[2][FDNS_NPTS]; float lsf_tcx_q[M]; Word16 lsp_q_fx[M], lsf_q_fx[M], lsf_fx[M]; Word16 lspmid_q_fx[M]; @@ -288,7 +286,7 @@ void stereo_tcx_core_enc( Word16 gainlpc_fx[2][FDNS_NPTS]; Word16 gainlpc_e[2][FDNS_NPTS]; Word16 lsp_tcx_q_fx[M], lsf_tcx_q_fx[M]; - int16_t tcx_lpc_cdk; + Word16 tcx_lpc_cdk; Word16 A_q_ind[M + 1]; /*for LPC-based AC*/ Word16 lspq_ind[M]; /*for LPC-based AC*/ @@ -321,10 +319,10 @@ void stereo_tcx_core_enc( hTcxEnc = st->hTcxEnc; #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 Q_new, q_comm_Bin; + Word16 Q_new, Q_exc, q_comm_Bin; Word16 lsp_fx[M]; Word16 Aw_fx[NB_SUBFR16k * ( M + 1 )]; - float Aw_flt[NB_SUBFR16k * ( M + 1 )], max = 0; + float Aw_flt[NB_SUBFR16k * ( M + 1 )] /*, max = 0*/; st->hTcxEnc->noiseTiltFactor = float_to_fix16( st->hTcxEnc->noiseTiltFactor_flt, Q15 ); mvr2r( Aw, Aw_flt, st->nb_subfr * ( M + 1 ) ); @@ -335,6 +333,15 @@ void stereo_tcx_core_enc( { st->clip_var_fx[j] = (Word16) ( st->clip_var[j] * 2.56f ); } + hTcxEnc->tcx_target_bits_fac = float_to_fix16( hTcxEnc->tcx_target_bits_fac_flt, Q14 ); + st->hTcxCfg->sq_rounding = float_to_fix16( st->hTcxCfg->sq_rounding_flt, Q15 ); + st->hTcxEnc->measuredBwRatio = float_to_fix16( st->hTcxEnc->measuredBwRatio_flt, Q14 ); + st->hTcxCfg->na_scale = float_to_fix16( st->hTcxCfg->na_scale_flt, Q15 ); + if ( st->hTdCngEnc != NULL ) + { + st->hTdCngEnc->CNG_att_fx = float_to_fix16( st->hTdCngEnc->CNG_att, Q12 ); + } + floatToFixed_arr( hTcxEnc->Txnq_flt, hTcxEnc->Txnq, -1, L_FRAME32k / 2 + 64 ); #endif @@ -516,6 +523,60 @@ void stereo_tcx_core_enc( st->hTcxEnc->spectrum_e[0] = 31 - ( Q_factor_arrL( st->hTcxEnc->spectrum[0], N_MAX ) - 4 ); floatToFixed_arrL( st->hTcxEnc->spectrum[0], st->hTcxEnc->spectrum_fx[0], 31 - st->hTcxEnc->spectrum_e[0], N_MAX ); + st->hTcxEnc->spectrum_e[1] = st->hTcxEnc->spectrum_e[0]; + + hTcxEnc->tcxltp_gain = float_to_fix16( hTcxEnc->tcxltp_gain_flt, Q15 ); + + Word16 L_frame = st->L_frame; + Word16 L_frameTCX = hTcxEnc->L_frameTCX; + Word16 L_spec = st->hTcxCfg->tcx_coded_lines; + Word16 tcx_offset = st->hTcxCfg->tcx_offset; + + IF( EQ_16( st->core, TCX_10_CORE ) ) + { + L_frame = shr( L_frame, 1 ); + L_frameTCX = shr( L_frameTCX, 1 ); + L_spec = shr( L_spec, 1 ); + } + ELSE IF( st->last_core == ACELP_CORE ) + { + L_frame = add( L_frame, tcx_offset ); + L_frameTCX = add( L_frameTCX, st->hTcxCfg->tcx_offsetFB ); + L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) ); + + IF( st->hTcxCfg->lfacNext < 0 ) + { + L_frame = sub( L_frame, st->hTcxCfg->lfacNext ); + L_frameTCX = sub( L_frameTCX, st->hTcxCfg->lfacNextFB ); + } + } + + Q_new = 0; + Q_exc = Q_new + ( Q_new - 1 ) + 1; + + st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); + floatToFixed_arr( st->lsp_old16k, st->lsp_old16k_fx, Q15, M ); + IF( st->hTdCngEnc != NULL ) + { + floatToFixed_arrL( st->hTdCngEnc->ho_ener_circ, st->hTdCngEnc->ho_ener_circ_fx, Q6, HO_HIST_SIZE ); + floatToFixed_arr( st->hTdCngEnc->ho_lsp_circ, st->hTdCngEnc->ho_lsp_circ_fx, Q15, HO_HIST_SIZE * M ); + floatToFixed_arrL( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); + floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); + st->hTdCngEnc->lp_ener_fx = float_to_fix( st->hTdCngEnc->lp_ener, Q6 ); + } + IF( st->hDtxEnc != NULL ) + { + floatToFixed_arr( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG_fx, Q15, M ); + } + + floatToFixed_arr( st->synth_flt, st->synth, Q_new, st->L_frame ); + floatToFixed_arr( st->hLPDmem->syn_flt, st->hLPDmem->syn, Q_new, M + 1 ); + // floatToFixed_arr( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, Q_new, L_EXC_MEM ); + st->wspeech_enc[st->L_frame - 1] = (Word16) floatToFixed( st->wspeech_enc_flt[st->L_frame - 1], Q_new ); + Word16 exp_exc; + f2me_buf_16( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, &exp_exc, L_EXC_MEM ); + Q_exc = 15 - exp_exc; + st->hLPDmem->e_old_exc = exp_exc; #endif // IVAS_FLOAT_FIXED_CONVERSIONS IF( !st->enableTcxLpc ) @@ -637,22 +698,6 @@ void stereo_tcx_core_enc( st->last_core = st->core; move16(); } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( A_q_fx, A_q, Q14 - norm_s( A_q_fx[0] ), M + 1 ); - fixedToFloat_arrL( st->hTcxEnc->spectrum_fx[0], st->hTcxEnc->spectrum[0], 31 - st->hTcxEnc->spectrum_e[0], N_MAX ); - st->hTcxEnc->noiseTiltFactor_flt = fix16_to_float( st->hTcxEnc->noiseTiltFactor, Q15 ); - if ( st->enablePlcWaveadjust ) - { - st->hTcxCfg->SFM2_flt = fix_to_float( st->hTcxCfg->SFM2, Q31 ); - } - for ( n = 0; n < n_subframes; n++ ) - { - for ( int k = 0; k < FDNS_NPTS; k++ ) - { - gainlpc[n][k] = fix16_to_float( gainlpc_fx[n][k], 15 - gainlpc_e[n][k] ); - } - } -#endif st->last_core = last_core_orig; move16(); @@ -696,9 +741,37 @@ void stereo_tcx_core_enc( } tmp2 = imult1616( n, NPRM_DIV ); - QuantizeSpectrum_ivas_fx( st, A_q, A_q_ind, gainlpc[n], st->synth_flt + tmp1, target_bits[n], tnsSize[n], param_core + tmp2, n, &hm_cfg[n], vad_hover_flag ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hTcxEnc->Q_old_out = Q_factor_arr( hTcxEnc->old_out, L_frame ) - 1; + floatToFixed_arr( hTcxEnc->old_out, hTcxEnc->old_out_fx, hTcxEnc->Q_old_out, L_frame ); +#endif + + QuantizeSpectrum_ivas_fx( st, A_q_fx, A_q_ind, gainlpc_fx[n], gainlpc_e[n], st->synth + tmp1, target_bits[n], tnsSize[n], param_core + tmp2, n, &hm_cfg[n], vad_hover_flag ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( hTcxEnc->old_out_fx, hTcxEnc->old_out, hTcxEnc->Q_old_out, L_frame ); +#endif } + + /* Update tcx overlap mode */ + st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; + move16(); + +#if 0 + Word16 s = sub( getScaleFactor16( st->synth, st->L_frame ), 2 ); + Scale_sig( st->synth, st->L_frame, s ); + Q_exc = sub( 15, st->hLPDmem->e_old_exc ); + Scale_sig( st->hLPDmem->old_exc, L_EXC_MEM, sub( s, Q_exc ) ); + Scale_sig( st->hLPDmem->syn, M + 1, s ); + st->wspeech_enc[st->L_frame - 1] = shl( st->wspeech_enc[st->L_frame - 1], s ); + Q_new = add( Q_new, s ); + move16(); + move16(); +#else #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + float max = 0.0f; + fixedToFloat_arr( st->synth + tmp1, st->synth_flt + tmp1, 0, L_frame ); for ( int k = 0; k < st->L_frame; k++ ) { if ( max < (float) fabs( st->synth_flt[k] ) ) @@ -719,13 +792,27 @@ void stereo_tcx_core_enc( floatToFixed_arr( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, Q_new, L_EXC_MEM ); st->wspeech_enc[st->L_frame - 1] = (Word16) floatToFixed( st->wspeech_enc_flt[st->L_frame - 1], Q_new ); #endif - - /* Update tcx overlap mode */ - st->hTcxCfg->tcx_last_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; - move16(); +#endif coder_tcx_post_ivas_fx( st, st->hLPDmem, st->hTcxCfg, st->synth, A_q_fx, Aw_fx, st->wspeech_enc, Q_new ); +#if 0 + Q_exc = shl( Q_new, 1 ); // Q_new + ( Q_new - 1 ) + 1; + move16(); +#else + fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, Q_new + ( Q_new - 1 ) + 1, L_EXC_MEM ); + f2me_buf_16( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, &exp_exc, L_EXC_MEM ); + Q_exc = 15 - exp_exc; + IF( st->hTdCngEnc != NULL ) + { + floatToFixed_arrL( st->hTdCngEnc->ho_ener_circ, st->hTdCngEnc->ho_ener_circ_fx, Q6, HO_HIST_SIZE ); + floatToFixed_arr( st->hTdCngEnc->ho_lsp_circ, st->hTdCngEnc->ho_lsp_circ_fx, Q15, HO_HIST_SIZE * M ); + floatToFixed_arrL( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); + floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); + st->hTdCngEnc->lp_ener_fx = float_to_fix( st->hTdCngEnc->lp_ener, Q6 ); + } +#endif + IF( st->enableTcxLpc ) { E_LPC_lsp_unweight( lsp_tcx_q_fx, lsp_q_fx, lsf_q_fx, st->inv_gamma, M ); /* Update lsf_q for encoderSideLossSimulation() */ @@ -758,29 +845,89 @@ void stereo_tcx_core_enc( Copy( lsp_q_fx, st->lsp_old_fx, M ); } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hTcxEnc->measuredBwRatio_flt = fix16_to_float( hTcxEnc->measuredBwRatio, Q14 ); + test(); + test(); + IF( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) + { + /* update CNG parameters in active frames */ + test(); + test(); + IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && NE_16( st->core, ACELP_CORE ) ) + { + Word16 buf_fx[L_LP], res_fx[L_FRAME], A_fx[M + 1], tmp_fx, lsptmp_fx[M]; + Word32 A_fx32[M + 1], r_fx[M + 1]; + Word16 Q_r; - fixedToFloat_arr( st->synth, st->synth_flt, Q_new, st->L_frame ); - fixedToFloat_arr( st->hLPDmem->mem_syn_r, st->hLPDmem->mem_syn_r_flt, Q_new + ( Q_new - 1 ), L_SYN_MEM ); - fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, Q_new + ( Q_new - 1 ), M ); - fixedToFloat_arr( st->hLPDmem->mem_syn2, st->hLPDmem->mem_syn2_flt, Q_new + ( Q_new - 1 ), M ); - fixedToFloat_arr( st->hLPDmem->syn, st->hLPDmem->syn_flt, Q_new, M + 1 ); - fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, Q_new + ( Q_new - 1 ) + 1, L_EXC_MEM ); - st->hLPDmem->mem_w0_flt = fixedToFloat_16( st->hLPDmem->mem_w0, Q_new ); + assert( st->L_frame == L_FRAME ); - st->streaklimit = fix16_to_float( st->streaklimit_fx, Q15 ); - fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); - for ( int j = 0; j < 6; j++ ) + Copy( st->synth + L_FRAME - L_LP, buf_fx, L_LP ); + tmp_fx = st->synth[L_FRAME - L_LP - 1]; + move16(); + preemph_copy_fx( buf_fx, buf_fx, st->preemph_fac, L_LP, &tmp_fx ); + autocorr_fx_32( buf_fx, M, r_fx, &Q_r, L_LP, LP_assym_window_fx, 0, 0 ); + lag_wind_32( r_fx, M, INT_FS_12k8, LAGW_WEAK ); + lev_dur_fx( A_fx32, r_fx, M, NULL, Q12, Q_r ); + FOR( Word16 j = 0; j < M; j++ ) + { + A_fx[j] = extract_l( A_fx32[j] ); + } + E_LPC_a_lsp_conversion( A_fx, lsptmp_fx, lsp_new_fx, M ); + Residu3_fx( A_fx, buf_fx + L_LP - L_FRAME, res_fx, L_FRAME, 0 ); + + cng_params_upd_ivas_fx( lsptmp_fx, res_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, + st->hTdCngEnc->ho_lsp_circ_fx, Q_r, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hFdCngEnc->hFdCngCom->CngBandwidth ); + Q_exc = Q_r; + move16(); + } + ELSE + { + cng_params_upd_ivas_fx( lsp_new_fx, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, + st->hTdCngEnc->ho_lsp_circ_fx, Q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, + st->hFdCngEnc->hFdCngCom->CngBandwidth ); + } + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + /* store LSPs@16k, potentially to be used in CNG@16k */ + Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); + } + + /* Set 16k LSP flag for CNG buffer */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 0; + move16(); + } + ELSE + { + st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 1; + move16(); + } + + /* efficient DTX hangover control */ + IF( GT_16( st->hTdCngEnc->burst_ho_cnt, 1 ) ) + { + dtx_hangover_control_fx( st, lsp_new_fx ); + } + } + + /*--------------------------------------------------------------------------------* + * Encode TCX20/10 parameters + *--------------------------------------------------------------------------------*/ + writeTCXparam_fx( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, add( nbits_lpc[0], nbits_lpc[1] ), NULL, NULL, NULL, -1 ); + + total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); + + IF( NE_16( param_core[1 + NOISE_FILL_RANGES], 0 ) ) { - st->clip_var[j] = (float) st->clip_var_fx[j] / 2.56f; + Word32 tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxEnc->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxEnc->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /* 15Q16 */ + set32_fx( pitch_buf_fx, tcxltp_pitch_tmp, NB_SUBFR16k ); } - for ( int j = 0; j < M; j++ ) + ELSE { - st->lsf_old[j] = (float) st->lsf_old_fx[j] / 2.56f; - st->mem_MA[j] = (float) st->mem_MA_fx[j] / 2.56f; + set32_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q16, NB_SUBFR16k ); } -#endif #else TCX_ENC_HANDLE hTcxEnc; int16_t i, n; @@ -1095,115 +1242,7 @@ void stereo_tcx_core_enc( mvr2r( lsf_q, st->lsf_old, M ); mvr2r( lsp_q, st->lsp_old, M ); } -#endif - -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - // Float to fixed - Word16 Q_exc, exp_exc; - f2me_buf_16( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, &exp_exc, L_EXC_MEM ); - Q_exc = 15 - exp_exc; - floatToFixed_arr( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, Q_exc, L_EXC_MEM ); - floatToFixed_arr( st->lsp_old16k, st->lsp_old16k_fx, Q15, M ); - IF( st->hTdCngEnc != NULL ) - { - floatToFixed_arrL( st->hTdCngEnc->ho_ener_circ, st->hTdCngEnc->ho_ener_circ_fx, Q6, HO_HIST_SIZE ); - floatToFixed_arr( st->hTdCngEnc->ho_lsp_circ, st->hTdCngEnc->ho_lsp_circ_fx, Q15, HO_HIST_SIZE * M ); - floatToFixed_arrL( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, HO_HIST_SIZE * NUM_ENV_CNG ); - floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); - st->hTdCngEnc->lp_ener_fx = float_to_fix( st->hTdCngEnc->lp_ener, Q6 ); - } - IF( st->hDtxEnc != NULL ) - { - floatToFixed_arr( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG_fx, Q15, M ); - } - st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); -#endif - -#ifdef IVAS_FLOAT_FIXED - test(); - test(); - IF( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) - { - /* update CNG parameters in active frames */ - test(); - test(); - IF( EQ_16( st->bwidth, NB ) && st->enableTcxLpc && NE_16( st->core, ACELP_CORE ) ) - { - Word16 buf_fx[L_LP], res_fx[L_FRAME], A_fx[M + 1], tmp_fx, lsptmp_fx[M]; - Word32 A_fx32[M + 1], r_fx[M + 1]; - Word16 Q_r; - - assert( st->L_frame == L_FRAME ); - - Copy( st->synth + L_FRAME - L_LP, buf_fx, L_LP ); - tmp_fx = st->synth[L_FRAME - L_LP - 1]; - move16(); - preemph_copy_fx( buf_fx, buf_fx, st->preemph_fac, L_LP, &tmp_fx ); - autocorr_fx_32( buf_fx, M, r_fx, &Q_r, L_LP, LP_assym_window_fx, 0, 0 ); - lag_wind_32( r_fx, M, INT_FS_12k8, LAGW_WEAK ); - lev_dur_fx( A_fx32, r_fx, M, NULL, Q12, Q_r ); - FOR( Word16 j = 0; j < M; j++ ) - { - A_fx[j] = extract_l( A_fx32[j] ); - } - E_LPC_a_lsp_conversion( A_fx, lsptmp_fx, lsp_new_fx, M ); - Residu3_fx( A_fx, buf_fx + L_LP - L_FRAME, res_fx, L_FRAME, 0 ); - - cng_params_upd_ivas_fx( lsptmp_fx, res_fx, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, - st->hTdCngEnc->ho_lsp_circ_fx, Q_r, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, - st->hFdCngEnc->hFdCngCom->CngBandwidth ); - Q_exc = Q_r; - move16(); - } - ELSE - { - cng_params_upd_ivas_fx( lsp_new_fx, st->hLPDmem->old_exc + L_EXC_MEM - st->L_frame, st->L_frame, &st->hTdCngEnc->ho_circ_ptr, st->hTdCngEnc->ho_ener_circ_fx, &st->hTdCngEnc->ho_circ_size, - st->hTdCngEnc->ho_lsp_circ_fx, Q_exc, ENC, st->hTdCngEnc->ho_env_circ_fx, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hDtxEnc->last_active_brate, st->element_mode, - st->hFdCngEnc->hFdCngCom->CngBandwidth ); - } - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - /* store LSPs@16k, potentially to be used in CNG@16k */ - Copy( st->lsp_old16k_fx, &( st->hTdCngEnc->ho_lsp_circ2_fx[( st->hTdCngEnc->ho_circ_ptr ) * M] ), M ); - } - - /* Set 16k LSP flag for CNG buffer */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 0; - move16(); - } - ELSE - { - st->hTdCngEnc->ho_16k_lsp[st->hTdCngEnc->ho_circ_ptr] = 1; - move16(); - } - - /* efficient DTX hangover control */ - IF( GT_16( st->hTdCngEnc->burst_ho_cnt, 1 ) ) - { - dtx_hangover_control_fx( st, lsp_new_fx ); - } - } - - /*--------------------------------------------------------------------------------* - * Encode TCX20/10 parameters - *--------------------------------------------------------------------------------*/ - writeTCXparam_fx( st, hBstr, hm_cfg, param_core, nbits_header, nbits_start, add( nbits_lpc[0], nbits_lpc[1] ), NULL, NULL, NULL, -1 ); - - total_nbbits = sub( hBstr->nb_bits_tot, nbits_start ); - IF( NE_16( param_core[1 + NOISE_FILL_RANGES], 0 ) ) - { - Word32 tcxltp_pitch_tmp = L_add( L_deposit_h( hTcxEnc->tcxltp_pitch_int ), L_shl( L_deposit_l( div_s( hTcxEnc->tcxltp_pitch_fr, st->pit_res_max ) ), 1 ) ); /* 15Q16 */ - set32_fx( pitch_buf_fx, tcxltp_pitch_tmp, NB_SUBFR16k ); - } - ELSE - { - set32_fx( pitch_buf_fx, L_SUBFR * ONE_IN_Q16, NB_SUBFR16k ); - } -#else if ( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) { /* update CNG parameters in active frames */ @@ -1277,6 +1316,39 @@ void stereo_tcx_core_enc( fixedToFloat_arr( st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_exc2_buf_flt, Q_exc, HO_HIST_SIZE * L_FFT ); fixedToFloat_arr( st->hTdCngEnc->ho_lsp_circ2_fx, st->hTdCngEnc->ho_lsp_circ2, M, Q15 ); } + + hTcxEnc->measuredBwRatio_flt = fix16_to_float( hTcxEnc->measuredBwRatio, Q14 ); + + fixedToFloat_arr( st->synth, st->synth_flt, Q_new, st->L_frame ); + fixedToFloat_arr( st->hLPDmem->mem_syn_r, st->hLPDmem->mem_syn_r_flt, Q_new + ( Q_new - 1 ), L_SYN_MEM ); + fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, Q_new + ( Q_new - 1 ), M ); + fixedToFloat_arr( st->hLPDmem->mem_syn2, st->hLPDmem->mem_syn2_flt, Q_new + ( Q_new - 1 ), M ); + fixedToFloat_arr( st->hLPDmem->syn, st->hLPDmem->syn_flt, Q_new, M + 1 ); + fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, Q_exc, L_EXC_MEM ); + st->hLPDmem->mem_w0_flt = fixedToFloat_16( st->hLPDmem->mem_w0, Q_new ); + + st->streaklimit = fix16_to_float( st->streaklimit_fx, Q15 ); + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); + for ( int j = 0; j < 6; j++ ) + { + st->clip_var[j] = (float) st->clip_var_fx[j] / 2.56f; + } + for ( int j = 0; j < M; j++ ) + { + st->lsf_old[j] = (float) st->lsf_old_fx[j] / 2.56f; + st->mem_MA[j] = (float) st->mem_MA_fx[j] / 2.56f; + } + if ( st->enablePlcWaveadjust ) + { + st->hTcxCfg->SFM2_flt = fix_to_float( st->hTcxCfg->SFM2, Q31 ); + } + for ( n = 0; n < n_subframes; n++ ) + { + fixedToFloat_arrL( st->hTcxEnc->spectrum_fx[n], st->hTcxEnc->spectrum[n], 31 - st->hTcxEnc->spectrum_e[n], s_max( L_frame, L_spec ) ); + } + fixedToFloat_arr( hTcxEnc->Txnq, hTcxEnc->Txnq_flt, -1, L_FRAME32k / 2 + 64 ); + st->hTcxEnc->noiseTiltFactor_flt = fix16_to_float( st->hTcxEnc->noiseTiltFactor, Q15 ); + hTcxEnc->tcx_target_bits_fac_flt = me2f_16( hTcxEnc->tcx_target_bits_fac, Q15 - Q14 ); #endif pop_wmops(); diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index 451506067602bca1ea3c5b04b50fc9e977c6882c..42cea4ce66215b04b1c5915984b9683151e8b727 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -41,6 +41,7 @@ #include "prot_fx.h" #include "prot_fx_enc.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" @@ -288,6 +289,7 @@ void tdm_low_rate_enc( * Encode GC, 2 subframes mode *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void encod_gen_2sbfr( Encoder_State *st, /* i/o: state structure */ const float speech[], /* i : input speech */ @@ -472,3 +474,216 @@ void encod_gen_2sbfr( return; } +#else +void encod_gen_2sbfr( + Encoder_State *st, /* i/o: state structure */ + const Word16 speech[], /* i : input speech Q_new-1 */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes e(norm_s(Aw[0]+1)*/ + const Word16 Aq[], /* i : LP coefficients e(norm_s(Aw[0]+1)*/ + const Word16 *res, /* i : residual signal Q_new */ + Word16 *syn, /* i/o: core synthesis Q_new */ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new-1 */ + Word16 *exc2, /* i/o: current enhanced excitation Q_new-1 */ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6 */ + Word16 *voice_factors, /* o : voicing factors Q15 */ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel Q4 */ + Word16 *Q_new ) +{ + Word16 xn[2 * L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[2 * L_SUBFR]; /* Target vector for codebook search */ + Word16 cn[2 * L_SUBFR]; /* Target vector in residual domain */ + Word16 h1[2 * L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[2 * L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */ + Word16 gain_pit; /* Pitch gain */ + Word16 voice_fac; /* Voicing factor */ + Word32 gain_code; /* Gain of code */ + Word16 gain_inov; /* inovation gain */ + Word16 L_frame, coder_type; /* L_frame; coder type */ + Word16 i, i_subfr; /* tmp variables */ + Word16 T0, T0_frac; /* close loop integer pitch and fractional part */ + Word16 T0_min, T0_max; /* pitch variables */ + Word16 *pt_pitch; /* pointer to floating pitch buffer */ + Word16 g_corr[6]; /* ACELP correl, values + gain pitch */ + // Word16 gains_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */ + Word32 gc_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */ + Word16 gp_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */ + Word16 clip_gain; /* LSF clip gain */ + const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coeff. vector*/ + Word32 norm_gain_code; + Word16 pitch_limit_flag; + Word16 error; + Word16 shift; + + LPD_state_HANDLE hLPDmem = st->hLPDmem; + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + gain_pit = 0; + move16(); + gain_code = 0; + move16(); + error = 0; + move16(); + + T0_max = PIT_MAX; + move16(); + T0_min = PIT_MIN; + move16(); + + L_frame = L_FRAME; + move16(); + coder_type = GENERIC; + move16(); + + p_Aw = Aw; + p_Aq = Aq; + pt_pitch = pitch_buf; + + shift = 0; + move16(); + + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + + FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += 2 * L_SUBFR ) + { + /*----------------------------------------------------------------* + * Find the the excitation search target "xn" and innovation + * target in residual domain "cn" + * Compute impulse response, h1[], of weighted synthesis filter + *----------------------------------------------------------------*/ + + Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new + + // Scaling mem_syn buffer to Q_new - 1 from e_mem_syn + Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent + hLPDmem->e_mem_syn = sub( Q16, *Q_new ); + + find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); + + /*------------------------------------------------------------------------* + * Close-loop pitch search on the 1st and 3rd subfr only and quantization + * Adaptive exc. construction + *------------------------------------------------------------------------*/ + + *pt_pitch = pit_encode_ivas_fx( st->hBstr, st->acelp_cfg.pitch_bits, st->core_brate, 0, L_frame, coder_type, &pitch_limit_flag, i_subfr, exc, 2 * L_SUBFR, st->pitch, &T0_min, &T0_max, &T0, &T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + + tbe_celp_exc_ivas( st->element_mode, st->idchan, L_frame, 2 * L_SUBFR, i_subfr, T0, T0_frac, &error, bwe_exc, st->tdm_LRTD_flag ); + + /*-----------------------------------------------------------------* + * Find adaptive exitation + *-----------------------------------------------------------------*/ + + pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, 2 * L_SUBFR + 1, inter4_2_fx_Q15, L_INTERPOL2, PIT_UP_SAMP ); + + /*-----------------------------------------------------------------* + * Gain clipping test to avoid unstable synthesis on frame erasure + *-----------------------------------------------------------------*/ + + clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, *Q_new ); // Q0 + + /*-----------------------------------------------------------------* + * LP filtering of the adaptive excitation, codebook target computation + *-----------------------------------------------------------------*/ + + lp_filt_exc_enc_fx( MODE1, coder_type, i_subfr, exc, h1, xn, y1, xn2, 2 * L_SUBFR, L_frame, g_corr, clip_gain, &gain_pit, &st->acelp_cfg.ltf_mode ); + + /* update long-term pitch gain for speech/music classifier */ + st->hSpMusClas->lowrate_pitchGain = add( mult( 29491, st->hSpMusClas->lowrate_pitchGain ), mult( 3277, gain_pit ) ); // Q14 + move16(); + + /*-----------------------------------------------------------------* + * Innovation encoding + *-----------------------------------------------------------------*/ + + inov_encode_ivas_fx( st, st->core_brate, 0, L_frame, st->last_L_frame, coder_type, st->bwidth, st->sharpFlag, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR, 0, *Q_new ); + + /*-----------------------------------------------------------------* + * Gain encoding + *-----------------------------------------------------------------*/ + + gain_enc_lbr_ivas_fx( st->hBstr, st->acelp_cfg.gains_mode, coder_type, i_subfr, xn, y1, add( sub( *Q_new, 1 ), shift ), y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gc_mem, gp_mem, clip_gain, 2 * L_SUBFR ); + + IF( st->Opt_SC_VBR ) + { + IF( EQ_16( st->hSC_VBR->last_ppp_mode, 1 ) ) + { + /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */ + st->clip_var_fx[1] = gain_pit; + move16(); + } + } + + /*-----------------------------------------------------------------* + * update LP-filtered gains for the case of frame erasures + *-----------------------------------------------------------------*/ + + gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); + + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, *Q_new, 2 * L_SUBFR, 0 ); + move16(); + + /*-----------------------------------------------------------------* + * Update memory of the weighting filter + *-----------------------------------------------------------------*/ + + hLPDmem->mem_w0 = sub( sub( xn[2 * L_SUBFR - 1], mult_r( gain_pit, y1[2 * L_SUBFR - 1] ) ), mult_r( extract_h( gain_code ), y2[2 * L_SUBFR - 1] ) ); + move16(); + + /*-----------------------------------------------------------------* + * Construct adaptive part of the excitation + * Save the non-enhanced excitation for FEC_exc + *-----------------------------------------------------------------*/ + + FOR( i = 0; i < 2 * L_SUBFR; i++ ) + { + exc2[i + i_subfr] = mult( gain_pit, exc[i + i_subfr] ); + move16(); + exc[i + i_subfr] = add( exc2[i + i_subfr], mult( extract_h( gain_code ), code[i] ) ); + move16(); + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, *Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); + + voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; + move16(); + + /*-----------------------------------------------------------------* + * Synthesize speech to update mem_syn_flt[]. + * Update A(z) filters + *-----------------------------------------------------------------*/ + + E_UTIL_synthesis( 0, p_Aq, &exc[i_subfr], &syn[i_subfr], 2 * L_SUBFR, hLPDmem->mem_syn, 1, M ); + + p_Aw += 2 * ( M + 1 ); + p_Aq += 2 * ( M + 1 ); + + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + } + + /* SC-VBR */ + IF( st->Opt_SC_VBR ) + { + st->hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; + st->hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + move16(); + move16(); + } + + return; +} +#endif diff --git a/lib_enc/mdct_classifier.c b/lib_enc/mdct_classifier.c index 415792510c9007ab93e79069f9acfec6bf3d8062..4e346a9619b97129b9e9b4c298d834e7b6202000 100644 --- a/lib_enc/mdct_classifier.c +++ b/lib_enc/mdct_classifier.c @@ -40,7 +40,7 @@ #include "prot.h" #include "wmc_auto.h" #include - +#include "ivas_prot_fx.h" /*--------------------------------------------------------------------------* * Local constants diff --git a/lib_enc/mdct_classifier_fx.c b/lib_enc/mdct_classifier_fx.c index dc938766bd6c77053296139df471f7b27195394b..b7725a527036f2018066bd075f8c464422f4e325 100644 --- a/lib_enc/mdct_classifier_fx.c +++ b/lib_enc/mdct_classifier_fx.c @@ -7,8 +7,11 @@ #include "cnst.h" //#include "prot_fx.h" #include "rom_com.h" -#include "prot_fx.h" /* Function prototypes */ -#include "prot_fx_enc.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ +#include "prot_fx.h" /* Function prototypes */ +#include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ /*--------------------------------------------------------------------------* * Local constants @@ -588,3 +591,555 @@ Word16 mdct_classifier_fx( /* o: MDCT A/B decision return clas_final; /* Q0 */ } +#ifdef IVAS_FLOAT_FIXED +Word16 mdct_classifier_ivas_fx( + Encoder_State *st, /* i/o: Encoder state variable */ + const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */ + const Word32 enerBuffer[], /* i : energy buffer */ + Word16 enerBuffer_exp, + const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */ +) +{ + Word16 c; + Word32 X[129]; + Word16 k; + Word32 nf; + Word32 pe; + Word16 np; + Word32 max_cand; + Word16 max_i; + Word32 p_energy_man, n_energy_man, man; + Word16 p_energy_exp, n_energy_exp, expo; + Word16 d_acc; + Word16 pos_last; + Word16 clas_sec; + Word16 clas_final; + Word16 i; + Word32 gain1, gain2, gain3, gain11, gain4; + Word32 peak_l, peak_h, avrg_l, avrg_h, peak_H1, avrg_H1, peak_H2, avrg_H2; + Word16 condition1, condition2; + Word16 condition3, condition4; + Word16 gain2_start, gain3_start, gain4_start, H1_start, H2_start, H_length; + Word16 factor; + Word32 acc; + UWord16 lsb16; + UWord32 lsb32; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 exp, exp1, exp2, exp3; + Word32 gain1_tmp = 0, gain2_tmp = 0; + Word32 L_tmp, L_tmp1; + Flag Overflow = 0; + move16(); + move16(); + move16(); + + test(); + IF( EQ_32( st->input_Fs, 32000 ) || EQ_32( st->input_Fs, 48000 ) ) + { + gain2_start = GAIN2_START_SWB; + gain3_start = GAIN3_START_SWB; + gain4_start = GAIN4_START_SWB; + H1_start = H1_START_SWB; + H2_start = H2_START_SWB; + H_length = H_LENGTH_SWB; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE IF( EQ_32( st->input_Fs, 16000 ) ) + { + gain2_start = GAIN2_START_WB; + gain3_start = GAIN3_START_WB; + gain4_start = GAIN4_START_WB; + H1_start = H1_START_WB; + H2_start = H2_START_WB; + H_length = H_LENGTH_WB; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + ELSE + { + assert( !"Unknown sampling frequency in MDCT_classifier" ); + H1_start = -1; /* to avoid compilation warning */ + H2_start = -1; /* to avoid compilation warning */ + H_length = -1; /* to avoid compilation warning */ + gain2_start = -1; /* to avoid compilation warning */ + gain3_start = -1; /* to avoid compilation warning */ + gain4_start = -1; /* to avoid compilation warning */ + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + } + + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + dft_mag_square_fx( fft_buff, X, 256 ); + } + ELSE + { + Word16 norm_val; + + norm_val = i_mult( L_FFT, shr( L_FFT, 2 ) ); + FOR( k = 0; k < 128; k++ ) + { + X[k + 1] = Mpy_32_16_1( st->Bin_E_old_fx[k], norm_val ); + } + X[0] = X[1]; + move32(); + } + + nf = L_add( X[0], 0 ); + pe = L_add( X[0], 0 ); + np = 0; + move16(); + + max_cand = L_negate( 1 ); + max_i = 0; + move16(); + + p_energy_man = L_deposit_l( 0 ); + n_energy_man = L_deposit_l( 0 ); + p_energy_exp = n_energy_exp = 32; + move16(); + move16(); + d_acc = 0; + move16(); + pos_last = -1; + move16(); + + FOR( k = 0; k < 128; k++ ) + { + /* NB: a*f + b*(1 - f) needs two multiplies + * = (a - b)*f + b saves one multiply */ + IF( GT_32( X[k + 1], nf ) ) + { + factor = 31385; + move16(); /* 0.9578 in Q15 */ + } + ELSE + { + factor = 21207; + move16(); /* 0.6472 in Q15 */ + } + + acc = L_sub( nf, X[k + 1] ); + Mpy_32_16_ss( acc, factor, &acc, &lsb16 ); + nf = L_add( acc, X[k + 1] ); + + IF( GT_32( X[k + 1], pe ) ) + { + factor = 13840; + move16(); /* 0.42237 in Q15 */ + } + ELSE + { + factor = 26308; + move16(); /* 0.80285 in Q15 */ + } + + acc = L_sub( pe, X[k + 1] ); + Mpy_32_16_ss( acc, factor, &acc, &lsb16 ); + pe = L_add( acc, X[k + 1] ); + Mpy_32_16_ss( pe, 20972, &acc, &lsb16 ); /* 0.64 in Q15 */ + + IF( GT_32( X[k + 1], acc ) ) + { + IF( GT_32( X[k + 1], max_cand ) ) + { + max_cand = X[k + 1]; + move32(); + max_i = add( 2, k ); + } + } + ELSE + { + IF( max_i > 0 ) + { + IF( np > 0 ) + { + d_acc = sub( add( d_acc, max_i ), pos_last ); + } + np = add( np, 1 ); + pos_last = max_i; + move16(); + } + + max_cand = L_negate( 1 ); + max_i = 0; + move16(); + } + + IF( pe != 0 ) + { + expo = norm_l( pe ); + man = L_shl( pe, expo ); + Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */ + expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ + floating_point_add( &p_energy_man, &p_energy_exp, man, expo ); + } + IF( nf != 0 ) + { + expo = norm_l( nf ); + man = L_shl( nf, expo ); + Mpy_32_32_ss( man, man, &man, &lsb32 ); /* nf square */ + expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */ + floating_point_add( &n_energy_man, &n_energy_exp, man, expo ); + } + } + + gain1 = L_deposit_l( 0 ); + gain2 = L_deposit_l( 0 ); + gain3 = L_deposit_l( 0 ); + + FOR( i = 0; i < gain2_start; i++ ) + { + IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) + { + gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); + gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); + gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); + } + ELSE + { + gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); + gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 ) ); + gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 ) ); + } + } + + + IF( EQ_16( gain2_start, GAIN2_START_SWB ) ) + { + acc = L_shr( enerBuffer[0], 3 ); + acc = L_sub( gain1, acc ); + acc = Mult_32_16( acc, 4681 ); + gain11 = L_shl( acc, 3 ); + gain4 = L_deposit_l( 0 ); + } + ELSE + { + acc = Mult_32_16( enerBuffer[0], 5461 ); + acc = L_sub( gain1, acc ); + acc = Mult_32_16( acc, 6553 ); + gain11 = (Word32) W_mult_32_16( acc, 6 ); + gain4 = L_deposit_l( 0 ); + } + + gain4 = L_deposit_l( 0 ); + FOR( i = 0; i < gain4_start; i++ ) + { + IF( EQ_16( gain4_start, GAIN4_START_SWB ) ) + { + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 ) ); + } + ELSE + { + gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 ) ); + } + } + + peak_H1 = enerBuffer[H1_start]; + move32(); + + avrg_H1 = enerBuffer[H1_start]; + move32(); + + FOR( i = 1; i < H_length; i++ ) + { + IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) ) + { + peak_H1 = enerBuffer[H1_start + i]; + move32(); + } + avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); + } + + peak_H2 = enerBuffer[H2_start]; + move32(); + + avrg_H2 = enerBuffer[H2_start]; + move32(); + + FOR( i = 1; i < H_length; i++ ) + { + IF( GT_32( enerBuffer[H2_start + i], peak_H2 ) ) + { + peak_H2 = enerBuffer[H2_start + i]; + move32(); + } + avrg_H2 = L_add( avrg_H2, enerBuffer[H2_start + i] ); + } + + peak_l = L_deposit_l( 0 ); + avrg_l = L_deposit_l( 0 ); + peak_h = L_deposit_l( 0 ); + avrg_h = L_deposit_l( 0 ); + + FOR( i = 0; i < 32; i++ ) + { + avrg_l = L_add( avrg_l, L_shr( X[20 + i], 5 ) ); + avrg_h = L_add( avrg_h, L_shr( X[96 + i], 5 ) ); + IF( GT_32( X[20 + i], peak_l ) ) + { + peak_l = L_add( X[20 + i], 0 ); + } + IF( GT_32( X[96 + i], peak_h ) ) + { + peak_h = L_add( X[96 + i], 0 ); + } + } + + /* Compute: d_acc - 12*(np -1). */ + acc = L_deposit_l( d_acc ); + IF( L_msu( acc, 12 / 2, sub( np, 1 ) ) > 0 ) /* 12/2 is to compensate the fractional mode multiply */ + { + condition1 = 1; /* Signifies: d_acc/(np - 1) > 12 */ + move16(); + } + ELSE + { + condition1 = 0; /* Signifies: d_acc/(np - 1) <= 12 */ + move16(); + /* NB: For np = 0 or 1, it fits this condition. */ + } + + /* Compute: p_energy - 147.87276*n_energy. */ + IF( n_energy_man != 0 ) + { + Mpy_32_16_ss( n_energy_man, 18928, &acc, &lsb16 ); /* 147.87276 in Q7 */ + expo = sub( n_energy_exp, 15 - 7 ); /* Due to 18928 in Q7 */ + acc = L_negate( acc ); /* To facilitate the following floating_point_add() to perform subtraction. */ + floating_point_add( &acc, &expo, p_energy_man, p_energy_exp ); + } + ELSE + { + acc = L_deposit_l( 0 ); + } + IF( acc > 0 ) + { + condition2 = 1; /* Signifies: p_energy / n_energy > 147.87276 */ + move16(); + } + ELSE + { + condition2 = 0; /* Signifies: p_energy / n_energy <= 147.87276 */ + move16(); + } + + condition3 = 0; + move16(); + condition4 = 0; + move16(); + + L_tmp = Mult_32_16( peak_h, 12603 ); + IF( GT_32( peak_l, L_tmp ) ) + { + exp = norm_l( peak_l ); + } + ELSE + { + exp = norm_l( L_tmp ); + } + IF( GT_32( avrg_h, avrg_l ) ) + { + exp1 = norm_l( avrg_h ); + } + ELSE + { + exp1 = norm_l( avrg_l ); + } + + L_tmp1 = Mult_32_16( peak_l, 12603 ); + IF( GT_32( peak_h, L_tmp1 ) ) + { + exp2 = norm_l( peak_h ); + } + ELSE + { + exp2 = norm_l( L_tmp1 ); + } + + test(); + test(); + test(); + test(); +#ifdef BASOP_NOGLOB + IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) ) +#else + IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl( avrg_H1, 1 ) ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( L_tmp, exp ), L_shl( avrg_l, exp1 ) ) ) || GT_32( Mult_32_32( L_shl( L_tmp1, exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) ) +#endif + { + condition3 = 1; + move16(); + } + + L_tmp = Mult_32_16( peak_h, 12800 ); + IF( GT_32( peak_l, L_tmp ) ) + { + exp = norm_l( peak_l ); + } + ELSE + { + exp = norm_l( L_tmp ); + } + + L_tmp1 = Mult_32_16( peak_l, 6400 ); + IF( GT_32( peak_h, L_tmp1 ) ) + { + exp2 = norm_l( peak_h ); + } + ELSE + { + exp2 = norm_l( L_tmp1 ); + } + + IF( GT_32( peak_h, L_shl( L_tmp1, 1 ) ) ) + { + exp3 = norm_l( peak_h ); + } + ELSE + { + exp3 = sub( norm_l( L_tmp1 ), 1 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 ) ) && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 ), avrg_H2 ) ) || + ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 ), avrg_h ) ) ) + { + condition4 = 1; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + + IF( ( GE_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) && GT_32( st->input_Fs, 16000 ) && ( s_xor( condition1, condition2 ) != 0 || condition3 ) ) || ( ( LT_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) || EQ_32( st->input_Fs, 16000 ) ) && condition4 ) ) + { + c = MDCT_CLASSIFER_HQ_LOCAL; /* Q13 */ + move16(); + } + ELSE + { + c = MDCT_CLASSIFER_TCX_LOCAL; /* Q13 */ + move16(); + } + + /* Smooth decision from instantaneous decision*/ + acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */ + clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */ + + /* Do thresholding with hysteresis */ + + IF( GT_16( st->last_enerBuffer_exp, enerBuffer_exp ) ) + { + gain1_tmp = L_shr( gain1, sub( st->last_enerBuffer_exp, enerBuffer_exp ) ); + move32(); + gain2_tmp = L_shr( gain2, sub( st->last_enerBuffer_exp, enerBuffer_exp ) ); + move32(); + } + ELSE + { + hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st->last_enerBuffer_exp ) ); + move32(); + hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st->last_enerBuffer_exp ) ); + move32(); + gain1_tmp = gain1; + move32(); + gain2_tmp = gain2; + move32(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + +#ifdef BASOP_NOGLOB + IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) ) +#else + IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl( gain1_tmp, 1 ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl( gain2_tmp, 1 ) ) ) ) ) +#endif + { + clas_final = hTcxEnc->clas_final_old; + move16(); + } + ELSE IF( GT_16( clas_sec, hTcxEnc->clas_sec_old_fx ) && GT_16( clas_sec, MDCT_CLASSIFER_THRESH_UP ) ) /* Going up? */ + { + clas_final = HQ_CORE; /* Q0 */ + move16(); + } + ELSE IF( LT_16( clas_sec, MDCT_CLASSIFER_THRESH_DOWN ) ) /* Going down */ + { + clas_final = TCX_20_CORE; + move16(); + } + ELSE + { + clas_final = hTcxEnc->clas_final_old; + move16(); + } + + + /* Prevent the usage of HQ_CORE on noisy-speech or inactive */ + test(); + test(); + test(); + if ( EQ_16( st->mdct_sw_enable, MODE2 || st->element_mode > EVS_MONO ) && ( EQ_16( st->flag_noisy_speech_snr, 1 ) || st->vad_flag == 0 ) && EQ_16( clas_final, HQ_CORE ) ) + { + clas_final = TCX_20_CORE; + move16(); + } + + /* Restrict usage of HQ_core to supported operating range */ + /* EVS: brate == st->total_brate */ + /* IVAS: brate is the nominal bitrate while st->total_brate may fluctuate. This sets a hard limit for HQ at HQ_16k40 */ + test(); + test(); + test(); + if ( LE_32( st->total_brate, HQ_16k40 ) || LT_32( brate, HQ_16k40 ) || EQ_16( st->bwidth, NB ) || GT_32( brate, IVAS_48k ) ) + { + clas_final = TCX_20_CORE; + move16(); + } + + + /* Memory update */ + + hTcxEnc->clas_sec_old_fx = clas_sec; + move16(); /* Q13 */ + hTcxEnc->clas_final_old = clas_final; + move16(); /* Q0 */ + hTcxEnc->last_gain1 = gain1; + move32(); + hTcxEnc->last_gain2 = gain2; + move32(); + st->last_enerBuffer_exp = enerBuffer_exp; + move16(); + + return clas_final; +} +#endif diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index 6bcf678a1dab815e60eeb7d424324c04c11cde48..93edebeea35b4c9795ce1d32ad18574d97310926 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -10,6 +10,7 @@ #include "rom_com.h" /* Static table prototypes */ //#include "prot_fx.h" /* Function prototypes */ #include "rom_basop_util.h" +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -471,6 +472,437 @@ Word16 pit_encode_fx( /* o : Fractional pitc return pitch_cl; } +#ifdef IVAS_FLOAT_FIXED +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response */ + const Word16 *xn, /* i : target vector */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +) +{ + Word16 pitch_cl; + Word16 pit_flag, delta, mult_Top, nBits; + Word16 L_sufr_sft; + Word16 T_op[2]; /* values for two half-frames */ +#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING + (void) tdm_Pitch_reuse_flag; +#endif + + L_sufr_sft = 6; + move16(); + if ( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + L_sufr_sft = 7; + } + + /*----------------------------------------------------------------* + * convert pitch values to 16kHz domain + *----------------------------------------------------------------*/ + IF( EQ_16( L_frame, L_FRAME ) || ( tdm_Pri_pitch_buf != NULL && tdm_Pri_pitch_buf[0] < 0 ) ) + { + Copy( pitch, T_op, 2 ); + } + ELSE /* L_frame == L_FRAME16k */ + { + /*T_op[0] = (int16_t)(pitch[0] * 1.25f + 0.5f); + T_op[1] = (int16_t)(pitch[1] * 1.25f + 0.5f);*/ + T_op[0] = shr( add( round_fx( L_shl( L_mult( 20480, pitch[0] ), 2 ) ), 1 ), 1 ); + move16(); + T_op[1] = shr( add( round_fx( L_shl( L_mult( 20480, pitch[1] ), 2 ) ), 1 ), 1 ); + move16(); + } + + /*----------------------------------------------------------------* + * Set pit_flag to 0 for every subframe with absolute pitch search + *----------------------------------------------------------------*/ + pit_flag = i_subfr; + move16(); + if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + pit_flag = 0; + move16(); + } + + /*-----------------------------------------------------------------* + * Limit range of pitch search + * Fractional pitch search + * Pitch quantization + *-----------------------------------------------------------------*/ + mult_Top = 1; + move16(); + + IF( !Opt_AMR_WB ) + { + /*----------------------------------------------------------------* + * pitch Q: Set limit_flag to 0 for restrained limits, and 1 for extended limits + *----------------------------------------------------------------*/ + test(); + test(); + IF( i_subfr == 0 ) + { + *limit_flag = 1; + move16(); + if ( EQ_16( coder_type, VOICED ) ) + { + *limit_flag = 2; + move16(); /* double-extended limits */ + } + test(); + if ( EQ_16( coder_type, GENERIC ) && EQ_32( core_brate, ACELP_7k20 ) ) + { + *limit_flag = 0; + move16(); + } + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) && EQ_16( coder_type, GENERIC ) && LE_32( core_brate, ACELP_13k20 ) ) + { + /*if( *T0 > (PIT_FR1_EXTEND_8b + PIT_MIN)>>1 )*/ + if ( GT_16( *T0, shr( add( PIT_FR1_EXTEND_8b, PIT_MIN ), 1 ) ) ) + { + *limit_flag = 0; + move16(); + } + } + + IF( *limit_flag == 0 ) + { + test(); + test(); + IF( i_subfr == 0 && LT_16( T_op[0], PIT_MIN ) ) + { + mult_Top = 2; + move16(); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) && LT_16( T_op[1], PIT_MIN ) ) + { + mult_Top = 2; + move16(); + } + } + /*-------------------------------------------------------* + * Retrieve the number of Q bits + *-------------------------------------------------------*/ + nBits = 0; + move16(); + IF( NE_16( coder_type, AUDIO ) ) + { + nBits = pitch_bits[shr( i_subfr, L_sufr_sft )]; + } + IF( EQ_16( coder_type, AUDIO ) ) + { + /*-------------------------------------------------------* + * Pitch encoding in AUDIO coder type + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + + delta = 4; + move16(); + test(); + test(); + if ( EQ_16( L_subfr, L_frame / 2 ) && i_subfr != 0 && EQ_16( L_frame, L_FRAME ) ) + { + pit_flag = L_SUBFR; + move16(); + } + IF( pit_flag == 0 ) + { + nBits = 10; + move16(); + } + ELSE + { + nBits = 6; + move16(); + } + + /* pitch lag search limitation */ + test(); + IF( i_subfr == 0 ) + { + limit_T0_fx( L_frame, delta, pit_flag, *limit_flag, mult_Top * T_op[0], 0, T0_min, T0_max ); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) && pit_flag == 0 ) + { + limit_T0_fx( L_frame, delta, pit_flag, *limit_flag, mult_Top * T_op[1], 0, T0_min, T0_max ); + } + + /* search and encode the closed loop pitch period */ + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr ); + + pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + ELSE IF( EQ_16( coder_type, VOICED ) ) + { + /*-------------------------------------------------------* + * Pitch encoding in VOICED code type (ACELP@12k8 core only) + *-------------------------------------------------------*/ + + delta = 4; + move16(); + if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + pit_flag = i_subfr; + move16(); + } + + /* pitch lag search limitation */ + IF( i_subfr == 0 ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, mult_Top * T_op[0], 0, T0_min, T0_max ); + } + + /* search and encode the closed loop pitch period */ + test(); + test(); + IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 5 ) ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_DOUBLEEXTEND_9b, PIT_FR1_DOUBLEEXTEND_9b, L_FRAME, L_SUBFR ); + move16(); + } + ELSE IF( EQ_16( nBits, 10 ) ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + move16(); + } + + pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } +#if 1 + //#ifdef ADD_LRTD + ELSE IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) || EQ_16( nBits, 4 ) ) + { + /*-------------------------------------------------------* + * Pitch encoding with reusing primary channel information + *-------------------------------------------------------*/ + Word16 loc_T0, loc_frac; + + delta = 4; + move16(); + + pit_flag = L_SUBFR; + move16(); + + Word16 idx1 = shr( i_subfr, L_sufr_sft ); + Word16 idx2 = shr( add( i_subfr, 64 ), L_sufr_sft ); + + IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + loc_T0 = add( shr( tdm_Pri_pitch_buf[idx1], 1 ), shr( tdm_Pri_pitch_buf[idx2], 1 ) ); // Q6 + loc_frac = shr( sub( loc_T0, shl( shr( loc_T0, 6 ), 6 ) ), 4 ); // Q2 + loc_T0 = shr( loc_T0, 6 ); // Q0 + } + ELSE + { + loc_T0 = tdm_Pri_pitch_buf[idx1]; // Q6 + loc_frac = shr( sub( loc_T0, shl( shr( loc_T0, 6 ), 6 ) ), 4 ); // Q2 + loc_T0 = shr( loc_T0, 6 ); // Q0 + } + + /* pitch lag search limitation */ + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, loc_T0, loc_frac, T0_min, T0_max ); + IF( nBits > 0 ) + { + /* search and encode the closed loop pitch period */ + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + IF( EQ_16( delta, 8 ) ) + { + *T0_frac = 0; + move16(); + } + pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + ELSE + { + *T0 = loc_T0; + move16(); + *T0_frac = loc_frac; + move16(); + } + } +#endif + ELSE + { + /*-------------------------------------------------------* + * Pitch encoding in GENERIC coder type + * (both ACELP@12k8 and ACELP@16k cores) + *-------------------------------------------------------*/ + + delta = 8; + move16(); + + /* pitch lag search limitation */ + IF( i_subfr == 0 ) + { + limit_T0_fx( L_frame, delta, pit_flag, *limit_flag, mult_Top * T_op[0], 0, T0_min, T0_max ); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + limit_T0_fx( L_frame, delta, pit_flag, *limit_flag, mult_Top * T_op[1], 0, T0_min, T0_max ); + } + + /* search and encode the closed loop pitch period */ + IF( EQ_16( L_frame, L_FRAME ) ) + { + test(); + test(); + IF( EQ_16( nBits, 8 ) || EQ_16( nBits, 5 ) ) + { + IF( *limit_flag == 0 ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + } + ELSE + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN_EXTEND, PIT_FR1_EXTEND_8b, L_FRAME, L_SUBFR ); + } + } + ELSE IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) + { + IF( *limit_flag == 0 ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + } + ELSE + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_EXTEND_9b, PIT_FR1_EXTEND_9b, L_FRAME, L_SUBFR ); + } + } + ELSE IF( EQ_16( nBits, 10 ) ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_SUBFR ); + } + + pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + ELSE /* L_frame == L_FRAME16k */ + { + test(); + IF( EQ_16( nBits, 9 ) || EQ_16( nBits, 6 ) ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, L_FRAME16k, L_SUBFR ); + } + ELSE IF( nBits == 10 ) + { + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + } + + pit16k_Q_enc_ivas_fx( hBstr, nBits, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + } + } + + /*-------------------------------------------------------* + * Pitch encoding in AMR-WB IO mode + *-------------------------------------------------------*/ + + ELSE + { + delta = 8; + move16(); + *limit_flag = 0; + move16(); + + IF( EQ_32( core_brate, ACELP_6k60 ) ) + { + nBits = 5; + move16(); + + /* pitch lag search limitation */ + IF( i_subfr == 0 ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, i_mult2( mult_Top, T_op[0] ), 0, T0_min, T0_max ); + nBits = 8; + move16(); + } + + if ( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + /* rewrite pit_flag - it must not be zero */ + pit_flag = i_subfr; + move16(); + } + + /* search and encode the closed loop pitch period */ + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + } + ELSE IF( EQ_32( core_brate, ACELP_8k85 ) ) + { + nBits = 5; + move16(); + + /* pitch lag search limitation */ + IF( i_subfr == 0 ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, i_mult2( mult_Top, T_op[0] ), 0, T0_min, T0_max ); + nBits = 8; + move16(); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, i_mult2( mult_Top, T_op[1] ), 0, T0_min, T0_max ); + nBits = 8; + move16(); + } + + /* search and encode the closed loop pitch period */ + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + } + ELSE + { + nBits = 6; + move16(); + + /* pitch lag search limitation */ + IF( i_subfr == 0 ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, i_mult2( mult_Top, T_op[0] ), 0, T0_min, T0_max ); + nBits = 9; + move16(); + } + ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, *limit_flag, i_mult2( mult_Top, T_op[1] ), 0, T0_min, T0_max ); + nBits = 9; + move16(); + } + ELSE + { + limit_T0_fx( L_FRAME, delta, pit_flag, 0, *T0, 0, T0_min, T0_max ); /* T0_frac==0 to keep IO with AMR-WB */ + } + + /* search and encode the closed loop pitch period */ + *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + } + + pit_Q_enc_fx( hBstr, 1, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + + /*-------------------------------------------------------* + * Compute floating pitch output + *-------------------------------------------------------*/ + + /*pitch = (float)(*T0) + (float)(*T0_frac)/4.0f;*/ /* save subframe pitch values */ + pitch_cl = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); /* save subframe pitch values Q6 */ + + return pitch_cl; +} +#endif + /*-------------------------------------------------------------------* * abs_pit_enc() * @@ -1119,6 +1551,99 @@ void pit_Q_enc_fx( return; } +void pit_Q_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 delta, /* i : Half the CL searched interval */ + const Word16 pit_flag, /* i : absolute(0) or delta(1) pitch Q */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + const Word16 T0, /* i : integer pitch lag */ + const Word16 T0_frac, /* i : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* o : delta search max_val */ +) +{ + Word16 pitch_index; + + IF( EQ_16( nBits, 10 ) ) /* absolute encoding with 10 bits */ + { + IF( limit_flag == 0 ) + { + /* pitch_index = T0*4 + T0_frac - (PIT_MIN*4);*/ + pitch_index = sub( add( shl( T0, 2 ), T0_frac ), ( PIT_MIN * 4 ) ); + } + ELSE IF( EQ_16( limit_flag, 1 ) ) + { + /*pitch_index = T0*4 + T0_frac - (PIT_MIN_EXTEND*4);*/ + pitch_index = sub( add( shl( T0, 2 ), T0_frac ), ( PIT_MIN_EXTEND * 4 ) ); + } + ELSE /* limit_flag == 2 */ + { + /*pitch_index = T0*4 + T0_frac - (PIT_MIN_DOUBLEEXTEND*4);*/ + pitch_index = sub( add( shl( T0, 2 ), T0_frac ), ( PIT_MIN_DOUBLEEXTEND * 4 ) ); + } + } + ELSE IF( EQ_16( nBits, 9 ) ) /* absolute encoding with 9 bits */ + { + pitch_index = abs_pit_enc_fx( 4, limit_flag, T0, T0_frac ); + + /* find T0_min and T0_max for delta search */ + IF( Opt_AMR_WB ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, 0, T0, 0, T0_min, T0_max ); /* T0_frac==0 to keep IO with AMR-WB */ + } + } + ELSE IF( EQ_16( nBits, 8 ) ) /* absolute encoding with 8 bits */ + { + pitch_index = abs_pit_enc_fx( 2, limit_flag, T0, T0_frac ); + + /* find T0_min and T0_max for delta search */ + IF( Opt_AMR_WB ) + { + limit_T0_fx( L_FRAME, delta, pit_flag, 0, T0, 0, T0_min, T0_max ); /* T0_frac==0 to keep IO with AMR-WB */ + } + } + ELSE IF( EQ_16( nBits, 6 ) ) /* relative encoding with 6 bits */ + { + pitch_index = delta_pit_enc_fx( 4, T0, T0_frac, *T0_min ); + } + ELSE IF( EQ_16( nBits, 5 ) ) /* relative encoding with 5 bits */ + { + IF( EQ_16( delta, 8 ) ) + { + pitch_index = delta_pit_enc_fx( 2, T0, T0_frac, *T0_min ); + } + ELSE /* delta == 4 */ + { + pitch_index = delta_pit_enc_fx( 4, T0, T0_frac, *T0_min ); + } + } + ELSE /* nBits == 4 ) */ /* relative encoding with 4 bits */ + { + IF( EQ_16( delta, 8 ) ) + { + pitch_index = delta_pit_enc_fx( 0, T0, T0_frac, *T0_min ); + } + ELSE /* delta == 4 */ + { + pitch_index = delta_pit_enc_fx( 2, T0, T0_frac, *T0_min ); + } + } + + IF( !Opt_AMR_WB ) + { + /* find T0_min and T0_max for delta search */ + limit_T0_fx( L_FRAME, delta, L_SUBFR, limit_flag, T0, T0_frac, T0_min, T0_max ); + } + + { + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); + } + + return; +} + /*-------------------------------------------------------------------* * pit16k_Q_enc() * @@ -1197,6 +1722,77 @@ void pit16k_Q_enc_fx( return; } +void pit16k_Q_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + const Word16 T0, /* i : integer pitch lag */ + const Word16 T0_frac, /* i : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* o : delta search max_val */ +) +{ + Word16 pitch_index; + + IF( EQ_16( nBits, 10 ) ) /* absolute encoding with 10 bits */ + { + { + IF( LT_16( T0, PIT16k_FR2_EXTEND_10b ) ) + { + /*pitch_index = T0*4 + T0_frac - (PIT16k_MIN_EXTEND*4);*/ + pitch_index = add( shl( T0, 2 ), sub( T0_frac, ( PIT16k_MIN_EXTEND * 4 ) ) ); + } + ELSE + { + /*pitch_index = T0*2 + (T0_frac>>1) - (PIT16k_FR2_EXTEND_10b*2) + ((PIT16k_FR2_EXTEND_10b-PIT16k_MIN_EXTEND)*4);*/ + pitch_index = add( sub( add( shl( T0, 1 ), shr( T0_frac, 1 ) ), ( PIT16k_FR2_EXTEND_10b * 2 ) ), ( ( PIT16k_FR2_EXTEND_10b - PIT16k_MIN_EXTEND ) * 4 ) ); + } + } + + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); + } + ELSE IF( EQ_16( nBits, 9 ) ) /* absolute encoding with 9 bits */ + { + { + /*-------------------------------------------------------------------* + * The pitch range is encoded absolutely with 9 bits + * and is divided as follows: + * PIT16k_EXTEND_MIN to PIT16k_FR2_EXTEND_9b-1 resolution 1/4 (frac = 0,1,2 or 3) + * PIT16k_FR2_EXTEND_9b to PIT16k_FR1_EXTEND_9b-1 resolution 1/2 (frac = 0 or 2) + * PIT16k_FR1_EXTEND_9b to PIT16k_MAX_EXTEND resolution 1 (frac = 0) + *-------------------------------------------------------------------*/ + + IF( LT_16( T0, PIT16k_FR2_EXTEND_9b ) ) + { + /*pitch_index = T0*4 + T0_frac - (PIT16k_MIN_EXTEND*4);*/ + pitch_index = add( shl( T0, 2 ), sub( T0_frac, ( PIT16k_MIN_EXTEND * 4 ) ) ); + } + ELSE IF( LT_16( T0, PIT16k_FR1_EXTEND_9b ) ) + { + /*pitch_index = T0*2 + (T0_frac>>1) - (PIT16k_FR2_EXTEND_9b*2) + ((PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4);*/ + pitch_index = add( sub( add( shl( T0, 1 ), shr( T0_frac, 1 ) ), ( PIT16k_FR2_EXTEND_9b * 2 ) ), ( ( PIT16k_FR2_EXTEND_9b - PIT16k_MIN_EXTEND ) * 4 ) ); + } + ELSE + { + /*pitch_index = T0 - PIT16k_FR1_EXTEND_9b + ((PIT16k_FR2_EXTEND_9b-PIT16k_MIN_EXTEND)*4) + ((PIT16k_FR1_EXTEND_9b-PIT16k_FR2_EXTEND_9b)*2);*/ + pitch_index = add( add( sub( T0, PIT16k_FR1_EXTEND_9b ), ( ( PIT16k_FR2_EXTEND_9b - PIT16k_MIN_EXTEND ) * 4 ) ), ( ( PIT16k_FR1_EXTEND_9b - PIT16k_FR2_EXTEND_9b ) * 2 ) ); + } + } + + push_indice( hBstr, IND_PITCH, pitch_index, 9 ); + } + ELSE /* nBits == 6 */ /* relative encoding with 6 bits */ + { + /*pitch_index = (T0 - *T0_min) * 4 + T0_frac;*/ + pitch_index = add( shl( sub( T0, *T0_min ), 2 ), T0_frac ); + + push_indice( hBstr, IND_PITCH, pitch_index, nBits ); + } + + limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, T0, T0_frac, T0_min, T0_max ); + + return; +} /*------------------------------------------------------------------* * pit_encode: diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index 065fb2a45df2040d79d80bcc9d495987732278c8..524956f7fa1ab5d42795c2d0633dc9f506a5dd48 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -42,6 +42,10 @@ #include "prot.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#include "prot_fx_enc.h" +#endif /*-------------------------------------------------------------------* * pre_proc() @@ -74,6 +78,10 @@ void pre_proc( { int16_t delay; const float *signal_in; + +#ifdef IVAS_FLOAT_FIXED + const Word16 *signal_in_fx; +#endif float *inp_12k8, *new_inp_12k8, *inp_16k, *new_inp_16k; /* pointers to current frame and new data */ float old_wsp[L_WSP], *wsp; /* weighted input signal buffer */ float pitch_fr[NB_SUBFR]; /* fractional pitch values */ @@ -121,6 +129,10 @@ void pre_proc( signal_in = st->input; +#ifdef IVAS_FLOAT_FIXED + signal_in_fx = st->input_fx; +#endif + localVAD_HE_SAD = 0; NB_speech_HO = 0; clean_speech_HO = 0; @@ -278,7 +290,50 @@ void pre_proc( if ( st->tcx10Enabled || st->tcx20Enabled ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->hTranDet->subblockEnergies.firState1 = (Word16) floatToFixed( st->hTranDet->subblockEnergies.firState1_flt, 0 ); + st->hTranDet->subblockEnergies.firState2 = (Word16) floatToFixed( st->hTranDet->subblockEnergies.firState2_flt, 0 ); + + FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY + 1; i++ ) + { + st->hTranDet->subblockEnergies.accSubblockNrg[i] = floatToFixed( st->hTranDet->subblockEnergies.accSubblockNrg_flt[i], 0 ); + } + + FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) + { + st->hTranDet->subblockEnergies.subblockNrg[i] = floatToFixed( st->hTranDet->subblockEnergies.subblockNrg_flt[i], 0 ); + } + + + FOR( Word16 i = 0; i < L_FRAME_MAX / NSUBBLOCKS; i++ ) + { + st->hTranDet->subblockEnergies.pDelayBuffer->buffer[i] = float_to_fix16( st->hTranDet->subblockEnergies.pDelayBuffer->buffer_flt[i], 0 ); + } + + st->hTranDet->transientDetector.attackRatioThreshold = float_to_fix16( st->hTranDet->transientDetector.attackRatioThreshold_flt, 0 ); + + floatToFixed_arr( st->input, st->input_fx, 0, input_frame ); + + st->hTranDet->subblockEnergies.facAccSubblockNrg = float_to_fix16( st->hTranDet->subblockEnergies.facAccSubblockNrg_flt, 0 ); + +#endif + + RunTransientDetection_ivas_fx( signal_in_fx, input_frame, st->hTranDet ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + st->hTranDet->subblockEnergies.firState1_flt = fixedToFloat( (Word32) st->hTranDet->subblockEnergies.firState1, 0 ); + st->hTranDet->subblockEnergies.firState2_flt = fixedToFloat( (Word32) st->hTranDet->subblockEnergies.firState2, 0 ); + + FOR( Word16 i = 0; i < NSUBBLOCKS + MAX_TD_DELAY; i++ ) + { + st->hTranDet->subblockEnergies.subblockNrg_flt[i] = fixedToFloat( st->hTranDet->subblockEnergies.subblockNrg[i], 0 ); + } +#endif +#else RunTransientDetection( signal_in, input_frame, st->hTranDet ); +#endif currFlatness = GetTCXAvgTemporalFlatnessMeasure( st->hTranDet, NSUBBLOCKS, 0 ); } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 57c977cb8819f0c646b9aecb0b8cec430ad898f0..cf502f30795b0270b4f60768cf7f820ca5b2b0eb 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -565,6 +565,11 @@ void swb_pre_proc_fx( const CLDFB_SCALE_FACTOR *cldfbScale /* i : scale data of real and imag CLDFB buffers */ ); +void InitSWBencBufferStates_fx( + TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word16 *shb_speech /* o : SHB target signal (6-14kHz) at 16kHz */ +); + void swb_tbe_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 coder_type, /* i : coding type */ @@ -864,6 +869,16 @@ void pit16k_Q_enc_fx( Word16 *T0_max /* o : delta search max */ ); +void pit16k_Q_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + const Word16 T0, /* i : integer pitch lag */ + const Word16 T0_frac, /* i : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* o : delta search max_val */ +); + Word16 pitch_fr4_fx( /* o : chosen integer pitch lag */ const Word16 exc[], /* i : excitation buffer Q_new*/ const Word16 xn[], /* i : target signal Q_new-1+shift*/ @@ -891,6 +906,19 @@ void pit_Q_enc_fx( Word16 *T0_max /* o : delta search max */ ); +void pit_Q_enc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 nBits, /* i : # of Q bits */ + const Word16 delta, /* i : Half the CL searched interval */ + const Word16 pit_flag, /* i : absolute(0) or delta(1) pitch Q */ + const Word16 limit_flag, /* i : restrained(0) or extended(1) Q limits */ + const Word16 T0, /* i : integer pitch lag */ + const Word16 T0_frac, /* i : pitch fraction */ + Word16 *T0_min, /* i/o: delta search min */ + Word16 *T0_max /* o : delta search max_val */ +); + void PsychAdaptLowFreqEmph_fx( Word32 x[], const Word16 lpcGains[], const Word16 lpcGains_e[] ); @@ -948,6 +976,13 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, */ void RunTransientDetection_fx( Word16 const *i, Word16 nSamplesAvailable, struct TransientDetection *pTransientDetection ); + +void RunTransientDetection_ivas_fx( + const Word16 *input_fx, /* i : input signal Q0 */ + const int16_t length, /* i : frame length */ + TRAN_DET_HANDLE hTranDet /* i/o: transient detection handle */ +); + /** Get the average temporal flatness measure using subblock energies aligned with the TCX. * @param pTransientDetection Structure that contains transient detectors to be run. * @param nCurrentSubblocks Number of the subblocks from the current frame to use for the calculation. @@ -1872,6 +1907,20 @@ void find_targets_fx( , Word16 *h1 /* Q14 ?*/ ); +void find_targets_ivas_fx( + const Word16 *speech, /* i : pointer to the speech frame Q_new-1*/ + const Word16 *mem_syn, /* i : memory of the synthesis filter Q_new-1*/ + const Word16 i_subfr, /* i : subframe index */ + Word16 *mem_w0, /* i/o: weighting filter denominator memory Q_new-1*/ + const Word16 *p_Aq, /* i : interpolated quantized A(z) filter Q12*/ + const Word16 *res, /* i : residual signal Q_new*/ + const Word16 L_subfr, /* i : length of vectors for gain quantization */ + const Word16 *Ap, /* i : unquantized A(z) filter with bandwidth expansion Q12*/ + Word16 tilt_fac, /* i : tilt factor Q15 */ + Word16 *xn, /* o : Close-loop Pitch search target vector Q_new-1*/ + Word16 *cn, /* o : target vector in residual domain Q_new*/ + Word16 *h1 /* o : impulse response of weighted synthesis filter */ +); void E_ACELP_adaptive_codebook( Word16 *exc, /* i : pointer to the excitation frame */ @@ -2462,6 +2511,13 @@ void corr_xh_fx( const Word16 h[] /* i : impulse response (of weighted synthesis filter) */ ); +void corr_xh_ivas_fx( + const Word16 *x, /* i : target signal Q_new - 1 */ + Word16 *y, /* o : correlation between x[] and h[] Q_new + 1 */ + const Word16 *h, /* i : impulse response (of weighted synthesis filter) e(norm_s(h1[0])+1) */ + const Word16 L_subfr /* i : length of the subframe */ +); + void qlpc_avq_fx( const Word16 *lsf, /* i : Input LSF vectors (14Q1*1.28) */ const Word16 *lsfmid, /* i : Input LSF vectors (14Q1*1.28) */ @@ -2835,6 +2891,28 @@ Word16 pit_encode_fx( /* o : Fractional pitc const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ ); +Word16 pit_encode_ivas_fx( /* o : Fractional pitch for each subframe */ + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 pitch_bits[], /* i : pitch bits */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 coder_type, /* i : coding type */ + Word16 *limit_flag, /* i/o: restrained(0) or extended(1) Q limits */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *exc, /* i/o: pointer to excitation signal frame */ + const Word16 L_subfr, /* i : subframe length */ + const Word16 *pitch, /* i : open loop pitch estimates in current frame */ + Word16 *T0_min, /* i/o: lower limit for close-loop search */ + Word16 *T0_max, /* i/o: higher limit for close-loop search */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch */ + const Word16 *h1, /* i : weighted filter input response */ + const Word16 *xn, /* i : target vector */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */ +); + Word16 lp_filt_exc_enc_fx( const Word16 codec_mode, /* i : MODE1 or MODE2 Q0 */ const Word16 coder_type, /* i : coding type Q0 */ @@ -2877,6 +2955,32 @@ Word16 inov_encode_fx( const Word16 L_subfr, /* i : subframe length */ Word16 shift ); +Word16 inov_encode_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word32 core_brate, /* i : core bitrate */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + const Word16 L_frame, /* i : length of the frame */ + const Word16 last_L_frame, /* i : length of the last frame */ + const Word16 coder_type, /* i : coding type */ + const Word16 bwidth, /* i : input signal bandwidth */ + const Word16 sharpFlag, /* i : formant sharpening flag */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 tc_subfr, /* i : TC subframe index */ + const Word16 *p_Aq, /* i : LP filter coefficients Q12*/ + const Word16 gain_pit, /* i : adaptive excitation gain Q14*/ + Word16 *cn, /* i/o: target vector in residual domain Q_new*/ + const Word16 *exc, /* i : pointer to excitation signal frame Q_new*/ + Word16 *h2, /* i/o: weighted filter input response Q12*/ + const Word16 tilt_code, /* i : tilt of the excitation of previous subframe Q15*/ + const Word16 pt_pitch, /* i : pointer to current subframe fractional pitch Q6*/ + const Word16 *xn2, /* i : target vector for innovation search Q_new-1+shift*/ + Word16 *code, /* o : algebraic excitation Q9*/ + Word16 *y2, /* o : zero-memory filtered algebraic excitation Q9*/ + Word16 *unbits, /* o : number of unused bits for PI */ + const Word16 L_subfr, /* i : subframe length */ + Word16 shift, + Word16 Q_new ); + void gain_enc_mless_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 gains_mode[], /* i : gain bits */ @@ -3040,6 +3144,27 @@ void gain_enc_lbr_fx( const Word16 L_subfr /* i : subframe length */ ); +void gain_enc_lbr_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 coder_type, /* i : coding type */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *xn, /* i : target vector Q_xn*/ + const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/ + const Word16 Q_xn, /* i : xn and y1 format */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/ + const Word16 *code, /* i : algebraic excitation Q9*/ + Word16 *gain_pit, /* o : quantized pitch gain Q14*/ + Word32 *gain_code, /* o : quantized codebook gain Q16*/ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/ + Word16 *g_corr, /* i/o: correlations , -2,, -2 and 2 mant/exp*/ + Word32 gc_mem[], /* i/o: gain_code from previous subframes */ + Word16 gp_mem[], /* i/o: gain_pitch from previous subframes */ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ + const int16_t L_subfr /* i : subframe length */ +); + void gain_enc_SQ_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 gains_mode[], /* i : gain bits */ @@ -3929,4 +4054,14 @@ void writeLPCparam_fx( const Word16 no_param_lpc, /* i : number of LPC parameters */ Word16 *nbits_lpc /* o : LPC bits written */ ); + +Word16 cng_energy_ivas_fx( + const Word16 element_mode, /* i : element mode */ + const Word16 bwidth, /* i : audio bandwidh */ + const Word16 CNG_mode, /* i : mode for DTX configuration */ + const Word16 CNG_att, /* i : attenuation factor for CNG Q7 */ + const Word16 *exc, /* i : input signal */ + const Word16 len, /* i : vector length */ + const Word16 Q_new /* i : Input scaling */ +); #endif diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 6f42de5416b506b808ce40ad9d9b3d26d7d582a5..21abcc4d1713907a1abcde8f8667e9c577fbc8af 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1041,12 +1041,12 @@ typedef struct lpd_state_structure float mem_syn_r_flt[L_SYN_MEM]; /* ACELP synthesis memory for 1.25ms */ float mem_syn3_flt[M]; + Word16 mem_w0; /* weighting filter memory */ Word16 mem_syn[M]; /* ACELP synthesis memory (pe) before post-proc */ Word16 mem_syn1_fx[M]; /* synthesis filter memory (for core switching and FD BWE) */ Word16 mem_syn2[M]; /* ACELP synthesis memory (pe) after post-proc */ Word16 mem_syn_r[L_SYN_MEM]; /* ACELP synthesis memory for 1.25ms */ Word16 mem_syn3[M]; - Word16 mem_w0; /* weighting filter memory */ Word16 e_mem_syn; float tilt_code_flt; @@ -1333,15 +1333,23 @@ typedef struct td_bwe_enc_structure Word16 cldfbHBLT; /* states for the filters used in generating SHB excitation from WB excitation*/ float mem_csfilt[2]; - Word32 mem_csfilt_fx[2]; /* Q(prev_Q_bwe_exc) */ - float mem_shb_res[MAX_LEN_MA_FILTER]; /* old SHB residual signal */ - float old_EnvSHBres[L_FRAME4k]; /* old TD envelope of the SHB residual signal */ - float old_mean_EnvSHBres; /* energy of the last subframe of the SHB residual signal from previous frame */ - float prev_enr_EnvSHBres; /* energy of the residual SHB envelope from the previous frame */ - float prev_shb_env_tilt; /* tilt of the residual SHB envelope from the previous frame */ - float prev_pow_exc16kWhtnd; /* power of the LB excitation signal in the previous frame */ - float prev_mix_factor; /* mixing factor in the previous frame */ - float prev_Env_error; /* error in SHB envelope modelling */ + Word32 mem_csfilt_fx[2]; /* Q(prev_Q_bwe_exc) */ + float mem_shb_res[MAX_LEN_MA_FILTER]; /* old SHB residual signal */ + Word16 mem_shb_res_fx[MAX_LEN_MA_FILTER]; /* old SHB residual signal */ + float old_EnvSHBres[L_FRAME4k]; /* old TD envelope of the SHB residual signal */ + Word16 old_EnvSHBres_fx[L_FRAME4k]; /* old TD envelope of the SHB residual signal */ + float old_mean_EnvSHBres; /* energy of the last subframe of the SHB residual signal from previous frame */ + Word16 old_mean_EnvSHBres_fx; /* energy of the last subframe of the SHB residual signal from previous frame */ + float prev_enr_EnvSHBres; /* energy of the residual SHB envelope from the previous frame */ + Word16 prev_enr_EnvSHBres_fx; /* energy of the residual SHB envelope from the previous frame */ + float prev_shb_env_tilt; /* tilt of the residual SHB envelope from the previous frame */ + Word16 prev_shb_env_tilt_fx; /* tilt of the residual SHB envelope from the previous frame */ + float prev_pow_exc16kWhtnd; /* power of the LB excitation signal in the previous frame */ + Word16 prev_pow_exc16kWhtnd_fx; /* power of the LB excitation signal in the previous frame */ + float prev_mix_factor; /* mixing factor in the previous frame */ + Word16 prev_mix_factor_fx; /* mixing factor in the previous frame */ + float prev_Env_error; /* error in SHB envelope modelling */ + Word16 prev_Env_error_fx; /* error in SHB envelope modelling */ /* states for the filters used in generating SHB signal from SHB excitation*/ float state_syn_shbexc[L_SHB_LAHEAD]; @@ -2382,6 +2390,8 @@ typedef struct enc_core_structure Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ + Word16 Q_exc; + Word16 prev_Q_bwe_exc; Word16 prev_Q_bwe_syn; Word16 Q_stat_noise_ge; diff --git a/lib_enc/swb_pre_proc.c b/lib_enc/swb_pre_proc.c index 3336ee3362dfa27b9e8a1d2e4dbbea7af16ea496..fe5c5d8345c7f1cd0b1a882c8d4097f6ad8a0dcc 100644 --- a/lib_enc/swb_pre_proc.c +++ b/lib_enc/swb_pre_proc.c @@ -47,6 +47,7 @@ #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" #include "prot_fx.h" +#include "prot_fx_enc.h" #endif /*-------------------------------------------------------------------* @@ -303,7 +304,9 @@ void swb_pre_proc_ivas_fx( float sign, lbEner, v, t, regression; const float *thr, *regV; int16_t Sample_Delay_SWB_BWE32k, lMemRecalc32k, dft_ovl32k; - +#ifdef IVAS_FLOAT_FIXED + Word16 shb_speech_fx[L_FRAME16k]; +#endif lMemRecalc32k = NS2SA( 32000, L_MEM_RECALC_NS ); /* initialization */ @@ -738,7 +741,15 @@ void swb_pre_proc_ivas_fx( { if ( ( st->bwidth == FB || st->core == ACELP_CORE ) && ( st->element_mode == EVS_MONO ) ) { +#ifdef IVAS_FLOAT_FIXED + InitSWBencBufferStates_fx( st->hBWE_TD, shb_speech_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* To be removed */ InitSWBencBufferStates( st->hBWE_TD, shb_speech ); +#endif +#else + InitSWBencBufferStates( st->hBWE_TD, shb_speech ); +#endif } else { diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index fa64751348860272c44c241f534b7b3c42f1a5f8..4414d376285fcac6629f4597b0fbb9eff8772025 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -44,6 +44,9 @@ #include "rom_enc.h" #include "wmc_auto.h" #include "ivas_prot.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx_enc.h" +#endif /*-----------------------------------------------------------------* * Local constants @@ -111,7 +114,15 @@ void InitSWBencBuffer( set_f( hBWE_TD->old_speech_wb, 0.0f, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 16 ); set_f( hBWE_TD->old_input_fhb, 0.0f, NS2SA( 48000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) - L_FRAME48k / 2 ); +#ifdef IVAS_FLOAT_FIXED + InitSWBencBufferStates_fx( hBWE_TD, NULL ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* To be removed */ InitSWBencBufferStates( hBWE_TD, NULL ); +#endif +#else + InitSWBencBufferStates( hBWE_TD, NULL ); +#endif for ( i = 0; i < LPC_SHB_ORDER; i++ ) { diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index de765d5a01b6569e292998fba1c5607273af7263..90940ccfa9b4f4dc03e1e405cd0bbc833593f298 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -4991,3 +4991,40 @@ void TBEreset_enc_fx( } } } + +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * InitSWBencBufferStates() + * + * Initialize SWB buffer states + *-------------------------------------------------------------------*/ + +void InitSWBencBufferStates_fx( + TD_BWE_ENC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word16 *shb_speech /* o : SHB target signal (6-14kHz) at 16kHz */ +) +{ + IF( shb_speech != NULL ) + { + set16_fx( shb_speech, 0, L_FRAME16k ); + } + + set16_fx( hBWE_TD->old_speech_shb_fx, 0, L_LOOK_16k + L_SUBFR16k ); + set16_fx( hBWE_TD->mem_shb_res_fx, 0, MAX_LEN_MA_FILTER ); + set16_fx( hBWE_TD->old_EnvSHBres_fx, 0, L_FRAME4k ); + hBWE_TD->old_mean_EnvSHBres_fx = 0; + hBWE_TD->prev_enr_EnvSHBres_fx = 32767; /*1.0f in Q15*/ + hBWE_TD->prev_shb_env_tilt_fx = 0; + hBWE_TD->prev_pow_exc16kWhtnd_fx = 32767; /*1.0f in Q15*/ + hBWE_TD->prev_mix_factor_fx = 32767; /*1.0f in Q15*/ + hBWE_TD->prev_Env_error_fx = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + return; +} +#endif diff --git a/lib_enc/transient_detection.c b/lib_enc/transient_detection.c index dea0296adf688e5e6c5c038074fd34141fa8da5d..39d33b7b0e7bc413c0198ff4c757d7bb50120054 100644 --- a/lib_enc/transient_detection.c +++ b/lib_enc/transient_detection.c @@ -43,7 +43,9 @@ #include #include "wmc_auto.h" - +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#endif /*---------------------------------------------------------------* * Local constants *---------------------------------------------------------------*/ @@ -56,7 +58,6 @@ #define THR_LOW 4.25f #define THR_LOW_STEP 1.0f - /*---------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------*/ @@ -71,7 +72,6 @@ static void CalculateSubblockEnergies( const float *input, const int16_t nSample static void RunTransientDetector( TransientDetector *pTransientDetector ); static void GetAttackForTCXDecision( const float *pSubblockNrg, const float *pAccSubblockNrg, const int16_t nSubblocks, const int16_t nPastSubblocks, const float attackRatioThreshold, int16_t *pbIsAttackPresent, int16_t *pAttackIndex ); - /*-------------------------------------------------------------------* * InitTransientDetection() * @@ -92,6 +92,7 @@ void InitTransientDetection( /* Init the TCX Short/Long transient detector. */ InitTransientDetector( &hTranDet->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision, 8.5f, &hTranDet->transientDetector ); + hTranDet->transientDetector.CheckSubblocksForAttack_fx = GetAttackForTCXDecision_fx; /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure for the TCX LTP. */ if ( ext_mem_flag ) @@ -249,7 +250,6 @@ void RunTransientDetection( return; } - static uint16_t isLongTermTransient( const float frameTFM, float *lastTFM ) @@ -485,7 +485,6 @@ static void GetAttackForTCXDecision( return; } - static void InitDelayBuffer( const int16_t nFrameLength, const int16_t nDelay, @@ -579,7 +578,6 @@ static float InlineFilter( return 0.375f * inValue - 0.5f * firState1 + 0.125f * firState2; } - static void HighPassFilter( const float *input, const int16_t length, @@ -603,7 +601,6 @@ static void HighPassFilter( return; } - static void RunTransientDetector( TransientDetector *pTransientDetector ) { @@ -624,7 +621,6 @@ static void RunTransientDetector( return; } - static void UpdateDelayBuffer( const float *input, const int16_t nSamplesAvailable, @@ -649,7 +645,6 @@ static void UpdateDelayBuffer( return; } - static void UpdateSubblockEnergies( const float *input, const int16_t nSamplesAvailable, @@ -676,7 +671,6 @@ static void UpdateSubblockEnergies( return; } - /* This function should be inlined and WMOPS instrumentation takes that into account, meaning that all references are considered as local variables */ static void UpdatedAndStoreAccWindowNrg( float newWindowNrgF, diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 6fd743a99c6d516c9ff7422af91932dfabc7fc2f..3e6bafcd6356a31ce81d1a619791ac34df692245 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -128,6 +128,82 @@ static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *p } +#ifdef IVAS_FLOAT_FIXED +void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) +{ + Word16 i; + Word16 bIsAttackPresent, attackIndex; + Word16 attackRatioThreshold_1_5; + + (void) nPastSubblocks; + (void) nSubblocks; + assert( nSubblocks >= NSUBBLOCKS ); + assert( nPastSubblocks >= 2 ); + + /* attackRatioThreshold_1_5 = attackRatioThreshold * 1.5, exponent is ATTACKTHRESHOLD_E+1 */ + attackRatioThreshold_1_5 = add( shr( attackRatioThreshold, 2 ), shr( attackRatioThreshold, 1 ) ); + + move16(); + move16(); + bIsAttackPresent = FALSE; + attackIndex = 0; + /* Search for the last attack in the subblocks */ + if ( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ), + L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) ) + { + move16(); + bIsAttackPresent = TRUE; + } + + FOR( i = 0; i < NSUBBLOCKS; i++ ) + { + IF( GT_32( L_shr( pSubblockNrg[i], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[i], attackRatioThreshold ) ) ) + { + if ( i < 6 ) + { + move16(); + bIsAttackPresent = TRUE; + } + + if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + } + } + ELSE /* no attack, but set index anyway in case of strong energy increase */ + { + IF( s_and( ( (Word16) GT_32( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 1 )], attackRatioThreshold_1_5 ) ) ), + ( L_sub( L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E ), Mpy_32_16_1( pSubblockNrg[sub( i, 2 )], attackRatioThreshold_1_5 ) ) > 0 ) ) ) + { + + if ( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) ) + { + move16(); + attackIndex = i; + } + } + } + } + /* avoid post-echos on click sounds (very short transients) due to TNS aliasing */ + if ( EQ_16( attackIndex, 4 ) ) + { + move16(); + attackIndex = 7; + } + if ( EQ_16( attackIndex, 5 ) ) + { + move16(); + attackIndex = 6; + } + + move16(); + move16(); + *pAttackIndex = attackIndex; + *pbIsAttackPresent = bIsAttackPresent; +} + +#endif /** Initialize TCX transient detector. * See InitTransientDetector_fx for definition of parameters. */ @@ -410,6 +486,50 @@ void RunTransientDetection_fx( Word16 const *input, Word16 nSamplesAvailable, Tr } +#ifdef IVAS_FLOAT_FIXED +void RunTransientDetection_ivas_fx( + const Word16 *input_fx, /* i : input signal Q0 */ + const Word16 length, /* i : frame length */ + TRAN_DET_HANDLE hTranDet /* i/o: transient detection handle */ +) +{ + + Word16 filteredInput_fx[L_FRAME_MAX]; + SubblockEnergies *pSubblockEnergies = &hTranDet->subblockEnergies; + TransientDetector *pTransientDetector = &hTranDet->transientDetector; + + Word32 e0_fx, e1_fx; + + assert( ( input_fx != NULL ) && ( hTranDet != NULL ) && ( pSubblockEnergies != NULL ) && ( pTransientDetector != NULL ) ); + + /* Variable initializations */ + HighPassFilter( input_fx, length, &pSubblockEnergies->firState1, &pSubblockEnergies->firState2, filteredInput_fx ); + + /* Update subblock energies. */ + UpdateSubblockEnergies( filteredInput_fx, length, pSubblockEnergies ); + + /* Run transient detectors. */ + RunTransientDetector( pTransientDetector ); + + /* Update the delay buffer. */ + UpdateDelayBuffer( filteredInput_fx, length, &hTranDet->delayBuffer ); + + /* compute ramp up flag */ + pSubblockEnergies->ramp_up_flag = ( ( pSubblockEnergies->ramp_up_flag << 1 ) & 0x0003 ); + Word16 exp = 0, exp1 = 0; + e0_fx = dotp_fx( filteredInput_fx + length / 2, filteredInput_fx + length / 2, pSubblockEnergies->pDelayBuffer->nSubblockSize / 2, &exp ); + e0_fx = BASOP_Util_Add_Mant32Exp( 1, exp, e0_fx, exp, &exp1 ); // exponent: exp1 + e1_fx = L_sub( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], L_shr( e0_fx, 31 - exp1 ) ); // exponent: 31, Q: 0 + IF( BASOP_Util_Cmp_Mant32Exp( e0_fx, exp1, e1_fx, 31 ) > 0 ) + { + pSubblockEnergies->ramp_up_flag = s_or( pSubblockEnergies->ramp_up_flag, 0x0001 ); + move16(); + } + + return; +} + +#endif #ifdef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * isLongTermTransient_fx() diff --git a/lib_enc/updt_enc.c b/lib_enc/updt_enc.c index 088b8b49499b524ae0ec71e2862322e346cb2557..6ea9eb417a14c23a6297983b6c0507f4cb2d19f5 100644 --- a/lib_enc/updt_enc.c +++ b/lib_enc/updt_enc.c @@ -39,6 +39,10 @@ #include "cnst.h" #include "rom_com.h" #include "prot.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#include "prot_fx_enc.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -151,7 +155,163 @@ void updt_enc( * * Common updates for AMR-WB IO mode and EVS primary mode switching *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void updt_IO_switch_enc( + Encoder_State *st, /* i/o: state structure */ + const int16_t input_frame /* i : input frame length */ +) +{ + float xsp_tmp[M]; + + if ( st->last_core == AMR_WB_CORE ) /* switching to EVS primary mode */ + { + /* reset onset detection counter */ + st->tc_cnt = -1; + + /* force safety-net LSFQ in the first frames after the switching */ + st->Nb_ACELP_frames = 0; + + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode LSF(LSP) */ + mvr2r( stable_LSP, xsp_tmp, M ); + isf2lsf( st->lsf_old, st->lsf_old, xsp_tmp, M, INT_FS_12k8 ); + mvr2r( stable_LSP, xsp_tmp, M ); + isp2lsp( st->lsp_old, st->lsp_old, xsp_tmp, M ); + isp2lsp( st->lsp_old1, st->lsp_old1, xsp_tmp, M ); + + mvr2r( stable_LSP, xsp_tmp, M ); + isp2lsp( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG, xsp_tmp, M ); + if ( st->hTdCngEnc->old_enr_index >= 0 ) + { + st->hTdCngEnc->old_enr_index = min( (int16_t) ( (float) st->hTdCngEnc->old_enr_index / STEP_AMR_WB_SID * STEP_SID ), 127 ); + } + /* Perform preemphasis of the old input signal @16kHz */ + st->mem_preemph16k = 0; + preemph( st->old_inp_16k, PREEMPH_FAC_16k_FLT, L_INP_MEM, &( st->mem_preemph16k ) ); + + /* reset TD BWE buffers */ + set_f( st->hBWE_TD->old_speech_wb, 0.0f, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 16 ); + set_f( st->hBWE_TD->old_bwe_exc, 0.0f, PIT16k_MAX * 2 ); + set_f( st->hBWE_TD->old_bwe_exc_extended, 0.0f, NL_BUFF_OFFSET ); +#ifdef IVAS_FLOAT_FIXED + InitSWBencBufferStates_fx( st->hBWE_TD, NULL ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* To be removed*/ + InitSWBencBufferStates( st->hBWE_TD, NULL ); +#endif +#else + InitSWBencBufferStates( st->hBWE_TD, NULL ); +#endif + + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0; + set_f( st->hBWE_TD->decim_state1, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( st->hBWE_TD->decim_state2, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( st->hBWE_FD->old_wtda_swb, 0, L_FRAME16k ); + set_f( st->hBWE_FD->old_input_wb, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); +#ifdef IVAS_FLOAT_FIXED + wb_tbe_extras_reset_fx( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + set_f( st->hBWE_TD->mem_genSHBexc_filt_down_wb2, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( st->hBWE_TD->mem_genSHBexc_filt_down_wb3, 0.0f, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); +#endif +#else + wb_tbe_extras_reset( st->hBWE_TD->mem_genSHBexc_filt_down_wb2, st->hBWE_TD->mem_genSHBexc_filt_down_wb3 ); +#endif + if ( input_frame >= L_FRAME32k ) + { +#ifdef IVAS_FLOAT_FIXED + swb_tbe_reset_fx( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->state_syn_shbexc_fx, &( st->hBWE_TD->tbe_demph_fx ), &( st->hBWE_TD->tbe_premph_fx ), st->hBWE_TD->mem_stp_swb_fx, &( st->hBWE_TD->gain_prec_swb_fx ) ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + swb_tbe_reset( st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &( st->hBWE_TD->tbe_demph ), &( st->hBWE_TD->tbe_premph ), st->hBWE_TD->mem_stp_swb, &( st->hBWE_TD->gain_prec_swb ) ); +#endif +#else + swb_tbe_reset( st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &( st->hBWE_TD->tbe_demph ), &( st->hBWE_TD->tbe_premph ), st->hBWE_TD->mem_stp_swb, &( st->hBWE_TD->gain_prec_swb ) ); +#endif + } + + if ( input_frame == L_FRAME48k ) + { + set_f( st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); + st->hBWE_TD->fb_tbe_demph = 0; +#ifdef IVAS_FLOAT_FIXED + fb_tbe_reset_enc_fx( st->hBWE_TD->elliptic_bpf_2_48k_mem_fx, &st->hBWE_TD->prev_fb_energy_fx, st->hBWE_TD->elliptic_bpf_2_48k_mem_fx_Q, &st->hBWE_TD->prev_fb_energy_fx_Q ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fb_tbe_reset_enc( st->hBWE_TD->elliptic_bpf_2_48k_mem, &st->hBWE_TD->prev_fb_energy ); +#endif +#else + fb_tbe_reset_enc( st->hBWE_TD->elliptic_bpf_2_48k_mem, &st->hBWE_TD->prev_fb_energy ); +#endif + } + + /* reset FD BWE buffers */ + st->hBWE_FD->prev_mode = NORMAL; + + /* reset the unvoiced/audio signal improvement memories */ + st->hGSCEnc->seed_tcx = 15687; + st->use_acelp_preq = 0; + + set_f( st->hSpMusClas->finc_prev, 0.0f, ATT_NSEG ); + st->hSpMusClas->lt_finc = 0.0f; + st->hSpMusClas->last_strong_attack = 0; + set_f( st->hSpMusClas->tod_lt_Bin_E, 0.0f, TOD_NSPEC ); + set_f( st->hSpMusClas->tod_S_map_lt, 0.0f, TOD_NSPEC ); + st->hSpMusClas->tod_thr_lt = TOD_THR_MASS; + st->hSpMusClas->tod_weight = 0.0f; + st->hSpMusClas->tod_S_mass_prev = TOD_THR_MASS; + st->hSpMusClas->tod_S_mass_lt = TOD_THR_MASS; + } + else /* switching to AMR-WB IO mode */ + { + set_f( st->mem_MA, 0, M ); + + /* AMR-WB IO mode uses ISF(ISP), but EVS primary mode LSF(LSP) */ + mvr2r( stable_ISP, xsp_tmp, M ); + lsf2isf( st->lsf_old, st->lsf_old, xsp_tmp, M, INT_FS_12k8 ); + mvr2r( stable_ISP, xsp_tmp, M ); + lsp2isp( st->lsp_old, st->lsp_old, xsp_tmp, M ); + mvr2r( st->lsp_old, st->lsp_old1, M ); + lsp2isp( st->lsp_old1, st->lsp_old1, xsp_tmp, M ); + mvr2r( stable_ISP, xsp_tmp, M ); + lsp2isp( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG, xsp_tmp, M ); + if ( st->hTdCngEnc->old_enr_index >= 0 ) + { + st->hTdCngEnc->old_enr_index = min( (int16_t) ( (float) st->hTdCngEnc->old_enr_index / STEP_SID * STEP_AMR_WB_SID ), 63 ); + } + + /* gain quantization memory */ + set_f( st->hAmrwb_IO->past_qua_en, -14.0f, GAIN_PRED_ORDER ); + + /* reset VBR signaling */ + if ( st->Opt_SC_VBR ) + { + st->hSC_VBR->ppp_mode = 0; + st->hSC_VBR->nelp_mode = 0; + } + + /* reset the unvoiced/audio signal improvement memories */ + st->hGSCEnc->seed_tcx = 15687; + } + + if ( st->hTdCngEnc != NULL ) + { + /* Force SID in case of AMR-WB IO mode/EVS primary mode switching */ + st->hDtxEnc->cnt_SID = 0; + st->hDtxEnc->cng_cnt = 0; + st->hTdCngEnc->ho_hist_size = 0; + st->hTdCngEnc->burst_ho_cnt = 0; + } + + /* LP memories */ + mvr2r( UVWB_Ave, st->mem_AR, M ); + + /* FEC - update adaptive LSF mean vector */ + mvr2r( st->lsf_old, st->lsfoldbfi0, M ); + mvr2r( st->lsf_old, st->lsfoldbfi1, M ); + mvr2r( st->lsf_old, st->lsf_adaptive_mean, M ); + + return; +} +#else void updt_IO_switch_enc( Encoder_State *st, /* i/o: state structure */ const int16_t input_frame /* i : input frame length */ @@ -278,7 +438,7 @@ void updt_IO_switch_enc( return; } - +#endif /*-------------------------------------------------------------------* * updt_enc_common() diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 472e70a26e8f7edfd4361ba6d0d56f22bd1c1734..21c49189e78f281de440d196532e73da5b481157 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -121,7 +121,7 @@ typedef struct parambin_rend_config_data *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_f[], const Word16 nchan_transport, const Word16 subframe ); +static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_f[] /*Q11*/, const Word16 nchan_transport, const Word16 subframe ); #else static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t nchan_transport, const int16_t subframe ); @@ -129,11 +129,11 @@ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, #endif #ifdef IVAS_FLOAT_FIXED -static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX], Word32 decIm[][CLDFB_NO_CHANNELS_MAX] ); +static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME] /*q_inp*/[CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, Word32 decRe[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 decIm[] /*q_inp*/[CLDFB_NO_CHANNELS_MAX] ); #endif #ifdef IVAS_FLOAT_FIXED -static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 Rmat_fx[3][3], const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); +static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q*/, Word32 Rmat_fx[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, Word16 q ); #else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); @@ -141,13 +141,13 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN #endif #ifdef IVAS_FLOAT_FIXED -static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3], const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, Word32 Rmat[3][3] /*Q30*/, const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); -static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[], Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); +static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], Word32 *output_fx[] /*q_out*/, Word16 *q_out, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, const Word16 q_inp, const Word16 max_band_decorr, const Word16 numInChannels, const Word16 processReverb, const Word16 subframe, const Word16 q_mat ); -static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word16 q_inp, const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] ); +static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /*q_inp*/, Word16 q_inp, const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] /*Q30*/ ); -static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] ); +static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nBins, const Word16 nSlots, Word32 Rmat[3][3] /*Q30*/ ); #endif #ifndef IVAS_FLOAT_FIXED static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe ); @@ -170,7 +170,7 @@ static void hrtfShGetHrtf_fx( const Word16 bin, const Word16 aziDeg, const Word1 static void hrtfShGetHrtf( const int16_t bin, const int16_t aziDeg, const int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t useCachedValue ); #endif #ifdef IVAS_FLOAT_FIXED -static void getDirectPartGains_fx( const Word16 bin, Word16 aziDeg, Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, const UWord8 renderStereoOutputInsteadOfBinaural, Word32 Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 isHeadtracked ); +static void getDirectPartGains_fx( const Word16 bin, Word16 aziDeg, Word16 eleDeg, Word32 *lRealp, Word32 *lImagp, Word32 *rRealp, Word32 *rImagp, const UWord8 renderStereoOutputInsteadOfBinaural, Word32 Rmat[3][3] /*Q30*/, PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 isHeadtracked ); #else static void getDirectPartGains( const int16_t bin, int16_t aziDeg, int16_t eleDeg, float *lRealp, float *lImagp, float *rRealp, float *rImagp, const uint8_t stereoMode, float Rmat[3][3], PARAMBIN_HRTF_GAIN_CACHE *gainCache, const int16_t isHeadtracked ); @@ -179,16 +179,16 @@ static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Ai static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); #endif #ifdef IVAS_FLOAT_FIXED -static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[], const Word16 subframe ); +static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, Word32 *output_fx[] /*Q11*/, const Word16 subframe ); #else static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe ); #endif #ifdef IVAS_FLOAT_FIXED -static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx, Word32 Ein2_fx, Word16 q_Ein, Word32 CinRe_fx, Word32 CinIm_fx, Word16 q_Cin, Word32 Eout1_fx, Word32 Eout2_fx, Word16 q_Eout, Word32 CoutRe_fx, Word32 CoutIm_fx, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_M, const Word16 regularizationFactor_fx ); +static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx /*q_Ein*/, Word32 Ein2_fx /*q_Ein*/, Word16 q_Ein, Word32 CinRe_fx /*q_Cin*/, Word32 CinIm_fx /*q_Cin*/, Word16 q_Cin, Word32 Eout1_fx /*q_Eout*/, Word32 Eout2_fx /*q_Eout*/, Word16 q_Eout, Word32 CoutRe_fx /*q_Cout*/, Word32 CoutIm_fx /*q_Cout*/, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*Q31*/, Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word16 *q_M, const Word16 regularizationFactor_fx /*Q14*/ ); -static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_out ); +static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); -static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS], Word16 *q_out ); +static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); #endif // 1 /*------------------------------------------------------------------------- @@ -460,10 +460,10 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( tmp_e = 0; move16(); } - tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q30*/ - tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); //*binCenterFreq_fx * EVS_PI / 550.0f*/ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ - hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); + tmpFloat_fx = s_max( 0, sub( shl_sat( 1, sub( 15, tmp_e ) ), tmp ) ) /*max( 0.0f, 1.0f - binCenterFreq / 2700.0f )*/; /*Q15-tmp_e*/ + tmp2 = extract_l( Mult_32_32( binCenterFreq_fx, 1952258 /*=2^31*180/(550)/360*/ ) % 32767 ); /* Q15 */ //*binCenterFreq_fx * EVS_PI / 550.0f*/ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( L_mult0( divide3232( tmpFloat_fx, Mult_32_16( binCenterFreq_fx, 187 /*2^15*pi/550*/ ) ), getSineWord16R2( tmp2 ) ), tmp_e ); /*tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );*/ /* Q30 */ + hDiracDecBin->diffuseFieldCoherence_fx[bin] = L_shl( hDiracDecBin->diffuseFieldCoherence_fx[bin], 1 ); /* Q31 */ move32(); move32(); } @@ -562,7 +562,7 @@ ivas_error ivas_dirac_dec_init_binaural_data_fx( } } - hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + hDiracDecBin->reqularizationFactor_fx = configure_reqularization_factor_fx( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); /* Q14 */ move16(); st_ivas->hDiracDecBin = hDiracDecBin; @@ -689,13 +689,13 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs_fx( { FOR( j = 0; j < HRTF_SH_CHANNELS; j++ ) { - Copy( hrtfShCoeffsRe_fx[i][j], hrtfParambin->hrtfShCoeffsRe_fx[i][j], HRTF_NUM_BINS ); - Copy( hrtfShCoeffsIm_fx[i][j], hrtfParambin->hrtfShCoeffsIm_fx[i][j], HRTF_NUM_BINS ); + Copy( hrtfShCoeffsRe_fx[i][j], hrtfParambin->hrtfShCoeffsRe_fx[i][j], HRTF_NUM_BINS ); /*Q14*/ + Copy( hrtfShCoeffsIm_fx[i][j], hrtfParambin->hrtfShCoeffsIm_fx[i][j], HRTF_NUM_BINS ); /*Q14*/ } } - Copy32( parametricReverberationTimes_fx, hrtfParambin->parametricReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX ); - Copy32( parametricReverberationEneCorrections_fx, hrtfParambin->parametricReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX ); - Copy32( parametricEarlyPartEneCorrection_fx, hrtfParambin->parametricEarlyPartEneCorrection_fx, CLDFB_NO_CHANNELS_MAX ); + Copy32( parametricReverberationTimes_fx, hrtfParambin->parametricReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX ); /*Q31*/ + Copy32( parametricReverberationEneCorrections_fx, hrtfParambin->parametricReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX ); /*Q31*/ + Copy32( parametricEarlyPartEneCorrection_fx, hrtfParambin->parametricEarlyPartEneCorrection_fx, CLDFB_NO_CHANNELS_MAX ); /*Q28*/ *hHrtfParambin = hrtfParambin; } @@ -830,7 +830,7 @@ void ivas_dirac_dec_binaural_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ const Word16 nchan_transport, /* i : number of transport channels */ - Word32 *output_f[] /* o : rendered time signal */ + Word32 *output_f[] /* o : rendered time signal, Q11 */ ) { Word16 slots_to_render, first_sf, last_sf, subframe_idx; @@ -908,9 +908,9 @@ void ivas_dirac_dec_binaural_render_fx( *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED void ivas_dirac_dec_binaural_sba_gain_fx( - Word32 *output[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ - const Word16 output_frame /* i : output frame length */ + Word32 *output[], /* i/o: synthesized core-coder transport channels/DirAC output, inp Qx, out Qx-1 */ + const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ + const Word16 output_frame /* i : output frame length */ ) { Word16 n; @@ -918,18 +918,18 @@ void ivas_dirac_dec_binaural_sba_gain_fx( IF( EQ_16( nchan_remapped, 1 ) ) { - gain = 23681; + gain = 23681; /*Q14*/ move16(); } ELSE { - gain = 22376; + gain = 22376; /*Q14*/ move16(); } FOR( n = 0; n < nchan_remapped; n++ ) { - v_multc_fixed_16( output[n], gain, output[n], output_frame ); + v_multc_fixed_16( output[n], gain, output[n], output_frame ); /* Qx to Qx-1*/ } return; @@ -1214,7 +1214,7 @@ static void ivas_dirac_dec_binaural_internal( static void ivas_dirac_dec_binaural_internal_fx( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - Word32 *output_fx[], + Word32 *output_fx[], /*Q11*/ const Word16 nchan_transport, const Word16 subframe ) { @@ -1275,7 +1275,7 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); IF( st_ivas->hMasa != NULL ) { - config_data.qualityBasedSmFactor_fx = L_deposit_h( st_ivas->hMasa->data.dir_decode_quality_fx ); + config_data.qualityBasedSmFactor_fx = L_deposit_h( st_ivas->hMasa->data.dir_decode_quality_fx ); // Q31 } ELSE { @@ -1486,12 +1486,12 @@ static void ivas_dirac_dec_binaural_internal_fx( move16(); FOR( Word16 idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, Q31 - Q22 ); + Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, Q31 - Q22 ); /*Q31 to Q22*/ } ivas_sba_prototype_renderer_fx( st_ivas, Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, q_cldfb, subframe ); FOR( Word16 idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, Q22 - Q31 ); + Scale_sig32( st_ivas->hSpar->hFbMixer->pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[idx], IVAS_MAX_NUM_FB_BANDS, Q22 - Q31 ); /*Q31 to Q22*/ } } @@ -1501,8 +1501,8 @@ static void ivas_dirac_dec_binaural_internal_fx( { FOR( slot = 0; slot < 4; slot++ ) { - scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); - scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); + scale_sig32( Cldfb_RealBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 + scale_sig32( Cldfb_ImagBuffer_in_fx[cha][slot], 60, sub( q_inp, q_cldfb[cha][slot] ) ); // Q6 } } @@ -1553,8 +1553,8 @@ static void ivas_dirac_dec_binaural_internal_fx( { FOR( Word16 k = 0; k < 60; k++ ) { - Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); - Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); + Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q + Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q move32(); move32(); } @@ -1621,21 +1621,21 @@ static void ivas_dirac_dec_binaural_internal_fx( { FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) { - Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); - Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); - Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); - Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); - Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); - Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat } FOR( slot = 0; slot < nchanSeparateChannels; slot++ ) { - Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); - Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot + BINAURAL_CHANNELS], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat } } hDiracDecBin->q_processMtx = q_mat; @@ -1730,11 +1730,11 @@ static void ivas_dirac_dec_decorrelate_slot_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const Word16 num_freq_bands, const Word16 slot, - Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word32 inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ Word16 q_inp, - Word32 decRe[][CLDFB_NO_CHANNELS_MAX], - Word32 decIm[][CLDFB_NO_CHANNELS_MAX] ) + Word32 decRe[][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word32 decIm[][CLDFB_NO_CHANNELS_MAX] /*q_inp*/ ) { Word16 offset, ch, bin; Word32 onset_filter_fx[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ @@ -1751,8 +1751,8 @@ static void ivas_dirac_dec_decorrelate_slot_fx( offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); FOR( bin = 0; bin < num_freq_bands; bin++ ) { - protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )] = inRe[ch][slot][bin]; - protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )] = inIm[ch][slot][bin]; + protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )] = inRe[ch][slot][bin]; // q_protoFrame + protoFrame_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )] = inIm[ch][slot][bin]; // q_protoFrame move32(); move32(); } @@ -1780,8 +1780,8 @@ static void ivas_dirac_dec_decorrelate_slot_fx( offset = imult1616( imult1616( num_freq_bands, BINAURAL_CHANNELS ), ch ); FOR( bin = 0; bin < num_freq_bands; bin++ ) { - decRe[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )]; - decIm[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )]; + decRe[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), offset )]; // q_inp + decIm[ch][bin] = decorrelatedFrameInterleaved_fx[add( imult1616( bin, BINAURAL_CHANNELS ), add( offset, 1 ) )]; // q_inp move32(); move32(); } @@ -2264,9 +2264,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, - Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 Rmat_fx[3][3], + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q*/ + Word32 Rmat_fx[3][3], /*Q30*/ const Word16 subframe, const Word16 isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData, @@ -2301,9 +2301,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric move32(); nchan_transport = hConfig->nchan_transport; move16(); - qualityBasedSmFactor_fx = hConfig->qualityBasedSmFactor_fx; + qualityBasedSmFactor_fx = hConfig->qualityBasedSmFactor_fx; /*Q31*/ move32(); - qualityBasedSmFactor_fx = Mpy_32_32( qualityBasedSmFactor_fx, qualityBasedSmFactor_fx ); + qualityBasedSmFactor_fx = Mpy_32_32( qualityBasedSmFactor_fx, qualityBasedSmFactor_fx ); /*Q31*/ nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ move16(); @@ -2561,11 +2561,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric IF( isIsmDirection ) { /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ - diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, L_shr( ratio_fx, 1 ) ); + diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, L_shr( ratio_fx, 1 ) ); /*Q30*/ } ELSE { - diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); + diffusenessValForDecorrelationReduction_fx = L_sub( diffusenessValForDecorrelationReduction_fx, ratio_fx ); /*Q30*/ } IF( separateCenterChannelRendering ) @@ -2579,7 +2579,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric azi_scaled = i_mult( aziDeg, 91 ); ele_scaled = i_mult( eleDeg, 91 ); - doaVectorX_fx = L_mult( getCosWord16R2( azi_scaled ), getCosWord16R2( ele_scaled ) ); + doaVectorX_fx = L_mult( getCosWord16R2( azi_scaled ), getCosWord16R2( ele_scaled ) ); /*Q31*/ num = Sqrt32( L_sub( ONE_IN_Q31, Mpy_32_32( doaVectorX_fx, doaVectorX_fx ) ), &e ); den = doaVectorX_fx; move32(); @@ -2686,8 +2686,8 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ IF( LT_16( spreadCoh_fx, 16384 ) ) { - w1_fx = sub( 32767, shl( spreadCoh_fx, 1 ) ); - w2_fx = shl( spreadCoh_fx, 1 ); + w1_fx = sub( 32767, shl( spreadCoh_fx, 1 ) ); /*Q15*/ + w2_fx = shl( spreadCoh_fx, 1 ); /*Q15*/ w3_fx = 0; move16(); } @@ -2695,8 +2695,8 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric { w1_fx = 0; move16(); - w2_fx = shl( sub( 32767, spreadCoh_fx ), 1 ); - w3_fx = shl( sub( spreadCoh_fx, 16384 ), 1 ); + w2_fx = shl( sub( 32767, spreadCoh_fx ), 1 ); /*Q15*/ + w3_fx = shl( sub( spreadCoh_fx, 16384 ), 1 ); /*Q15*/ } test(); @@ -2862,7 +2862,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric Word16 num_e, den_e; Word32 num, den; num = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEne_fx[0][bin], hDiracDecBin->ChEne_e[0][bin], hDiracDecBin->ChEne_fx[1][bin], hDiracDecBin->ChEne_e[1][bin], &num_e ); - num = Mpy_32_32( num, IIReneLimiterFactor_fx ); + num = Mpy_32_32( num, IIReneLimiterFactor_fx ); /*Q = (31 - num_e + 26 - 31) = (26 - num_e)*/ den_e = 0; move16(); den = BASOP_Util_Add_Mant32Exp( hDiracDecBin->ChEnePrev_fx[0][bin], hDiracDecBin->ChEnePrev_e[0][bin], hDiracDecBin->ChEnePrev_fx[1][bin], hDiracDecBin->ChEnePrev_e[1][bin], &den_e ); @@ -2871,12 +2871,12 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric e = add( sub( num_e, den_e ), add( 5, e ) ); IF( L_shr_sat( IIReneLimiter_fx, sub( 31, e ) ) > 0 ) { - IIReneLimiter_fx = ONE_IN_Q31; + IIReneLimiter_fx = ONE_IN_Q31; /*Q31*/ move32(); } ELSE { - IIReneLimiter_fx = L_shl( IIReneLimiter_fx, e ); + IIReneLimiter_fx = L_shl( IIReneLimiter_fx, e ); /*Q31*/ } hDiracDecBin->ChCrossRe_fx[bin] = Mpy_32_32( hDiracDecBin->ChCrossRe_fx[bin], qualityBasedSmFactor_fx ); @@ -3184,7 +3184,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const Word16 max_band_decorr, - Word32 Rmat[3][3], + Word32 Rmat[3][3], /*Q30*/ const Word16 subframe, const Word16 isHeadtracked, const Word16 nchanSeparateChannels, @@ -3591,24 +3591,24 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxRe_fx[chA][chB][bin]; + hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxRe_fx[chA][chB][bin]; // q_processMtx_bin move16(); - hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxIm_fx[chA][chB][bin]; + hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxIm_fx[chA][chB][bin]; // q_processMtx_bin move16(); - hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecRe_fx[chA][chB][bin]; + hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecRe_fx[chA][chB][bin]; // q_processMtxDec_bin move16(); - hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecIm_fx[chA][chB][bin]; + hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = hDiracDecBin->processMtxDecIm_fx[chA][chB][bin]; // q_processMtxDec_bin move16(); - hDiracDecBin->processMtxRe_fx[chA][chB][bin] = extract_h( Mre_fx[chA][chB] ); + hDiracDecBin->processMtxRe_fx[chA][chB][bin] = extract_h( Mre_fx[chA][chB] ); // q_M -16 move16(); - hDiracDecBin->processMtxIm_fx[chA][chB][bin] = extract_h( Mim_fx[chA][chB] ); + hDiracDecBin->processMtxIm_fx[chA][chB][bin] = extract_h( Mim_fx[chA][chB] ); // q_M -16 move16(); - hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = extract_h( MdecRe_fx[chA][chB] ); + hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = extract_h( MdecRe_fx[chA][chB] ); // q_Mdec -16 move16(); - hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = extract_h( MdecIm_fx[chA][chB] ); + hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = extract_h( MdecIm_fx[chA][chB] ); // q_Mdec -16 move16(); } } @@ -3736,34 +3736,34 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - hDiracDecBin->processMtxRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); + hDiracDecBin->processMtxRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx move16(); - hDiracDecBin->processMtxIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); + hDiracDecBin->processMtxIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][chB][bin], sub( q_processMtx[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx move16(); - hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); + hDiracDecBin->processMtxRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev move16(); - hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); + hDiracDecBin->processMtxImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][chB][bin], sub( q_processMtxPrev[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev move16(); - hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRe_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); + hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRe_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); // hDiracDecBin->q_processMtxDec move16(); - hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecIm_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); + hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecIm_fx[chA][chB][bin], sub( q_processMtxDec[bin], hDiracDecBin->q_processMtxDec ) ); // hDiracDecBin->q_processMtxDec move16(); - hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); + hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); // hDiracDecBin->q_processMtxDecPrev move16(); - hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); + hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] = shr( hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin], sub( q_processMtxDecPrev[bin], hDiracDecBin->q_processMtxDecPrev ) ); // hDiracDecBin->q_processMtxDecPrev move16(); } IF( separateCenterChannelRendering ) { FOR( chB = 0; chB < nchanSeparateChannels; chB++ ) { - hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); + hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRe_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx move16(); - hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); + hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxIm_fx[chA][add( chB, 2 )][bin], sub( q_processMtx_SCCR[bin], hDiracDecBin->q_processMtx ) ); // hDiracDecBin->q_processMtx move16(); - hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); + hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxRePrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev move16(); - hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); + hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin] = shr( hDiracDecBin->processMtxImPrev_fx[chA][add( chB, 2 )][bin], sub( q_processMtxPrev_SCCR[bin], hDiracDecBin->q_processMtxPrev ) ); // hDiracDecBin->q_processMtxPrev move16(); } } @@ -3779,10 +3779,10 @@ static void ivas_dirac_dec_binaural_process_output_fx( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], - Word32 *output_fx[], + Word32 *output_fx[], /*q_out*/ Word16 *q_out, - Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_input*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_input*/ const Word16 q_input, const Word16 max_band_decorr, const Word16 numInChannels, @@ -3857,13 +3857,13 @@ static void ivas_dirac_dec_binaural_process_output_fx( FOR( Word16 j = 0; j < nSlots; j++ ) { - scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); - scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); + scale_sig32( inRe_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ + scale_sig32( inIm_fx[i][j], nBins, q_inp_mix ); /*q_input + q_inp_mix*/ test(); IF( processReverb && LT_16( i, 2 ) ) { - scale_sig32( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); - scale_sig32( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); + scale_sig32( reverbRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ + scale_sig32( reverbIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( add( q_inp_mix, q_mat ), 15 ) ); /*q_inp_mix+q_mat-15*/ } } } @@ -3890,11 +3890,11 @@ static void ivas_dirac_dec_binaural_process_output_fx( { IF( NE_16( slot, sub( nSlots, 1 ) ) ) { - interpVal_fx = add( interpVal_fx, slot_fx[nSlots - 1] ); + interpVal_fx = add( interpVal_fx, slot_fx[nSlots - 1] ); /*Q15*/ } ELSE { - interpVal_fx = 32767; + interpVal_fx = 32767; /*Q15*/ move16(); } test(); @@ -3980,7 +3980,7 @@ static void ivas_dirac_dec_binaural_process_output_fx( IF( LT_16( bin, max_band_decorr ) && LT_16( chB, 2 ) ) { #ifdef IVAS_ENH32_CADENCE_CHANGES - gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] ) ); + gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecRePrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecRe_fx[chA][chB][bin] ) ); // Q11 // interpVal * hDiracDecBin->processMtxDecRe[chA][chB][bin]; outSlotRe_fx[bin] = Madd_32_16( outSlotRe_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result @@ -3988,9 +3988,9 @@ static void ivas_dirac_dec_binaural_process_output_fx( move32(); - gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] ) ); - outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result - outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result + gain = add( mult( sub( 32767, interpVal_fx ), hDiracDecBin->processMtxDecImPrev_fx[chA][chB][bin] ), mult( interpVal_fx, hDiracDecBin->processMtxDecIm_fx[chA][chB][bin] ) ); // Q11 + outSlotRe_fx[bin] = Msub_32_16( outSlotRe_fx[bin], decSlotImPointer_fx[bin], gain ); // q_inp_mix-4//q_result + outSlotIm_fx[bin] = Madd_32_16( outSlotIm_fx[bin], decSlotRePointer_fx[bin], gain ); // q_inp_mix-4//q_result move32(); move32(); @@ -4166,12 +4166,12 @@ static void ivas_dirac_dec_binaural_process_output( #ifdef IVAS_FLOAT_FIXED static void adaptTransportSignalsHeadtracked_fx( COMBINED_ORIENTATION_HANDLE hHeadTrackData, - Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*q_inp*/ Word16 q_inp, const Word16 nBins, const Word16 nSlots, - Word32 Rmat[3][3] ) + Word32 Rmat[3][3] /*Q30*/ ) { Word16 slot, ch, bin, louderCh; Word32 mono_factor_ILD, mono_factor; @@ -4247,7 +4247,7 @@ static void adaptTransportSignalsHeadtracked_fx( move32(); } } - hHeadTrackData->chEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->chEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); + hHeadTrackData->chEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->chEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // q_chEneIIR move32(); temp = Mpy_32_16_1( ch_nrg[ch], sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) ); IF( LT_16( hHeadTrackData->q_chEneIIR, q_temp ) ) @@ -4296,9 +4296,9 @@ static void adaptTransportSignalsHeadtracked_fx( move16(); /* Determine ILD-based mono factor */ - mono_factor_ILD = Mpy_32_16_1( L_sub( ILD, ONE_IN_Q21 ), 10911 ); // Q23 + mono_factor_ILD = Mpy_32_16_1( L_sub( ILD, ONE_IN_Q21 ), 10911 ); // Q21 - mono_factor_ILD = L_max( 0, L_min( ONE_IN_Q21, mono_factor_ILD ) ); + mono_factor_ILD = L_max( 0, L_min( ONE_IN_Q21, mono_factor_ILD ) ); // Q21 IF( EQ_32( mono_factor_ILD, ONE_IN_Q21 ) ) { @@ -4330,12 +4330,12 @@ static void adaptTransportSignalsHeadtracked_fx( inIm_fx[ch][slot][bin] = L_add( ( Mpy_32_32( mono_factor, L_add( inIm_fx[0][slot][bin], inIm_fx[1][slot][bin] ) ) ), ( Mpy_32_32( L_sub( ONE_IN_Q31, mono_factor ), inIm_fx[ch][slot][bin] ) ) ); move32(); move32(); - re = L_shl( inRe_fx[ch][slot][bin], shift ); - img = L_shl( inIm_fx[ch][slot][bin], shift ); + re = L_shl( inRe_fx[ch][slot][bin], shift ); // q_inp +shift + img = L_shl( inIm_fx[ch][slot][bin], shift ); // q_inp +shift band_nrg = L_add( band_nrg, ( L_add( Mpy_32_32( re, re ), Mpy_32_32( img, img ) ) ) ); // 2(q_inp +shift) -31 } } - hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); + hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // q_procChEneIIR move32(); temp = Mpy_32_16_1( band_nrg, sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) ); @@ -4352,7 +4352,7 @@ static void adaptTransportSignalsHeadtracked_fx( ELSE { /* processed signal is input. use the original channel, so no need to compute new signals or signal energy */ - hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); + hHeadTrackData->procChEneIIR_fx[ch][band_idx] = Mpy_32_16_1( hHeadTrackData->procChEneIIR_fx[ch][band_idx], ADAPT_HTPROTO_IIR_FAC_FX ); // q_procChEneIIR move32(); temp = Mpy_32_16_1( ch_nrg[ch], sub( 32767, ADAPT_HTPROTO_IIR_FAC_FX ) ); @@ -4544,7 +4544,7 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx( Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const Word16 nBins, const Word16 nSlots, - Word32 Rmat_fx[3][3] ) + Word32 Rmat_fx[3][3] /*Q30*/ ) { Word16 slot, bin, ch; Word32 tmpVal; @@ -4893,16 +4893,16 @@ static void eig2x2( } #else static void eig2x2_fx( - const Word32 E1_fx, - const Word32 E2_fx, + const Word32 E1_fx, /*q_E*/ + const Word32 E2_fx, /*q_E*/ Word16 q_E, - const Word32 Cre_fx, - const Word32 Cim_fx, + const Word32 Cre_fx, /*q_C*/ + const Word32 Cim_fx, /*q_C*/ Word16 q_C, - Word32 Ure_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Uim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Ure_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_U*/ + Word32 Uim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_U*/ Word16 *q_U, - Word32 D_fx[BINAURAL_CHANNELS], + Word32 D_fx[BINAURAL_CHANNELS], /*q_D*/ Word16 *q_D ) { Word16 chA, chB, ch; @@ -5130,7 +5130,7 @@ static void eig2x2_fx( tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); - normVal_fx = Sqrt32( tmp2, &exp ); + normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); IF( LT_16( q_tmp1, q_c ) ) @@ -5199,7 +5199,7 @@ static void eig2x2_fx( tmp2 = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, tmp3, &exp ); exp = sub( exp, sub( Q30, sub( 31, exp_tmp3 ) ) ); - normVal_fx = Sqrt32( tmp2, &exp ); + normVal_fx = Sqrt32( tmp2, &exp ); // q_tmp2 q_tmp2 = sub( 31, exp ); IF( LT_16( q_tmp1, q_c ) ) @@ -5287,13 +5287,13 @@ static void matrixDiagMul( } #else static void matrixDiagMul_fx( - Word32 reIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 imIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 reIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_In*/ + Word32 imIn_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_In*/ Word16 q_In, - const Word32 D_fx[BINAURAL_CHANNELS], + const Word32 D_fx[BINAURAL_CHANNELS], /*q_D*/ Word16 q_D, - Word32 reOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 imOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 reOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_Out*/ + Word32 imOut_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_Out*/ Word16 *q_Out ) { Word16 chA, chB; @@ -5349,14 +5349,14 @@ static void matrixMul( } #else static void matrixMul_fx( - Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word16 *q_A, - Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ + Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, - Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) { Word16 chA, chB; @@ -5533,14 +5533,14 @@ static void matrixTransp1Mul( } #else static void matrixTransp1Mul_fx( - Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word16 q_A, - Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ + Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 q_B, - Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) { Word16 chA, chB; @@ -5658,14 +5658,14 @@ static void matrixTransp2Mul( } #else static void matrixTransp2Mul_fx( - Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word16 *q_A, - Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ + Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ Word16 *q_B, - Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) { Word16 chA, chB; @@ -5785,14 +5785,14 @@ static void matrixTransp2Mul_fx( #ifdef IVAS_FLOAT_FIXED static void chol2x2_fx( - const Word32 E1, - const Word32 E2, + const Word32 E1, /*q_E*/ + const Word32 E2, /*q_E*/ Word16 q_E, - const Word32 Cre, - const Word32 Cim, + const Word32 Cre, /*q_C*/ + const Word32 Cim, /*q_C*/ Word16 q_C, - Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) { Word16 chA, chB; @@ -5884,13 +5884,13 @@ static void chol2x2_fx( IF( LT_16( q_e, q_tmp ) ) { - sqrtVal_fx = L_sub( e2, L_shr( temp, sub( q_tmp, q_e ) ) ); + sqrtVal_fx = L_sub( e2, L_shr( temp, sub( q_tmp, q_e ) ) ); ////q_tmp q_tmp = q_e; move16(); } ELSE { - sqrtVal_fx = L_sub( L_shr( e2, sub( q_e, q_tmp ) ), temp ); + sqrtVal_fx = L_sub( L_shr( e2, sub( q_e, q_tmp ) ), temp ); // q_tmp } exp = sub( 31, q_tmp ); @@ -5969,13 +5969,13 @@ static void chol2x2_fx( IF( LT_16( q_e, q_tmp ) ) { - sqrtVal_fx = L_sub( e1, L_shr( temp, sub( q_tmp, q_e ) ) ); + sqrtVal_fx = L_sub( e1, L_shr( temp, sub( q_tmp, q_e ) ) ); ////q_tmp q_tmp = q_e; move16(); } ELSE { - sqrtVal_fx = L_sub( L_shr( e1, sub( q_e, q_tmp ) ), temp ); + sqrtVal_fx = L_sub( L_shr( e1, sub( q_e, q_tmp ) ), temp ); ////q_tmp } exp = sub( 31, q_tmp ); @@ -6168,23 +6168,23 @@ static void formulate2x2MixingMatrix( #else static void formulate2x2MixingMatrix_fx( - Word32 Ein1_fx, - Word32 Ein2_fx, + Word32 Ein1_fx, /*q_Ein*/ + Word32 Ein2_fx, /*q_Ein*/ Word16 q_Ein, - Word32 CinRe_fx, - Word32 CinIm_fx, + Word32 CinRe_fx, /*q_Cin*/ + Word32 CinIm_fx, /*q_Cin*/ Word16 q_Cin, - Word32 Eout1_fx, - Word32 Eout2_fx, + Word32 Eout1_fx, /*q_Eout*/ + Word32 Eout2_fx, /*q_Eout*/ Word16 q_Eout, - Word32 CoutRe_fx, - Word32 CoutIm_fx, + Word32 CoutRe_fx, /*q_Cout*/ + Word32 CoutIm_fx, /*q_Cout*/ Word16 q_Cout, - Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], // Q31 - Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], // Q31 + Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_M*/ + Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_M*/ Word16 *q_M, - const Word16 regularizationFactor_fx ) + const Word16 regularizationFactor_fx /*Q14*/ ) { /* This function implements a 2x2 solution for an optimized spatial audio rendering algorithm @@ -6257,11 +6257,11 @@ static void formulate2x2MixingMatrix_fx( tmp = L_max( E_out1, E_out2 ); IF( LT_16( q_maxEne, q_eout ) ) { - maxEne_fx = L_max( maxEne_fx, L_shr( tmp, sub( q_eout, q_maxEne ) ) ); + maxEne_fx = L_max( maxEne_fx, L_shr( tmp, sub( q_eout, q_maxEne ) ) ); // q_maxEne } ELSE { - maxEne_fx = L_max( L_shr( maxEne_fx, sub( q_maxEne, q_eout ) ), tmp ); + maxEne_fx = L_max( L_shr( maxEne_fx, sub( q_maxEne, q_eout ) ), tmp ); // q_maxEne q_maxEne = q_eout; move16(); } @@ -6311,9 +6311,9 @@ static void formulate2x2MixingMatrix_fx( Sx_fx[1] = Sqrt32( Sx_fx[1], &exp1 ); move32(); q_Sx = sub( 31, s_max( exp, exp1 ) ); - Sx_fx[0] = L_shr( Sx_fx[0], sub( sub( 31, exp ), q_Sx ) ); + Sx_fx[0] = L_shr( Sx_fx[0], sub( sub( 31, exp ), q_Sx ) ); // q_Sx move32(); - Sx_fx[1] = L_shr( Sx_fx[1], sub( sub( 31, exp1 ), q_Sx ) ); + Sx_fx[1] = L_shr( Sx_fx[1], sub( sub( 31, exp1 ), q_Sx ) ); // q_Sx move32(); matrixDiagMul_fx( Uxre_fx, Uxim_fx, q_Ux, Sx_fx, q_Sx, Kxre_fx, Kxim_fx, &q_Kx ); @@ -6340,11 +6340,11 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out1, temp, &exp ); exp = sub( exp, sub( q_eout, sub( 31, exp_temp ) ) ); } - Ghat_fx[0] = Sqrt32( temp, &exp ); + Ghat_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); temp = Mpy_32_32( E_in1, 2147484 ); // 2147484 = 0.001f in Q31 - temp = L_max( temp, E_in2 ); + temp = L_max( temp, E_in2 ); // q_ein IF( temp == 0 ) { BASOP_Util_Divide3232_Scale_cadence( E_out2, 4611686, &exp1 ); // 4611686 = Q62 @@ -6357,14 +6357,14 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( E_out2, temp, &exp1 ); exp1 = sub( exp1, sub( q_eout, sub( 31, exp_temp ) ) ); } - Ghat_fx[1] = Sqrt32( temp, &exp1 ); + Ghat_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 move32(); q_Ghat = sub( 31, s_max( exp, exp1 ) ); - Ghat_fx[0] = L_shr( Ghat_fx[0], sub( sub( 31, exp ), q_Ghat ) ); + Ghat_fx[0] = L_shr( Ghat_fx[0], sub( sub( 31, exp ), q_Ghat ) ); // q_Ghat move32(); - Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); + Ghat_fx[1] = L_shr( Ghat_fx[1], sub( sub( 31, exp1 ), q_Ghat ) ); // q_Ghat move32(); /* Matrix multiplication, tmp = Ky' * G_hat * Q */ @@ -6414,7 +6414,7 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[0], &exp ); exp = sub( exp, sub( Q30, q_D ) ); } - div_fx[0] = Sqrt32( temp, &exp ); + div_fx[0] = Sqrt32( temp, &exp ); // Q = 31 - exp move32(); IF( D_fx[1] == 0 ) @@ -6427,22 +6427,22 @@ static void formulate2x2MixingMatrix_fx( temp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, D_fx[1], &exp1 ); exp1 = sub( exp1, sub( Q30, q_D ) ); } - div_fx[1] = Sqrt32( temp, &exp1 ); + div_fx[1] = Sqrt32( temp, &exp1 ); // Q = 31 - exp1 move32(); q_div = sub( 31, s_max( exp, exp1 ) ); - div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); + div_fx[0] = L_shr( div_fx[0], sub( sub( 31, exp ), q_div ) ); // q_div move32(); - div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); + div_fx[1] = L_shr( div_fx[1], sub( sub( 31, exp1 ), q_div ) ); // q_div move32(); // 1310720000 = 10,000.0f in Q17 IF( LT_16( q_div, Q17 ) ) { - div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); + div_fx[0] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[0] ); // q_div move32(); - div_fx[1] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[1] ); + div_fx[1] = L_min( L_shr( 1310720000, sub( Q17, q_div ) ), div_fx[1] ); // q_div move32(); } ELSE @@ -6558,8 +6558,8 @@ static void formulate2x2MixingMatrix_fx( { FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ ) { - Pre_fx[chA][chB] = L_shr( Pre_fx[chA][chB], sub( q_Pre[chA][chB], q_P ) ); - Pim_fx[chA][chB] = L_shr( Pim_fx[chA][chB], sub( q_Pim[chA][chB], q_P ) ); + Pre_fx[chA][chB] = L_shr( Pre_fx[chA][chB], sub( q_Pre[chA][chB], q_P ) ); // q_P + Pim_fx[chA][chB] = L_shr( Pim_fx[chA][chB], sub( q_Pim[chA][chB], q_P ) ); // q_P move32(); move32(); } @@ -6584,7 +6584,7 @@ static void getDirectPartGains_fx( Word32 *rRealp, Word32 *rImagp, const UWord8 renderStereoOutputInsteadOfBinaural, - Word32 Rmat[3][3], + Word32 Rmat[3][3], /*Q30*/ PARAMBIN_HRTF_GAIN_CACHE *gainCache, const Word16 isHeadtracked ) { @@ -7029,34 +7029,34 @@ Word16 configure_reqularization_factor_fx( ) { Word16 reqularizationFactor; - reqularizationFactor = 16384; /* Default value */ + reqularizationFactor = 16384; /* Default value */ /*Q14*/ move16(); IF( EQ_32( ivas_format, MASA_FORMAT ) ) { IF( GE_32( ivas_total_brate, IVAS_160k ) ) { - reqularizationFactor = 6553; + reqularizationFactor = 6553; /*Q14*/ move16(); } ELSE IF( EQ_32( ivas_total_brate, IVAS_128k ) ) { - reqularizationFactor = 8192; + reqularizationFactor = 8192; /*Q14*/ move16(); } ELSE IF( EQ_32( ivas_total_brate, IVAS_96k ) ) { - reqularizationFactor = 9830; + reqularizationFactor = 9830; /*Q14*/ move16(); } ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) ) { - reqularizationFactor = 13107; + reqularizationFactor = 13107; /*Q14*/ move16(); } ELSE { - reqularizationFactor = 16384; + reqularizationFactor = 16384; /*Q14*/ move16(); } } @@ -7065,27 +7065,27 @@ Word16 configure_reqularization_factor_fx( { IF( GE_32( ivas_total_brate, IVAS_96k ) ) { - reqularizationFactor = 6553; + reqularizationFactor = 6553; /*Q14*/ move16(); } ELSE IF( GE_32( ivas_total_brate, IVAS_80k ) ) { - reqularizationFactor = 8192; + reqularizationFactor = 8192; /*Q14*/ move16(); } ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) ) { - reqularizationFactor = 11468; + reqularizationFactor = 11468; /*Q14*/ move16(); } ELSE IF( GE_32( ivas_total_brate, IVAS_48k ) ) { - reqularizationFactor = 13107; + reqularizationFactor = 13107; /*Q14*/ move16(); } ELSE { - reqularizationFactor = 16384; + reqularizationFactor = 16384; /*Q14*/ move16(); } } @@ -7105,8 +7105,8 @@ Word16 configure_reqularization_factor_fx( void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( Decoder_Struct *st_ivas, - Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/ + Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*cldfb_buf_q*/ Word16 *cldfb_buf_q, const Word16 nBins, const Word16 subframe ) @@ -7194,13 +7194,13 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( { FOR( ch = 0; ch < 2; ch++ ) { - Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ) ); + Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ) ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19 move32(); - Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = -19 + Enes_fx[ch] = L_add( Enes_fx[ch], Mpy_32_32( inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19 move32(); } - subframeEne_fx = L_add( Enes_fx[0], Enes_fx[1] ); + subframeEne_fx = L_add( Enes_fx[0], Enes_fx[1] ); // Q = *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19 IF( subframeEne_fx != 0 ) { @@ -7317,13 +7317,13 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( hMasaIsmData->eneMoveIIR_fx[ch][bin] = Mpy_32_16_1( hMasaIsmData->eneMoveIIR_fx[ch][bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 ); move32(); temp = Mpy_32_16_1( subframeEne_fx, eneMove_fx[ch] ); - hMasaIsmData->eneMoveIIR_fx[ch][bin] = L_add( hMasaIsmData->eneMoveIIR_fx[ch][bin], temp ); // Q = subframeEne_q_fx - 3 + hMasaIsmData->eneMoveIIR_fx[ch][bin] = L_add( hMasaIsmData->eneMoveIIR_fx[ch][bin], temp ); // Q = *cldfb_buf_q + *cldfb_buf_q - 34 = Q-22 move32(); hMasaIsmData->enePreserveIIR_fx[ch][bin] = Mpy_32_16_1( hMasaIsmData->enePreserveIIR_fx[ch][bin], STEREO_PREPROCESS_IIR_FACTOR_Q15 ); move32(); temp = Mpy_32_16_1( subframeEne_fx, enePreserve_fx[ch] ); - hMasaIsmData->enePreserveIIR_fx[ch][bin] = L_add( hMasaIsmData->enePreserveIIR_fx[ch][bin], temp ); // Q = subframeEne_q_fx - 3 + hMasaIsmData->enePreserveIIR_fx[ch][bin] = L_add( hMasaIsmData->enePreserveIIR_fx[ch][bin], temp ); // Q = *cldfb_buf_q + *cldfb_buf_q - 34 = Q-22 move32(); normVal_fx = L_add( hMasaIsmData->eneMoveIIR_fx[ch][bin], hMasaIsmData->enePreserveIIR_fx[ch][bin] ); @@ -7380,9 +7380,9 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( { hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] = add( hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin], ismPreprocMtxIncrement_fx[outCh][inCh] ); // Q = 15 move16(); - outSlotRe_fx[outCh] = Mpy_32_16_1( inRe_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q = 6; + outSlotRe_fx[outCh] = Mpy_32_16_1( inRe_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q; move32(); - outSlotIm_fx[outCh] = Mpy_32_16_1( inIm_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q = 6; + outSlotIm_fx[outCh] = Mpy_32_16_1( inIm_fx[inCh][slot][bin], hMasaIsmData->ismPreprocMatrix_fx[outCh][inCh][bin] ); // Q = *cldfb_buf_q; move32(); } } @@ -7394,14 +7394,14 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( move32(); FOR( ch = 0; ch < 2; ch++ ) { - hMasaIsmData->preprocEneTarget_fx[bin] = L_add( hMasaIsmData->preprocEneTarget_fx[bin], Madd_32_32( Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ), inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = -19 + hMasaIsmData->preprocEneTarget_fx[bin] = L_add( hMasaIsmData->preprocEneTarget_fx[bin], Madd_32_32( Mpy_32_32( inRe_fx[ch][slot][bin], inRe_fx[ch][slot][bin] ), inIm_fx[ch][slot][bin], inIm_fx[ch][slot][bin] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19 move32(); - hMasaIsmData->preprocEneRealized_fx[bin] = L_add( hMasaIsmData->preprocEneRealized_fx[bin], Madd_32_32( Mpy_32_32( outSlotRe_fx[ch], outSlotRe_fx[ch] ), outSlotIm_fx[ch], outSlotIm_fx[ch] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = -19 + hMasaIsmData->preprocEneRealized_fx[bin] = L_add( hMasaIsmData->preprocEneRealized_fx[bin], Madd_32_32( Mpy_32_32( outSlotRe_fx[ch], outSlotRe_fx[ch] ), outSlotIm_fx[ch], outSlotIm_fx[ch] ) ); // Q= *cldfb_buf_q + *cldfb_buf_q - 31 = Q-19 move32(); } temp1 = BASOP_Util_Divide3232_Scale( hMasaIsmData->preprocEneTarget_fx[bin], L_max( EPSILON_FX, hMasaIsmData->preprocEneRealized_fx[bin] ), &eqVal_q_fx ); eqVal_fx = Sqrt16( temp1, &eqVal_q_fx ); - temp1 = 4 << Q12; + temp1 = 4 << Q12; // Q12 move16(); IF( LT_16( eqVal_q_fx, Q12 ) ) { @@ -7417,7 +7417,7 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects_fx( { if ( GT_16( shr( eqVal_fx, sub( eqVal_q_fx, Q12 ) ), temp1 ) ) { - eqVal_fx = temp1; + eqVal_fx = temp1; // eqVal_q_fx move16(); } } @@ -7943,8 +7943,8 @@ static void ivas_masa_ext_rend_parambin_internal_fx( { FOR( Word16 k = 0; k < 60; k++ ) { - Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); - Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); + Cldfb_RealBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_RealBuffer_in_fx[i][j][k], shift ); // q + Cldfb_ImagBuffer_inTmp_fx[i][j][k] = L_shl( Cldfb_ImagBuffer_in_fx[i][j][k], shift ); // q move32(); move32(); } @@ -7981,20 +7981,20 @@ static void ivas_masa_ext_rend_parambin_internal_fx( { FOR( slot = 0; slot < BINAURAL_CHANNELS; slot++ ) { - Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); - Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); - Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); - Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); + Scale_sig( hDiracDecBin->processMtxDecRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDec ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxDecImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxDecPrev ) ); // scaling to q_mat } } FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { FOR( slot = 0; slot < numInChannels; slot++ ) { - Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); - Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); - Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); + Scale_sig( hDiracDecBin->processMtxRe_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxIm_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtx ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxRePrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat + Scale_sig( hDiracDecBin->processMtxImPrev_fx[ch][slot], nBins, sub( q_mat, hDiracDecBin->q_processMtxPrev ) ); // scaling to q_mat } } hDiracDecBin->q_processMtx = q_mat; @@ -8018,8 +8018,8 @@ static void ivas_masa_ext_rend_parambin_internal_fx( FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - scale_sig32( output_fx[ch], nBins * hSpatParamRendCom->subframe_nbslots[subframe], sub( Q11, q_out ) ); - scale_sig32( hMasaExtRend->cldfbSynRend[ch]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[ch]->cldfb_size, sub( Q11, hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state ) ); + scale_sig32( output_fx[ch], nBins * hSpatParamRendCom->subframe_nbslots[subframe], sub( Q11, q_out ) ); // Q11 + scale_sig32( hMasaExtRend->cldfbSynRend[ch]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[ch]->cldfb_size, sub( Q11, hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state ) ); // Q11 hMasaExtRend->cldfbSynRend[ch]->Q_cldfb_state = Q11; } diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index 625fb006f72b16a825a8d1432176c0dbad25f9ac..7928c75d535eb8eb16f0e9e0f680669022e5f40e 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -75,16 +75,16 @@ typedef struct } CovarianceMatrix; #ifdef IVAS_FLOAT_FIXED void ivas_mcmasa_param_est_ana_fx( - MCMASA_ANA_HANDLE hMcMasa, /* i : McMASA analyzer structure */ - Word32 data_fx[][L_FRAME48k], /* i : Audio frame in MC-format */ - Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */ - Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */ - Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */ - Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */ - Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */ + MCMASA_ANA_HANDLE hMcMasa, /* i : McMASA analyzer structure */ + Word32 data_fx[][L_FRAME48k], /* i : Audio frame in MC-format */ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation Q22 */ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth Q22 */ + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio Q31 */ + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence Q31 */ + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence Q31 */ Word16 q_data, - const Word16 input_frame, /* i : Input frame size */ - const Word16 nchan_inp /* i : Number of input channels */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_inp /* i : Number of input channels */ ); #else void ivas_mcmasa_param_est_ana( MCMASA_ANA_HANDLE hMcMasa, float data_f[][L_FRAME48k], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp ); @@ -107,19 +107,20 @@ static void computeVerticalDiffuseness_fx( Word32 **buffer_intensity, /* i : Intensity vectors */ const Word32 *buffer_energy, /* i : Energy */ const Word16 num_freq_bands, /* i : Number of frequency bands */ - Word32 *diffuseness, /* o : Estimated diffuseness */ - Word16 *buffer_intensity_e, - Word16 *buffer_energy_e ); + Word32 *diffuseness, /* o : Estimated diffuseness Q31 */ + Word16 *buffer_intensity_q, + Word16 *buffer_energy_q ); static void compute_cov_mtx_fx( Word32 sr[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Input matrix, real, s[ch][freq] */ Word32 si[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Input matrix, imag, s[ch][freq] */ const Word16 freq, /* i : Freq to process */ const Word16 N, /* i : Number of channels */ CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */ - Word16 shift ); + Word16 inp_exp /* i : Stores exponent for sr and si */ +); static void computeEvenLayout_fx( - const Word32 *ls_azimuth, - Word32 *ls_azimuth_even, + const Word32 *ls_azimuth, /* i: Q22 */ + Word32 *ls_azimuth_even, /* o: Q22 */ const Word16 numChannels ); static void ivas_mcmasa_dmx_fx( @@ -231,7 +232,7 @@ ivas_error ivas_mcmasa_ana_open( /* Determine band grouping */ Copy( MASA_band_grouping_24, hMcMasa->band_grouping, 24 + 1 ); - maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_Q31 ), ONE_IN_Q31 /*0.5f in Q31*/ ) ) ); + maxBin = extract_l( W_extract_h( W_add( W_mult_32_32( input_Fs, INV_CLDFB_BANDWIDTH_Q31 ), ONE_IN_Q31 /*0.5f in Q32*/ ) ) ); // Q0 FOR( i = 1; i < add( hMcMasa->nbands, 1 ); i++ ) { IF( GE_16( hMcMasa->band_grouping[i], maxBin ) ) @@ -323,22 +324,22 @@ ivas_error ivas_mcmasa_ana_open( FOR( i = 0; i < numAnalysisChannels; i++ ) { - hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; + hMcMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; // Q31 move32(); - hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_fx[i], 91 /*32767/360*/ ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ) ); + hMcMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_fx[i], 91 /*32767/360*/ ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ) ); // Q31 move32(); - hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ), 16 ); + hMcMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ), 16 ); // Q31 move32(); - hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_fx[i], 91 ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ) ); + hMcMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_fx[i], 91 ), 7 ) ) ), getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_elevation_fx[i], 91 ), 7 ) ) ) ); // Q31 move32(); - hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31; + hMcMasa->chnlToFoaEvenMtx_fx[0][i] = ONE_IN_Q31; // Q31 move32(); - hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even_fx[i], 91 ), 7 ) ) ), 16 ); + hMcMasa->chnlToFoaEvenMtx_fx[1][i] = L_shl( getSineWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even_fx[i], 91 ), 7 ) ) ), 16 ); // Q31 move32(); - hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0; + hMcMasa->chnlToFoaEvenMtx_fx[2][i] = 0; // Q31 move32(); - hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even_fx[i], 91 ), 7 ) ) ), 16 ); + hMcMasa->chnlToFoaEvenMtx_fx[3][i] = L_shl( getCosWord16R2( extract_l( L_shr( Mult_32_16( ls_azimuth_even_fx[i], 91 ), 7 ) ) ), 16 ); // Q31 move32(); } @@ -346,29 +347,29 @@ ivas_error ivas_mcmasa_ana_open( FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) { - left_min_fx = 360 << 22; + left_min_fx = 360 << 22; // Q22 move32(); - right_min_fx = -( 360 << 22 ); + right_min_fx = -( 360 << 22 ); // Q22 move32(); FOR( j = 0; j < hMcMasa->numHorizontalChannels; j++ ) { - azi_diff_fx = L_sub( ls_azimuth_fx[j], ls_azimuth_fx[i] ); + azi_diff_fx = L_sub( ls_azimuth_fx[j], ls_azimuth_fx[i] ); // Q22 IF( GT_32( azi_diff_fx, ( 180 << 22 ) ) ) { - azi_diff_fx = L_sub( azi_diff_fx, 360 << 22 ); + azi_diff_fx = L_sub( azi_diff_fx, 360 << 22 ); // Q22 } ELSE IF( LT_32( azi_diff_fx, -( 180 << 22 ) ) ) { - azi_diff_fx = L_add( azi_diff_fx, 360 << 22 ); + azi_diff_fx = L_add( azi_diff_fx, 360 << 22 ); // Q22 } test(); IF( LT_32( azi_diff_fx, left_min_fx ) && GT_32( azi_diff_fx, 0 ) ) { hMcMasa->leftNearest[i] = j; move16(); - left_min_fx = azi_diff_fx; + left_min_fx = azi_diff_fx; // Q22 move32(); } test(); @@ -376,7 +377,7 @@ ivas_error ivas_mcmasa_ana_open( { hMcMasa->rightNearest[i] = j; move16(); - right_min_fx = azi_diff_fx; + right_min_fx = azi_diff_fx; // Q22 move32(); } } @@ -398,7 +399,7 @@ ivas_error ivas_mcmasa_ana_open( move16(); FOR( i = 0; i < input_frame; i++ ) { - hMcMasa->interpolator_fx[i] = div_s( i, input_frame ); + hMcMasa->interpolator_fx[i] = div_s( i, input_frame ); // Q15 move16(); } @@ -844,16 +845,16 @@ void ivas_mcmasa_ana( /* Estimate metadata parameters for McMASA */ #ifdef IVAS_FLOAT_FIXED void ivas_mcmasa_param_est_ana_fx( - MCMASA_ANA_HANDLE hMcMasa, /* i : McMASA analyzer structure */ - Word32 data_fx[][L_FRAME48k], /* i : Audio frame in MC-format */ - Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation */ - Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth */ - Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio */ - Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence */ - Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence */ + MCMASA_ANA_HANDLE hMcMasa, /* i : McMASA analyzer structure */ + Word32 data_fx[][L_FRAME48k], /* i : Audio frame in MC-format */ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated elevation Q22 */ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated azimuth Q22 */ + Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated direct-to-total ratio Q31 */ + Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated spread coherence Q31 */ + Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* o : Estimated surround coherence Q31 */ Word16 q_data, - const Word16 input_frame, /* i : Input frame size */ - const Word16 nchan_inp /* i : Number of input channels */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_inp /* i : Number of input channels */ ) { Word16 cohPanCoh_e; @@ -981,8 +982,8 @@ void ivas_mcmasa_param_est_ana_fx( sf = sub( s_min( cr_q, ci_q ), 4 ); FOR( i = 0; i < numAnalysisChannels; i++ ) { - scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); - scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); + scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf + scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf } inp_q = add( inp_q, sf ); c_e = sub( 31, inp_q ); @@ -999,7 +1000,7 @@ void ivas_mcmasa_param_est_ana_fx( { FOR( i = 0; i < numAnalysisChannels; i++ ) { - Word32 temp = L_add( Mult_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mult_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ); + Word32 temp = L_add( Mult_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mult_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e hMcMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->energy_fx[block_m_idx][band_m_idx], hMcMasa->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hMcMasa->energy_e[block_m_idx][band_m_idx] ); move32(); } @@ -1021,21 +1022,21 @@ void ivas_mcmasa_param_est_ana_fx( /* Compute standard FOA */ /* W */ - v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); /*q*/ - v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); /*q*/ + v_add_32( Chnl_RealBuffer_fx[0], Chnl_RealBuffer_fx[1], Foa_RealBuffer_fx[0], num_freq_bins ); /*inp_q*/ + v_add_32( Chnl_ImagBuffer_fx[0], Chnl_ImagBuffer_fx[1], Foa_ImagBuffer_fx[0], num_freq_bins ); /*inp_q*/ FOR( i = 2; i < numAnalysisChannels; i++ ) { - v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); /*q*/ - v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); /*q*/ + v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); /*inp_q*/ + v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); /*inp_q*/ } /* Y */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/ - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); /*inp_q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); /*inp_q*/ FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/ - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); /*inp_q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); /*inp_q*/ } /* Z */ IF( hMcMasa->isHorizontalSetup ) @@ -1046,35 +1047,35 @@ void ivas_mcmasa_param_est_ana_fx( } ELSE { - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/ - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); /*inp_q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); /*inp_q*/ FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/ - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); /*inp_q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); /*inp_q*/ } } /* X */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/ - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); /*inp_q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); /*inp_q*/ FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/ - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); /*inp_q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); /*inp_q*/ } /* Compute even FOA */ /* W */ - Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); - Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); + Copy32( Foa_RealBuffer_fx[0], FoaEven_RealBuffer_fx[0], num_freq_bins ); /*inp_q*/ + Copy32( Foa_ImagBuffer_fx[0], FoaEven_ImagBuffer_fx[0], num_freq_bins ); /*inp_q*/ /* Y */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); /*q*/ - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_RealBuffer_fx[1], num_freq_bins ); /*inp_q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[1][0], FoaEven_ImagBuffer_fx[1], num_freq_bins ); /*inp_q*/ FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); /*q*/ - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_RealBuffer_fx[1], num_freq_bins ); /*inp_q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[1][i], FoaEven_ImagBuffer_fx[1], num_freq_bins ); /*inp_q*/ } /* Z (even setups are handled as horizontal) */ @@ -1082,22 +1083,22 @@ void ivas_mcmasa_param_est_ana_fx( set_zero_fx( FoaEven_ImagBuffer_fx[2], num_freq_bins ); /* X */ - v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); - v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); + v_multc_fixed( Chnl_RealBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_RealBuffer_fx[3], num_freq_bins ); /*inp_q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hMcMasa->chnlToFoaEvenMtx_fx[3][0], FoaEven_ImagBuffer_fx[3], num_freq_bins ); /*inp_q*/ FOR( i = 1; i < numAnalysisChannels; i++ ) { - v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); - v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_RealBuffer_fx[3], num_freq_bins ); /*inp_q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hMcMasa->chnlToFoaEvenMtx_fx[3][i], FoaEven_ImagBuffer_fx[3], num_freq_bins ); /*inp_q*/ } /* Direction estimation */ - computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /*2+q-31*/ + computeIntensityVector_ana_fx( hMcMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */ - computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) ); /*Q30*/ + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], shl( c_e, 1 ) ); /* Q direction_vector_fx = Q30*/ /* Power and intensity estimation for diffuseness */ - computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*(q)-31*/ - computeReferencePower_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); /*2*q-30*/ + computeIntensityVector_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, num_freq_bands, intensity_even_real_fx ); /*2*inp_q-31*/ + computeReferencePower_ana_fx( hMcMasa->band_grouping, FoaEven_RealBuffer_fx, FoaEven_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); /*2*inp_q-30*/ /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hMcMasa->index_buffer_intensity = add( ( hMcMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */ @@ -1113,19 +1114,19 @@ void ivas_mcmasa_param_est_ana_fx( Copy32( reference_power_fx[ts], &( hMcMasa->buffer_energy_fx[i_mult( index - 1, num_freq_bands )] ), num_freq_bands ); hMcMasa->buffer_energy_q[index - 1] = sub( shl( inp_q, 1 ), 30 ); move16(); - computeDiffuseness_fixed( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, out_exp ); + computeDiffuseness_fixed( hMcMasa->buffer_intensity_real_fx, hMcMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hMcMasa->buffer_intensity_real_q, hMcMasa->buffer_energy_q, out_exp ); // out_exp = Q30 /* Compute vertical diffuseness, and tune original diffuseness if needed */ IF( !hMcMasa->isHorizontalSetup ) { Copy32( intensity_real_fx[2], &( hMcMasa->buffer_intensity_real_vert_fx[index - 1][0] ), num_freq_bands ); hMcMasa->buffer_intensity_real_vert_q[index - 1] = sub( shl( inp_q, 1 ), 31 ); move16(); - computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q ); + computeVerticalDiffuseness_fx( hMcMasa->buffer_intensity_real_vert_fx, hMcMasa->buffer_energy_fx, num_freq_bands, vertical_diffuseness_vector_fx, hMcMasa->buffer_intensity_real_vert_q, hMcMasa->buffer_energy_q ); // Q vertical_diffuseness_vector_fx = 31 v_min_fx( diffuseness_vector_fx, out_exp, vertical_diffuseness_vector_fx, q_vdv, diffuseness_vector_fx, out_exp, num_freq_bands ); } FOR( band_m_idx = 0; band_m_idx < hMcMasa->nbands; band_m_idx++ ) { - norm_tmp_fx = L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ), 1 ); /*2q-30*/ + norm_tmp_fx = L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ), 1 ); /*2*inp_q-30*/ hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hMcMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), shl( c_e, 1 ), &hMcMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); @@ -1255,18 +1256,18 @@ void ivas_mcmasa_param_est_ana_fx( move32(); i1 = 0; move16(); - currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx]; + currentAzi_fx = azimuth_m_values_fx[block_m_idx][band_m_idx]; /*Q22*/ move32(); FOR( i = 0; i < hMcMasa->numHorizontalChannels; i++ ) { - angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) ); + angleDist_fx = L_abs( L_sub( currentAzi_fx, hMcMasa->ls_azimuth_fx[i] ) ); /*Q22*/ IF( GT_32( angleDist_fx, 754974720 /*180.0f Q.22*/ ) ) { - angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 ) ); + angleDist_fx = L_abs( L_sub( angleDist_fx, 1509949440 ) ); /*Q22*/ } IF( LT_32( angleDist_fx, minAngleDist_fx ) ) { - minAngleDist_fx = angleDist_fx; + minAngleDist_fx = angleDist_fx; /*Q22*/ move32(); i1 = i; move16(); @@ -1296,7 +1297,7 @@ void ivas_mcmasa_param_est_ana_fx( temp2 = L_add( temp2, EPSILON_FX ); lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, temp2, &lsEnergyRelation_e ); lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, temp2_e ) ); - lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); + lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31 stereoness_fx = Mult_32_32( stereoCoh_fx, lsEnergyRelation_fx ); stereoness_e = stereoCoh_e; move16(); @@ -1459,13 +1460,13 @@ void ivas_mcmasa_param_est_ana_fx( lsEnergySum_fx = L_add_sat( lsEnergySum_fx, EPSILON_FX ); lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp1, lsEnergySum_fx, &lsEnergyRelation_e ); lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp1_e, lsEnergySum_e ) ); - lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); - stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); + lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31 + stereoRatio_fx = L_sub( Mult_32_32( L_shl_sat( stereoCoh_fx, stereoCoh_e ), lsEnergyRelation_fx ), surrCoh_fx ); // Q31 lsEnergyRelation_fx = BASOP_Util_Divide3232_Scale( temp2, lsEnergySum_fx, &lsEnergyRelation_e ); lsEnergyRelation_e = add( lsEnergyRelation_e, sub( temp2_e, lsEnergySum_e ) ); - lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); - cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); + lsEnergyRelation_fx = L_shl( lsEnergyRelation_fx, add( 16, lsEnergyRelation_e ) ); // Q31 + cohPanRatio_fx = L_sub( Mult_32_32( cohPanCoh_fx, lsEnergyRelation_fx ), surrCoh_fx ); // Q31 IF( GT_32( stereoRatio_fx, cohPanRatio_fx ) ) { @@ -1533,7 +1534,7 @@ void ivas_mcmasa_param_est_ana_fx( diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e ); move32(); diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) ); - diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); + diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); // Q31 move32(); } ELSE @@ -2115,7 +2116,7 @@ static void ivas_mcmasa_dmx_fx( FOR( i = 0; i < input_frame; i++ ) { - dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_f_fx[2][i] ) ); + dmx_c_fx = W_extract_h( W_mult_32_32( INV_SQRT2_FX, data_f_fx[2][i] ) ); // data_e move32(); data_f_fx[0][i] = L_add( dmx_c_fx, data_f_fx[0][i] ); move32(); @@ -2148,16 +2149,16 @@ static void ivas_mcmasa_dmx_fx( } } - alpha_fx = 214748364; // Q31 + alpha_fx = 214748364; // 0.1 in Q31 move32(); L_tmp = Mpy_32_32( alpha_fx, multiChEne_fx ); - L_tmp1 = Mpy_32_32( 1932735284, hMcMasa->prevMultiChEne_fx ); + L_tmp1 = Mpy_32_32( 1932735284 /* 1.0 - alpha = 0.9 Q31 */, hMcMasa->prevMultiChEne_fx ); hMcMasa->prevMultiChEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, multiChEne_e, L_tmp1, hMcMasa->prevMultiChEne_e, &hMcMasa->prevMultiChEne_e ); L_tmp = Mpy_32_32( alpha_fx, downmixEne_fx ); - L_tmp1 = Mpy_32_32( 1932735284, hMcMasa->prevDownmixEne_fx ); + L_tmp1 = Mpy_32_32( 1932735284 /* 1.0 - alpha = 0.9 Q31 */, hMcMasa->prevDownmixEne_fx ); hMcMasa->prevDownmixEne_fx = BASOP_Util_Add_Mant32Exp( L_tmp, downmixEne_e, L_tmp1, hMcMasa->prevDownmixEne_e, &hMcMasa->prevDownmixEne_e ); prevEQ_fx = hMcMasa->prevEQ_fx; @@ -2177,16 +2178,16 @@ static void ivas_mcmasa_dmx_fx( FOR( i = 0; i < input_frame; i++ ) { L_tmp = Mpy_32_32( L_deposit_h( hMcMasa->interpolator_fx[i] ), currEQ_fx ); - L_tmp1 = L_sub( 1073741824, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) ); - L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx ); + L_tmp1 = L_sub( 1073741824 /* 1.0 in Q30*/, L_lshr( L_deposit_h( hMcMasa->interpolator_fx[i] ), 1 ) ); // Q30 + L_tmp1 = Mpy_32_32( L_tmp1, prevEQ_fx ); // e = prevEQ_e + 1 instEQ_fx = BASOP_Util_Add_Mant32Exp( L_tmp, currEQ_e, L_tmp1, add( prevEQ_e, 1 ), &instEQ_e ); FOR( j = 0; j < nchan_transport; j++ ) { - data_f_fx[j][i] = Mpy_32_32( instEQ_fx, data_f_fx[j][i] ); + data_f_fx[j][i] = Mpy_32_32( instEQ_fx, data_f_fx[j][i] ); // e = data_e + instEQ_e move32(); move32(); - data_f_fx[j][i] = L_shl( data_f_fx[j][i], instEQ_e ); + data_f_fx[j][i] = L_shl( data_f_fx[j][i], instEQ_e ); // data_e } } @@ -2203,7 +2204,7 @@ static void compute_cov_mtx_fx( const Word16 freq, /* i : Freq to process */ const Word16 N, /* i : Number of channels */ CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */ - Word16 inp_exp /*Stores exponent for temp*/ + Word16 inp_exp /* i : Stores exponent for sr and si */ ) { Word16 i, j; @@ -2225,9 +2226,9 @@ static void compute_cov_mtx_fx( d = si[j][freq]; norm_c = norm_l( c ); norm_d = norm_l( d ); - c = L_shl( c, norm_c ); /*inp_exp-norm_c*/ - d = L_shl( d, norm_d ); /*inp_exp-norm_d*/ - temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); /*exp=inp_exp-norm_ab+inp_exp-norm_cd*/ + c = L_shl( c, norm_c ); /*inp_exp-norm_c*/ + d = L_shl( d, norm_d ); /*inp_exp-norm_d*/ + temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( a, c ), sub( shl( inp_exp, 1 ), add( norm_a, norm_c ) ), Mult_32_32( b, d ), sub( shl( inp_exp, 1 ), add( norm_b, norm_d ) ), &shift ); COVls->xr_fx[i][j] = BASOP_Util_Add_Mant32Exp( COVls->xr_fx[i][j], COVls->xr_e[i][j], temp, shift, &COVls->xr_e[i][j] ); move32(); temp = BASOP_Util_Add_Mant32Exp( Mult_32_32( b, c ), sub( shl( inp_exp, 1 ), add( norm_b, norm_c ) ), L_negate( Mult_32_32( a, d ) ), sub( shl( inp_exp, 1 ), add( norm_a, norm_d ) ), &shift ); @@ -2279,7 +2280,7 @@ static void computeVerticalDiffuseness_fx( Word32 **buffer_intensity, /* i : Intensity vectors */ const Word32 *buffer_energy, /* i : Energy */ const Word16 num_freq_bands, /* i : Number of frequency bands */ - Word32 *diffuseness, /* o : Estimated diffuseness */ + Word32 *diffuseness, /* o : Estimated diffuseness Q31 */ Word16 *buffer_intensity_q, Word16 *buffer_energy_q ) { @@ -2304,7 +2305,7 @@ static void computeVerticalDiffuseness_fx( p_tmp_c = buffer_energy + i_mult( i, num_freq_bands ); FOR( k = 0; k < num_freq_bands; k++ ) { - energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], *( p_tmp_c ), sub( 31, buffer_energy_q[i] ), &energy_slow_e[k] ); /*q=min_q*/ + energy_slow[k] = BASOP_Util_Add_Mant32Exp( energy_slow[k], energy_slow_e[k], *( p_tmp_c ), sub( 31, buffer_energy_q[i] ), &energy_slow_e[k] ); move32(); p_tmp_c++; } @@ -2312,7 +2313,7 @@ static void computeVerticalDiffuseness_fx( /* Intensity slow */ FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow[k] = BASOP_Util_Add_Mant32Exp( intensity_slow[k], intensity_slow_e[k], buffer_intensity[i][k], sub( 31, buffer_intensity_q[i] ), &intensity_slow_e[k] ); /*q=min_q*/ + intensity_slow[k] = BASOP_Util_Add_Mant32Exp( intensity_slow[k], intensity_slow_e[k], buffer_intensity[i][k], sub( 31, buffer_intensity_q[i] ), &intensity_slow_e[k] ); move32(); } } @@ -2320,7 +2321,7 @@ static void computeVerticalDiffuseness_fx( /* Compute absolute value */ FOR( k = 0; k < num_freq_bands; k++ ) { - intensity_slow_abs[k] = L_abs( intensity_slow[k] ); /*min_q*/ + intensity_slow_abs[k] = L_abs( intensity_slow[k] ); move32(); } @@ -2340,14 +2341,14 @@ static void computeVerticalDiffuseness_fx( } ELSE IF( GE_32( tmp, L_shl( 1, sub( 15, tmp_e2 ) ) ) ) { - tmp = ONE_IN_Q31; + tmp = ONE_IN_Q31; // Q31 move32(); } ELSE { - tmp = L_shl( tmp, add( 16, tmp_e2 ) ); + tmp = L_shl( tmp, add( 16, tmp_e2 ) ); // Q31 } - diffuseness[i] = tmp; + diffuseness[i] = tmp; // Q31 move32(); } @@ -2411,8 +2412,8 @@ static void computeVerticalDiffuseness( #ifdef IVAS_FLOAT_FIXED static void computeEvenLayout_fx( - const Word32 *ls_azimuth, - Word32 *ls_azimuth_even, + const Word32 *ls_azimuth, /* i: Q22 */ + Word32 *ls_azimuth_even, /* o: Q22 */ const Word16 numChannels ) { Word16 i; @@ -2444,7 +2445,7 @@ static void computeEvenLayout_fx( { IF( LT_32( ls_azimuth_temp[j], smallestAzimuth ) ) { - smallestAzimuth = ls_azimuth_temp[j]; + smallestAzimuth = ls_azimuth_temp[j]; /*Q21*/ move32(); smallestAzimuthIndex = j; move16(); @@ -2452,7 +2453,7 @@ static void computeEvenLayout_fx( } ls_azimuth_order[i] = smallestAzimuthIndex; move32(); - ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 ); + ls_azimuth_temp[smallestAzimuthIndex] = ( 1000 << 21 ); /*Q21*/ move32(); } @@ -2473,7 +2474,7 @@ static void computeEvenLayout_fx( FOR( i = 0; i < numChannels; i++ ) { - ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 ), 22 ), 22 ); /*((a+2^21)/2^22)*2^22*/ + ls_azimuth_even[ls_azimuth_order[i]] = L_shl( L_shr( L_add( ls_azimuth_even_ordered[i], ONE_IN_Q21 /* 0.5 in Q22 */ ), 22 ), 22 ); /*Q22*/ move32(); } @@ -2630,14 +2631,14 @@ void ivas_create_masa_out_meta( } #else void ivas_create_masa_out_meta_fx( - MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ - SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ - const Word16 nchan_transport, /* i : Number of transport channels */ - Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ - Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ - Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ - Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ - Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ + MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ + SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ + const Word16 nchan_transport, /* i : Number of transport channels */ + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation Q22 */ + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth Q22 */ + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ Word16 energyRatio_q, Word16 spreadCoherence_q, Word16 surroundingCoherence_q @@ -2694,7 +2695,7 @@ void ivas_create_masa_out_meta_fx( /* Direct-to-total ratio */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->directToTotalRatio[0][sf][band] = (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ); + extOutMeta->directToTotalRatio[0][sf][band] = (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ); // Q8 move16(); extOutMeta->directToTotalRatio[1][sf][band] = 0; move16(); @@ -2703,7 +2704,7 @@ void ivas_create_masa_out_meta_fx( /* Spread coherence */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->spreadCoherence[0][sf][band] = (UWord8) L_shr( spreadCoherence[sf][band], sub( spreadCoherence_q, 8 ) ); + extOutMeta->spreadCoherence[0][sf][band] = (UWord8) L_shr( spreadCoherence[sf][band], sub( spreadCoherence_q, 8 ) ); // Q8 move16(); extOutMeta->spreadCoherence[1][sf][band] = 0; move16(); @@ -2712,14 +2713,14 @@ void ivas_create_masa_out_meta_fx( /* Diffuse-to-total ratio = 1 - sum(direct-to-total ratios) */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( UINT8_MAX, (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ) ); + extOutMeta->diffuseToTotalRatio[sf][band] = (UWord8) sub( UINT8_MAX, (UWord8) L_shr( energyRatio[sf][band], sub( energyRatio_q, 8 ) ) ); // Q8 move16(); } /* Surround coherence */ FOR( band = 0; band < numFrequencyBands; band++ ) { - extOutMeta->surroundCoherence[sf][band] = (UWord8) L_shr( surroundingCoherence[sf][band], sub( surroundingCoherence_q, 8 ) ); + extOutMeta->surroundCoherence[sf][band] = (UWord8) L_shr( surroundingCoherence[sf][band], sub( surroundingCoherence_q, 8 ) ); // Q8 move16(); } } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 1f230806be18e00babea4d972a62ee2d8d20ab87..de706bd47ab815d2fde7b0d91547ec7fde67ab76 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -167,28 +167,28 @@ ivas_error ivas_td_binaural_open_unwrap_fx( SWITCH( transport_config ) { case IVAS_AUDIO_CONFIG_5_1: - ls_azimuth_fx = ls_azimuth_CICP6_fx; - ls_elevation_fx = ls_elevation_CICP6_fx; + ls_azimuth_fx = ls_azimuth_CICP6_fx; // Q22 + ls_elevation_fx = ls_elevation_CICP6_fx; // Q22 BREAK; case IVAS_AUDIO_CONFIG_7_1: - ls_azimuth_fx = ls_azimuth_CICP12_fx; - ls_elevation_fx = ls_elevation_CICP12_fx; + ls_azimuth_fx = ls_azimuth_CICP12_fx; // Q22 + ls_elevation_fx = ls_elevation_CICP12_fx; // Q22 BREAK; case IVAS_AUDIO_CONFIG_5_1_2: - ls_azimuth_fx = ls_azimuth_CICP14_fx; - ls_elevation_fx = ls_elevation_CICP14_fx; + ls_azimuth_fx = ls_azimuth_CICP14_fx; // Q22 + ls_elevation_fx = ls_elevation_CICP14_fx; // Q22 BREAK; case IVAS_AUDIO_CONFIG_5_1_4: - ls_azimuth_fx = ls_azimuth_CICP16_fx; - ls_elevation_fx = ls_elevation_CICP16_fx; + ls_azimuth_fx = ls_azimuth_CICP16_fx; // Q22 + ls_elevation_fx = ls_elevation_CICP16_fx; // Q22 BREAK; case IVAS_AUDIO_CONFIG_7_1_4: - ls_azimuth_fx = ls_azimuth_CICP19_fx; - ls_elevation_fx = ls_elevation_CICP19_fx; + ls_azimuth_fx = ls_azimuth_CICP19_fx; // Q22 + ls_elevation_fx = ls_elevation_CICP19_fx; // Q22 BREAK; case IVAS_AUDIO_CONFIG_LS_CUSTOM: - ls_azimuth_fx = hTransSetup.ls_azimuth_fx; - ls_elevation_fx = hTransSetup.ls_elevation_fx; + ls_azimuth_fx = hTransSetup.ls_azimuth_fx; // Q22 + ls_elevation_fx = hTransSetup.ls_elevation_fx; // Q22 BREAK; default: ls_azimuth_fx = NULL; @@ -270,7 +270,7 @@ ivas_error ivas_td_binaural_open_unwrap_fx( test(); IF( NE_16( ivas_format, MASA_ISM_FORMAT ) && NE_16( ivas_format, SBA_ISM_FORMAT ) ) { - *binaural_latency_ns = Mult_32_32( ( *hBinRendererTd )->HrFiltSet_p->latency_s_fx, 1000000000 ); + *binaural_latency_ns = Mult_32_32( ( *hBinRendererTd )->HrFiltSet_p->latency_s_fx, 1000000000 /* 1000000000.f in Q0 */ ); move32(); } @@ -518,18 +518,18 @@ void ivas_td_binaural_close( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_td_binaural_renderer_unwrap_fx( - const REVERB_HANDLE hReverb, /* i : Reverberator handle */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD binaural object renderer handle */ - const Word16 num_src, /* i : number of sources to render */ - const Word16 lfe_idx, /* i : LFE channel index */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ + const REVERB_HANDLE hReverb, /* i : Reverberator handle */ + const AUDIO_CONFIG transport_config, /* i : Transport configuration */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD binaural object renderer handle */ + const Word16 num_src, /* i : number of sources to render */ + const Word16 lfe_idx, /* i : LFE channel index */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ const Word16 ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ - Word32 *output_fx[], /* i/o: SCE channels / Binaural synthesis */ - const Word16 output_frame, /* i : output frame length */ - const Word16 num_subframes /* i : number of subframes to render */ + Word32 *output_fx[], /* i/o: SCE channels / Binaural synthesis Q11 */ + const Word16 output_frame, /* i : output frame length */ + const Word16 num_subframes /* i : number of subframes to render */ ) { Word16 subframe_length; @@ -609,22 +609,22 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx( FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) { - scale_sig32( output_fx[i], L_FRAME48k, -4 ); + scale_sig32( output_fx[i], L_FRAME48k, -4 ); // Q11 - 4 = Q7 } - IF( NE_32( ( error = ivas_reverb_process_fx( hReverb, transport_config, 0, output_fx, p_reverb_signal_fx, subframe_idx ) ), IVAS_ERR_OK ) ) + IF( NE_32( ( error = ivas_reverb_process_fx( hReverb, transport_config, 0, output_fx, p_reverb_signal_fx, subframe_idx ) ), IVAS_ERR_OK ) ) // Q p_reverb_signal_fx = Q output_fx - 2 = 5 { return error; } FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) { - scale_sig32( output_fx[i], L_FRAME48k, 4 ); + scale_sig32( output_fx[i], L_FRAME48k, 4 ); // Q7 + 4 = Q11 } FOR( i = 0; i < BINAURAL_CHANNELS; ++i ) { - scale_sig32( p_reverb_signal_fx[i] + subframe_idx * hReverb->full_block_size, hReverb->full_block_size, 2 + 4 ); + scale_sig32( p_reverb_signal_fx[i] + subframe_idx * hReverb->full_block_size, hReverb->full_block_size, 2 + 4 ); // Q5 + 6 = Q11 } } @@ -654,8 +654,8 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx( IF( hReverb != NULL ) { - v_add_32( reverb_signal_fx[0], output_fx[0], output_fx[0], output_frame ); - v_add_32( reverb_signal_fx[1], output_fx[1], output_fx[1], output_frame ); + v_add_32( reverb_signal_fx[0], output_fx[0], output_fx[0], output_frame ); // Q11 + v_add_32( reverb_signal_fx[1], output_fx[1], output_fx[1], output_frame ); // Q11 } return IVAS_ERR_OK; @@ -781,10 +781,10 @@ ivas_error ivas_td_binaural_renderer_unwrap( #ifdef IVAS_FLOAT_FIXED ivas_error TDREND_GetMix_fx( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 */ - const Word16 subframe_length, /* i/o: subframe length */ - const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 Q11 */ + const Word16 subframe_length, /* i/o: subframe length */ + const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */ const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ ) { @@ -849,8 +849,8 @@ ivas_error TDREND_GetMix_fx( /* Populate output variable */ - Copy32( output_buf[0], output[0] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Left */ - Copy32( output_buf[1], output[1] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Right */ + Copy32( output_buf[0], output[0] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Left same Q as Src_p->InputFrame_p_fx Q11 */ + Copy32( output_buf[1], output[1] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Right same Q as Src_p->InputFrame_p_fx Q11 */ /* Clear the PoseUpdated and Source position update flags */ TDREND_Clear_Update_flags_fx( hBinRendererTd ); @@ -1219,23 +1219,23 @@ ivas_error TDREND_Update_listener_orientation_fx( move16(); /* Obtain head rotation matrix */ - QuatToRotMat_fx( *headPosition_fx, Rmat_fx ); // Rmat_fx Q: 2*Qx-32 + QuatToRotMat_fx( *headPosition_fx, Rmat_fx ); // Rmat_fx Q: 2*headPosition_q-32 Rmat_q = sub( shl( headPosition_q, 1 ), 32 ); /* Apply rotation matrix to looking vector [1;0;0] */ - FrontVec_fx[0] = Rmat_fx[0][0]; + FrontVec_fx[0] = Rmat_fx[0][0]; // Q Rmat_q move32(); - FrontVec_fx[1] = Rmat_fx[0][1]; + FrontVec_fx[1] = Rmat_fx[0][1]; // Q Rmat_q move32(); - FrontVec_fx[2] = Rmat_fx[0][2]; + FrontVec_fx[2] = Rmat_fx[0][2]; // Q Rmat_q move32(); /* Apply rotation matrix to up vector [0;0;1] */ - UpVec_fx[0] = Rmat_fx[2][0]; + UpVec_fx[0] = Rmat_fx[2][0]; // Q Rmat_q move32(); - UpVec_fx[1] = Rmat_fx[2][1]; + UpVec_fx[1] = Rmat_fx[2][1]; // Q Rmat_q move32(); - UpVec_fx[2] = Rmat_fx[2][2]; + UpVec_fx[2] = Rmat_fx[2][2]; // Q Rmat_q move32(); orient_q = Rmat_q; @@ -1244,9 +1244,9 @@ ivas_error TDREND_Update_listener_orientation_fx( IF( Pos_fx != NULL ) { /* Input position */ - Pos_p_fx[0] = ( *Pos_fx ).x_fx; - Pos_p_fx[1] = ( *Pos_fx ).y_fx; - Pos_p_fx[2] = ( *Pos_fx ).z_fx; + Pos_p_fx[0] = ( *Pos_fx ).x_fx; // Q Pos_fx->q_fact + Pos_p_fx[1] = ( *Pos_fx ).y_fx; // Q Pos_fx->q_fact + Pos_p_fx[2] = ( *Pos_fx ).z_fx; // Q Pos_fx->q_fact } ELSE { @@ -1430,7 +1430,7 @@ ivas_error ivas_td_binaural_renderer_ext_fx( const Word16 ism_md_subframe_update_ext, /* i : Metadata Delay in subframes to sync with audio delay */ const Word32 output_Fs, /* i : output sampling rate */ const Word16 output_frame, /* i : output frame length */ - Word32 output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ + Word32 output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis Q11 */ Word16 *exp ) { ISM_METADATA_FRAME hIsmMetaDataFrame; @@ -1659,15 +1659,15 @@ static void angles_to_vec_fx( ) { Word16 elevation_fx, azimuth_fx; - elevation_fx = (Word16) L_shr( Mult_32_16( elevation, 91 ), 7 ); + elevation_fx = (Word16) L_shr( Mult_32_16( elevation, 91 ), 7 ); // Q15 move16(); - azimuth_fx = (Word16) L_shr( Mult_32_16( azimuth, 91 ), 7 ); + azimuth_fx = (Word16) L_shr( Mult_32_16( azimuth, 91 ), 7 ); // Q15 move16(); - vec[0] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getCosWord16R2( azimuth_fx ) ) ); + vec[0] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getCosWord16R2( azimuth_fx ) ) ); // Qx + 16 move32(); - vec[1] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getSineWord16R2( azimuth_fx ) ) ); + vec[1] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getSineWord16R2( azimuth_fx ) ) ); // Qx + 16 move32(); - vec[2] = L_mult( radius, getSineWord16R2( elevation_fx ) ); + vec[2] = L_mult( radius, getSineWord16R2( elevation_fx ) ); // Qx + 16 move32(); return; } diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 8568da9eb6b18b2f74b126746df731bbf216d70b..2b0343c80aa469d39415b46cdb8d072998851e11 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -93,14 +93,14 @@ ivas_error TDREND_REND_RenderSourceHRFilt( } #else ivas_error TDREND_REND_RenderSourceHRFilt_fx( - TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ - Word32 *hrf_left_delta_fx, /* i/o: Left filter interpolation delta */ - Word16 *hrf_left_delta_e, /* i/o: Left filter interpolation delta exp */ - Word32 *hrf_right_delta_fx, /* i/o: Right filter interpolation delta */ - Word16 *hrf_right_delta_e, /* i/o: Right filter interpolation delta exp */ - const Word16 intp_count, /* i : Interpolation count */ - Word32 output_buf_fx[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ - const Word16 subframe_length /* i : Subframe length in use */ + TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ + Word32 *hrf_left_delta_fx, /* i/o: Left filter interpolation delta */ + Word16 *hrf_left_delta_e, /* i/o: Left filter interpolation delta exp */ + Word32 *hrf_right_delta_fx, /* i/o: Right filter interpolation delta */ + Word16 *hrf_right_delta_e, /* i/o: Right filter interpolation delta exp */ + const Word16 intp_count, /* i : Interpolation count */ + Word32 output_buf_fx[][L_SPATIAL_SUBFR_48k], /* o : Output buffer same Q as Src_p->InputFrame_p_fx Q11 */ + const Word16 subframe_length /* i : Subframe length in use */ ) { Word32 LeftOutputFrame_fx[L_SPATIAL_SUBFR_48k]; // will have same Q as Src_p->InputFrame_p_fx @@ -135,8 +135,8 @@ ivas_error TDREND_REND_RenderSourceHRFilt_fx( move16(); /* Copy to accumulative output frame */ - v_add_32( LeftOutputFrame_fx, output_buf_fx[0], output_buf_fx[0], subframe_length ); // Same Q as Src_p->InputFrame_p_fx - v_add_32( RightOutputFrame_fx, output_buf_fx[1], output_buf_fx[1], subframe_length ); // Same Q as Src_p->InputFrame_p_fx + v_add_32( LeftOutputFrame_fx, output_buf_fx[0], output_buf_fx[0], subframe_length ); // Same Q as Src_p->InputFrame_p_fx Q11 + v_add_32( RightOutputFrame_fx, output_buf_fx[1], output_buf_fx[1], subframe_length ); // Same Q as Src_p->InputFrame_p_fx Q11 return IVAS_ERR_OK; } @@ -190,7 +190,7 @@ void GetFilterFromAngle_fx( Word16 *hrf_left_e, /* o : Left HR filter exponent */ Word32 *hrf_right_fx, /* o : Right HR filter */ Word16 *hrf_right_e, /* o : Right HR filter exponent */ - Word16 *itd /* o : ITD value */ + Word16 *itd /* o : ITD value Q0 */ ) { GenerateFilter_fx( Elev_fx, Azim_fx, &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ); @@ -206,7 +206,7 @@ void GetFilterFromAngle_fx( IF( HrFiltSet_p->ModelParams.UseItdModel ) { GenerateITD_fx( Elev_fx, Azim_fx, &HrFiltSet_p->ModelParamsITD, &HrFiltSet_p->ModelEval ); - *itd = extract_l( HrFiltSet_p->ModelEval.itdMod_fx ); + *itd = extract_l( HrFiltSet_p->ModelEval.itdMod_fx ); // Q0 move16(); } ELSE @@ -401,13 +401,13 @@ static void GenerateFilter_fx( azim = L_add( azim, model->azimKSeq_fx[p][0] ); WHILE( GT_32( azim, DEG_360_IN_Q22 ) ) { - azim = L_sub( azim, DEG_360_IN_Q22 ); + azim = L_sub( azim, DEG_360_IN_Q22 ); // Q22 } IF( azim < 0 ) { - azim = L_add( azim, DEG_360_IN_Q22 ); + azim = L_add( azim, DEG_360_IN_Q22 ); // Q22 } - azim = L_sub( azim, model->azimKSeq_fx[p][0] ); + azim = L_sub( azim, model->azimKSeq_fx[p][0] ); // Q22 IF( EQ_16( model->azimDim3[EvIdx[p]], 1 ) ) /* Constant basis function */ { @@ -699,13 +699,13 @@ static void GenerateITD_fx( azim_fx = L_add( azim_fx, model->azimKSeq_fx[0] ); WHILE( GT_32( azim_fx, DEG_360_IN_Q22 ) ) { - azim_fx = L_sub( azim_fx, DEG_360_IN_Q22 ); + azim_fx = L_sub( azim_fx, DEG_360_IN_Q22 ); // Q22 } if ( azim_fx < 0 ) { - azim_fx = L_add( azim_fx, DEG_360_IN_Q22 ); + azim_fx = L_add( azim_fx, DEG_360_IN_Q22 ); // Q22 } - azim_fx = L_sub( azim_fx, model->azimKSeq_fx[0] ); + azim_fx = L_sub( azim_fx, model->azimKSeq_fx[0] ); // Q22 IF( NE_32( L_abs( elev_fx ), DEG_90_IN_Q22 ) ) { @@ -717,7 +717,7 @@ static void GenerateITD_fx( if ( GT_32( azim_fx, DEG_180_IN_Q22 ) ) { /* Flip spline functions around 180 deg */ - azim_itd_fx = L_sub( DEG_360_IN_Q22, azim_fx ); + azim_itd_fx = L_sub( DEG_360_IN_Q22, azim_fx ); // Q22 } getStandardBSplineSampVec_fx( modelEval->azimBfVecITD_fx, AzIdx, &num_az_idx, shr( add( model->azimDim3, 1 ), 1 ), azim_itd_fx, model->azimKSeq_fx, model->azimSegSamples, model->azimBsLen, model->azimBsStart, model->azimBsShape_fx ); diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 46aea4299273ece62b87b49432a66ee790060e65..7e7d93588a9c98e402e994ae03e2217c4e710df2 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -327,9 +327,9 @@ ivas_error ivas_sba_get_hoa_dec_matrix_fx( #endif #ifdef IVAS_FLOAT_FIXED void ivas_dirac_dec_binaural_sba_gain_fx( - Word32 *output[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ - const Word16 output_frame /* i : output frame length */ + Word32 *output[], /* i/o: synthesized core-coder transport channels/DirAC output, inp Qx, out Qx-1 */ + const Word16 nchan_remapped, /* i : num channels after remapping of TCs */ + const Word16 output_frame /* i : output frame length */ ); #endif void ivas_dirac_dec_binaural_sba_gain( @@ -353,7 +353,7 @@ void ivas_dirac_dec_binaural_render_fx( UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ UWord16 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ const Word16 nchan_transport, /* i : number of transport channels */ - Word32 *output_f[] /* o : rendered time signal */ + Word32 *output_f[] /* o : rendered time signal, Q11 */ ); #endif #ifndef IVAS_FLOAT_FIXED @@ -1195,7 +1195,7 @@ ivas_error ivas_td_binaural_renderer_unwrap_fx( ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ const Word16 ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ - Word32 *output_fx[], /* i/o: SCE channels / Binaural synthesis */ + Word32 *output_fx[], /* i/o: SCE channels / Binaural synthesis Q11 */ const Word16 output_frame, /* i : output frame length */ const Word16 num_subframes /* i : number of subframes to render */ ); @@ -1239,7 +1239,7 @@ ivas_error ivas_td_binaural_renderer_ext_fx( const Word16 ism_md_subframe_update_ext, /* i : Metadata Delay in subframes to sync with audio delay */ const Word32 output_Fs, /* i : output sampling rate */ const Word16 output_frame, /* i : output frame length */ - Word32 output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ + Word32 output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis Q11 */ Word16 *exp ); @@ -1310,7 +1310,7 @@ ivas_error TDREND_GetMix( ivas_error TDREND_GetMix_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 */ - const Word16 subframe_length, /* i/o: subframe length */ + const Word16 subframe_length, /* i/o: subframe length Q11 */ const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */ const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ ); @@ -1365,7 +1365,7 @@ void GetFilterFromAngle_fx( Word16 *hrf_left_e, /* o : Left HR filter exponent */ Word32 *hrf_right_fx, /* o : Right HR filter */ Word16 *hrf_right_e, /* o : Right HR filter exponent */ - Word16 *itd /* o : ITD value */ + Word16 *itd /* o : ITD value Q0 */ ); #endif @@ -1381,7 +1381,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt_fx( Word32 *hrf_right_delta_fx, /* i/o: Right filter interpolation delta */ Word16 *hrf_right_delta_e, /* i/o: Right filter interpolation delta exp */ const Word16 intp_count, /* i : Interpolation count */ - Word32 output_buf_fx[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ + Word32 output_buf_fx[][L_SPATIAL_SUBFR_48k], /* o : Output buffer same Q as Src_p->InputFrame_p_fx Q11 */ const Word16 subframe_length /* i : Subframe length in use */ ); #else @@ -1792,10 +1792,10 @@ ivas_error ivas_binaural_reverb_open_fastconv( ivas_error ivas_binaural_reverb_open_parambin( REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const int16_t numBins, /* i : number of CLDFB bins */ - const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ + const int16_t numBins, /* i : number of CLDFB bins Q0 */ + const int16_t numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate */ + const int32_t sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ); @@ -1858,9 +1858,9 @@ ivas_error ivas_reverb_process_fx( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ const Word16 mix_signals, /* i : add reverb to output signal */ - Word32 *pcm_in[], /* i : the PCM audio to apply reverb on */ + Word32 *pcm_in[], /* i (Q11): the PCM audio to apply reverb on */ Word32 *pcm_out[], /* o : the PCM audio with reverb applied */ - const Word16 i_ts /* i : subframe index */ + const Word16 i_ts /* i : (Q0) subframe index */ ); #endif ivas_error ivas_reverb_process( @@ -2785,14 +2785,14 @@ void computeReferencePower_ana( #ifdef IVAS_FLOAT_FIXED void ivas_create_masa_out_meta_fx( - MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ - SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ - const Word16 nchan_transport, /* i : Number of transport channels */ - Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation */ - Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth */ - Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ - Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ - Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ + MASA_DECODER_EXT_OUT_META_HANDLE extOutMeta, /* i/o: MASA metadata handle */ + SPHERICAL_GRID_DATA *Sph_Grid16, /* i : Spherical grid */ + const Word16 nchan_transport, /* i : Number of transport channels */ + Word32 elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated elevation Q22 */ + Word32 azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated azimuth Q22 */ + Word32 energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated direct-to-total ratio */ + Word32 spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated spread coherence */ + Word32 surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i : Estimated surround coherence */ Word16 energyRatio_q, Word16 spreadCoherence_q, Word16 surroundingCoherence_q diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index 00d4d0ef9509e31a5f4788dafa15e7c3f9556d28..5ea7dad8ec608a2a8e67c93e3dc66608655f4f6c 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -244,7 +244,7 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_MONO: reflections->shoebox_data.n_sources = 1; reflections->n_LC_sources = 1; - reflections->LC_mixing = LC_mixing_5_1; + reflections->LC_mixing = LC_mixing_5_1; /*Q0*/ move16(); move16(); move16(); @@ -259,15 +259,15 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_STEREO: reflections->shoebox_data.n_sources = 2; reflections->n_LC_sources = 2; - reflections->LC_mixing = LC_mixing_5_1; + reflections->LC_mixing = LC_mixing_5_1; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP2_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP2_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP2_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP2_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -277,15 +277,15 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_5_1: reflections->shoebox_data.n_sources = 5; reflections->n_LC_sources = 3; - reflections->LC_mixing = LC_mixing_5_1; + reflections->LC_mixing = LC_mixing_5_1; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP6_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP6_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP6_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP6_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -295,14 +295,14 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_7_1: reflections->shoebox_data.n_sources = 7; reflections->n_LC_sources = 5; - reflections->LC_mixing = LC_mixing_7_1; + reflections->LC_mixing = LC_mixing_7_1; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP12_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP12_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP12_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP12_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -312,14 +312,14 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_5_1_2: reflections->shoebox_data.n_sources = 7; reflections->n_LC_sources = 5; - reflections->LC_mixing = LC_mixing_5_1_2; + reflections->LC_mixing = LC_mixing_5_1_2; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP14_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP14_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP14_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP14_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -329,14 +329,14 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_5_1_4: reflections->shoebox_data.n_sources = 9; reflections->n_LC_sources = 5; - reflections->LC_mixing = LC_mixing_5_1_4; + reflections->LC_mixing = LC_mixing_5_1_4; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP16_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP16_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP16_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP16_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -346,14 +346,14 @@ ivas_error ivas_er_set_reflections_mode( case IVAS_AUDIO_CONFIG_7_1_4: reflections->shoebox_data.n_sources = 11; reflections->n_LC_sources = 5; - reflections->LC_mixing = LC_mixing_7_1_4; + reflections->LC_mixing = LC_mixing_7_1_4; /*Q0*/ move16(); move16(); move16(); FOR( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { - reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP19_idx[ch]; - reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP19_idx[ch]; + reflections->source_positions_fx[i_mult( 3, ch )] = ls_azimuth_CICP19_idx[ch]; /*Q0*/ + reflections->source_positions_fx[add( 1, i_mult( 3, ch ) )] = ls_elevation_CICP19_idx[ch]; /*Q0*/ reflections->source_positions_fx[add( 2, i_mult( 3, ch ) )] = ER_RADIUS_FX; move32(); move32(); @@ -597,8 +597,8 @@ ivas_error ivas_er_encoder_init( { /* Compute cartesian points for reflection (from degrees) */ - p_x_fx = reflections->shoebox_data.el_angle.data_fx[i]; - p_y_fx = reflections->shoebox_data.az_angle.data_fx[i]; + p_x_fx = reflections->shoebox_data.el_angle.data_fx[i]; // Q23 + p_y_fx = reflections->shoebox_data.az_angle.data_fx[i]; // Q23 move32(); move32(); @@ -639,9 +639,9 @@ ivas_error ivas_er_encoder_init( p_y_src_fx = Mpy_32_32( src_pos_ptr_fx[2], tmp_data_fx ); // .28 =.29*.30 p_z_src_fx = Mpy_32_32( src_pos_ptr_fx[2], shoebox_sin_cos_tbl_fx[( src_pos_ptr_fx[1] )][0] ); //.29 = .30 * .30 - p_x_src_fx = L_shr( p_x_src_fx, 14 ); - p_y_src_fx = L_shr( p_y_src_fx, 14 ); - p_z_src_fx = L_shr( p_z_src_fx, 15 ); + p_x_src_fx = L_shr( p_x_src_fx, 14 ); // Q.14 + p_y_src_fx = L_shr( p_y_src_fx, 14 ); // Q.14 + p_z_src_fx = L_shr( p_z_src_fx, 15 ); // Q.14 tmp_data = L_sub( p_x_src_fx, p_x_fx ); tmp16 = extract_l( tmp_data ); // Q.14 @@ -755,7 +755,7 @@ ivas_error ivas_er_compute_reflections( { FOR( j = 0; j < reflections->shoebox_data.n_ref; j++ ) { - tmp_fx = reflections->shoebox_data.times.data_fx[add( j, i_mult( i, reflections->shoebox_data.n_ref ) )]; + tmp_fx = reflections->shoebox_data.times.data_fx[add( j, i_mult( i, reflections->shoebox_data.n_ref ) )]; // Q23 tmp_fx_lo = u_extract_l( tmp_fx ); Mpy_32_16_uu( tmp_fx, (UWord16) reflections->output_Fs_fx, &tmp_fx1, &tmp_fx_lo ); tmp_fx1 = (UWord32) L_add( tmp_fx1, 0x20 ); @@ -937,7 +937,7 @@ ivas_error ivas_er_process( er_struct_t *reflections, const Word16 subframe_size, const Word16 subframe_idx, - Word32 **io, + Word32 **io, /*Q11*/ const AUDIO_CONFIG inConfig ) { ivas_error error = IVAS_ERR_OK; @@ -974,12 +974,12 @@ ivas_error ivas_er_process( /* If low complexity ER are requested only compute ER for n_LC_sources */ IF( reflections->lowComplexity ) { - n_ref_sources = reflections->n_LC_sources; + n_ref_sources = reflections->n_LC_sources; // Q0 move16(); } ELSE { - n_ref_sources = reflections->shoebox_data.n_sources; + n_ref_sources = reflections->shoebox_data.n_sources; // Q0 move16(); } @@ -993,7 +993,7 @@ ivas_error ivas_er_process( // buf_ch_idx = ( reflections->lowComplexity == 1 ) ? reflections->LC_mixing[i] : i; IF( EQ_32( reflections->lowComplexity, 1 ) ) { - buf_ch_idx = reflections->LC_mixing[i]; + buf_ch_idx = reflections->LC_mixing[i]; // Q0 move16(); } ELSE diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 73de5a7e627196130cfbaaabecbfd3ccaf8c110e..26f8122ed8363d8c4f4352990dd4a6de349d27c8 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -396,8 +396,8 @@ static void ivas_binaural_reverb_setReverbTimes( static void ivas_binaural_reverb_setReverbTimes_fx( REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ const Word32 output_Fs, /* i : sampling_rate */ - const Word32 *revTimes_fx, /* i : reverberation times T60 for each CLDFB bin in seconds */ - const Word32 *revEnes_fx /* i : spectrum for reverberated sound at each CLDFB bin */ + const Word32 *revTimes_fx, /*Q31 i : reverberation times T60 for each CLDFB bin in seconds */ + const Word32 *revEnes_fx /*Q31 i : spectrum for reverberated sound at each CLDFB bin */ ) { Word16 bin, ch, tap, sample; @@ -421,7 +421,7 @@ static void ivas_binaural_reverb_setReverbTimes_fx( tmp_exp = BASOP_Util_Add_MantExp( bin, 15, 1, 14, &tmp ); tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( tmp ), L_deposit_h( hReverb->numBins ), &exp ); exp = add( exp, sub( tmp_exp, 15 ) ); - L_tmp = Mpy_32_16_1( output_Fs, tmp ); + L_tmp = Mpy_32_16_1( output_Fs, tmp ); /*- exp */ binCenterFreq_exp = add( 31, exp ); binCenterFreq_fx = L_shr( L_tmp, 1 ); // divide by 2 IF( bin == 0 ) @@ -438,7 +438,7 @@ static void ivas_binaural_reverb_setReverbTimes_fx( tmp = add( mult( EVS_PI_FX, tmp ), EPSILLON_FX ); // to avoid divide by 0 issue tmp_exp = sub( add( binCenterFreq_exp, 2 ), norm ); - sine_inp = wrap_rad_fixed( L_shl( tmp, sub( tmp_exp, 2 ) ) ); + sine_inp = wrap_rad_fixed( L_shl( tmp, sub( tmp_exp, 2 ) ) ); // Q13 sine = getSinWord16( sine_inp ); // Q15 div1 = BASOP_Util_Divide1616_Scale( sine, tmp, &scale ); @@ -510,8 +510,8 @@ static void ivas_binaural_reverb_setReverbTimes_fx( Word32 tmp_mul; scale = norm_l( hReverb->loopBufLength[bin] ); tmp_mul = L_shl( hReverb->loopBufLength[bin], scale ); - L_tmp = BASOP_Util_Log2( attenuationFactorPerSample_fx ); - L_tmp = L_add( L_tmp, L_shl( (Word32) attenuationFactorPerSample_exp, 25 ) ); + L_tmp = BASOP_Util_Log2( attenuationFactorPerSample_fx ); // Q25 + L_tmp = L_add( L_tmp, L_shl( (Word32) attenuationFactorPerSample_exp, 25 ) ); // Q25 L_tmp = Mpy_32_32( L_tmp, tmp_mul ); L_tmp = BASOP_util_Pow2( L_tmp, sub( 6 + 31, scale ), &exp ); hReverb->loopAttenuationFactor_fx[bin] = L_shl( L_tmp, exp ); // making as Q31 @@ -538,7 +538,7 @@ static void ivas_binaural_reverb_setReverbTimes_fx( move32(); energyBuildup_exp = 0; move16(); - currentEnergy_fx = 1073741824; + currentEnergy_fx = ONE_IN_Q30; move32(); currentEnergy_exp = 1; move16(); @@ -625,13 +625,13 @@ static void ivas_binaural_reverb_setReverbTimes_fx( *-----------------------------------------------------------------------------------------*/ static ivas_error compute_feedback_matrix_fx( - Word32 *pFeedbackMatrix, + Word32 *pFeedbackMatrix, // Q31 const Word16 n ) { Word32 u; Word16 i, j, x; - u = MATRIX_CONSTANT; + u = MATRIX_CONSTANT; // Q31 move32(); pFeedbackMatrix[0] = u; @@ -814,15 +814,15 @@ static ivas_error set_base_config_fx( /* set loop delays to default */ IF( EQ_32( output_Fs, 48000 ) ) { - selected_loop_delay = default_loop_delay_48k; + selected_loop_delay = default_loop_delay_48k; // Q0 } ELSE IF( EQ_32( output_Fs, 32000 ) ) { - selected_loop_delay = default_loop_delay_32k; + selected_loop_delay = default_loop_delay_32k; // Q0 } ELSE IF( EQ_32( output_Fs, 16000 ) ) { - selected_loop_delay = default_loop_delay_16k; + selected_loop_delay = default_loop_delay_16k; // Q0 } FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) @@ -931,7 +931,7 @@ static ivas_error set_base_config( *-----------------------------------------------------------------------------------------*/ static Word32 calc_dmx_gain_fx( void ) { - const Word32 gain = DMX_GAIN; + const Word32 gain = DMX_GAIN; // Q25 move32(); return gain; } @@ -974,11 +974,11 @@ static void calc_predelay_fx( if ( LT_16( output_frame, predelay ) ) { - predelay = output_frame; + predelay = output_frame; // Q0 move16(); } - pParams->pre_delay = predelay; + pParams->pre_delay = predelay; // Q0 move16(); move16(); move16(); @@ -1021,7 +1021,7 @@ static void calc_predelay( #ifdef IVAS_FLOAT_FIXED static ivas_error compute_t60_coeffs_fx( ivas_reverb_params_t *pParams, - const Word16 nr_fc_fft_filter, + const Word16 nr_fc_fft_filter, /*Q0*/ const Word32 output_Fs ) { Word16 bin_idx, loop_idx, tf_T60_len, len; @@ -1073,15 +1073,15 @@ static ivas_error compute_t60_coeffs_fx( tmp = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( target_gains_db_fx[bin_idx] ), target_gains_db_exp[bin_idx], -2013265920, 7 ); IF( tmp < 0 ) { - target_gains_db_fx[bin_idx] = -30720; + target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720 move16(); target_gains_db_exp[bin_idx] = 7; move16(); } } - pCoeffs_a_fx = &pParams->pT60_filter_coeff_fx[add( shl( i_mult( len, loop_idx ), 1 ), len )]; - pCoeffs_b_fx = &pParams->pT60_filter_coeff_fx[shl( i_mult( len, loop_idx ), 1 )]; + pCoeffs_a_fx = &pParams->pT60_filter_coeff_fx[add( shl( i_mult( len, loop_idx ), 1 ), len )]; // Q14 + pCoeffs_b_fx = &pParams->pT60_filter_coeff_fx[shl( i_mult( len, loop_idx ), 1 )]; // Q14 Word16 val = target_gains_db_exp[0]; move16(); @@ -1103,10 +1103,10 @@ static ivas_error compute_t60_coeffs_fx( } } - len = shr( ( add( pParams->t60_filter_order, 1 ) ), 1 ); /* == floor( (order+1) / 2) */ + len = shr( ( add( pParams->t60_filter_order, 1 ) ), 1 ); // Q0// /* == floor( (order+1) / 2) */ FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) { - pParams->pLoop_delays[loop_idx] = sub( pParams->pLoop_delays[loop_idx], len ); + pParams->pLoop_delays[loop_idx] = sub( pParams->pLoop_delays[loop_idx], len ); // Q0 move16(); } return error; @@ -1328,13 +1328,13 @@ static void calc_low_shelf_first_order_filter_fx( move16(); norm_den1 = add( exp, sub( norm_den1, norm_den0 ) ); - pNum[0] = shr( pNum[0], sub( 1, norm_num0 ) ); + pNum[0] = shr( pNum[0], sub( 1, norm_num0 ) ); // Q14 move16(); - pNum[1] = shr( pNum[1], sub( 1, norm_num1 ) ); + pNum[1] = shr( pNum[1], sub( 1, norm_num1 ) ); // Q14 move16(); - pDen[1] = shr( pDen[1], sub( 1, norm_den1 ) ); + pDen[1] = shr( pDen[1], sub( 1, norm_den1 ) ); // Q14 move16(); - pDen[0] = shl( 1, 14 ); + pDen[0] = shl( 1, 14 ); // Q14 move16(); return; } @@ -1434,9 +1434,9 @@ static ivas_error calc_jot_t60_coeffs_fx( Word16 ref_hf_max_norm_fx = BASOP_Util_Divide1616_Scale( REF_HF_MAX_FX, fNyquist_fx, &scale4 ); ref_lf_min_norm_fx = shl( ref_lf_min_norm_fx, sub( scale1, 1 ) ); // Q14 - ref_lf_max_norm_fx = shl( ref_lf_max_norm_fx, sub( scale2, 1 ) ); - ref_hf_min_norm_fx = shl( ref_hf_min_norm_fx, sub( scale3, 1 ) ); - ref_hf_max_norm_fx = shl( ref_hf_max_norm_fx, sub( scale4, 1 ) ); + ref_lf_max_norm_fx = shl( ref_lf_max_norm_fx, sub( scale2, 1 ) ); // Q14 + ref_hf_min_norm_fx = shl( ref_hf_min_norm_fx, sub( scale3, 1 ) ); // Q14 + ref_hf_max_norm_fx = shl( ref_hf_max_norm_fx, sub( scale4, 1 ) ); // Q14 Word32 L_tmp; Word16 f0_fx, tmp_fx, lf_target_gain_dB_fx, hf_target_gain_dB_fx, mid_crossing_gain_dB_fx; @@ -1632,8 +1632,8 @@ static ivas_error set_t60_filter( REVERB_HANDLE hReverb, const UWord16 branch, const UWord16 nr_taps, - const Word16 coefA[], - const Word16 coefB[] ) + const Word16 coefA[], /*Q14*/ + const Word16 coefB[] /*Q14*/ ) { IF( GE_32( branch, hReverb->nr_of_branches ) ) { @@ -1683,7 +1683,7 @@ static ivas_error set_t60_filter( static ivas_error set_feedback_delay_fx( REVERB_HANDLE hReverb, const UWord16 branch, - const Word16 fb_delay ) + const Word16 fb_delay /*Q0*/ ) { IF( GE_32( branch, hReverb->nr_of_branches ) ) { @@ -1727,7 +1727,7 @@ static ivas_error set_feedback_delay( static ivas_error set_feedback_gain_fx( REVERB_HANDLE hReverb, const UWord16 branch, - const Word32 *pGain ) + const Word32 *pGain /*Q31*/ ) { UWord16 gain_idx; IF( GE_32( branch, hReverb->nr_of_branches ) ) @@ -1737,7 +1737,7 @@ static ivas_error set_feedback_gain_fx( FOR( gain_idx = 0; gain_idx < hReverb->nr_of_branches; gain_idx++ ) { - hReverb->gain_matrix_fx[branch][gain_idx] = pGain[gain_idx]; + hReverb->gain_matrix_fx[branch][gain_idx] = pGain[gain_idx]; // Q31 move32(); } @@ -1894,7 +1894,7 @@ static ivas_error set_color_fft_filter( static ivas_error set_mixer_level_fx( REVERB_HANDLE hReverb, const UWord16 channel, - const Word16 level[] ) + const Word16 level[] /*Q0*/ ) { UWord16 branch_idx; IF( GE_32( channel, BINAURAL_CHANNELS ) ) @@ -1904,7 +1904,7 @@ static ivas_error set_mixer_level_fx( FOR( branch_idx = 0; branch_idx < hReverb->nr_of_branches; branch_idx++ ) { - hReverb->mixer_fx[channel][branch_idx] = level[branch_idx]; + hReverb->mixer_fx[channel][branch_idx] = level[branch_idx]; /*Q0*/ move16(); } @@ -3038,7 +3038,7 @@ static void post_fft_filter( static void reverb_block_fx( REVERB_HANDLE hReverb, - Word32 *pInput_fx, + Word32 *pInput_fx, /*Q11*/ Word32 *pOut0_fx, Word32 *pOut1_fx ) @@ -3108,7 +3108,7 @@ static void reverb_block_fx( FOR( j = 0; j < nr_branches; j++ ) { - Word32 gain_matrix_j_i = hReverb->gain_matrix_fx[j][i]; + Word32 gain_matrix_j_i = hReverb->gain_matrix_fx[j][i]; // Q31 move32(); Word32 *pOutput = &ppOutput_fx[j][0]; FOR( ns = 0; ns < inner_bsize; ns++ ) @@ -3243,9 +3243,9 @@ static void reverb_block( static ivas_error downmix_input_block_fx( const REVERB_HANDLE hReverb, - Word32 *pcm_in[], + Word32 *pcm_in[], /* i Q11 : the input PCM audio */ const AUDIO_CONFIG input_audio_config, - Word32 *pPcm_out, + Word32 *pPcm_out, /* o Q11 : the output PCM audio */ const Word16 input_offset ) { Word16 i, s, nchan_transport; @@ -3285,7 +3285,7 @@ static ivas_error downmix_input_block_fx( { FOR( s = 0; s < hReverb->full_block_size; s++ ) { - pPcm_out[s] = Mpy_32_32( dmx_gain_fx, L_shl_sat( pcm_in[0][input_offset + s], 8 ) ); + pPcm_out[s] = Mpy_32_32( dmx_gain_fx, L_shl_sat( pcm_in[0][input_offset + s], 8 ) ); //(Q23 + Q11 + Q8) - 31 = Q11 move32(); } BREAK; @@ -3366,8 +3366,8 @@ static ivas_error downmix_input_block( static void predelay_block_fx( const REVERB_HANDLE hReverb, - Word32 *pInput, - Word32 *pOutput ) + Word32 *pInput, /*Q11*/ + Word32 *pOutput /*Q11*/ ) { UWord16 i, idx, n_samples, blk_size; UWord16 max_blk_size = (UWord16) hReverb->predelay_line.Delay; @@ -3377,7 +3377,7 @@ static void predelay_block_fx( { FOR( i = 0; i < hReverb->full_block_size; i++ ) { - pOutput[i] = pInput[i]; + pOutput[i] = pInput[i]; // Q11 move32(); } } @@ -3385,7 +3385,7 @@ static void predelay_block_fx( { FOR( i = 0; i < hReverb->full_block_size; i++ ) { - pOutput[i] = ivas_rev_delay_line_get_sample_fx( &( hReverb->predelay_line ) ); + pOutput[i] = ivas_rev_delay_line_get_sample_fx( &( hReverb->predelay_line ) ); // Q11 move32(); ivas_rev_delay_line_feed_sample_fx( &( hReverb->predelay_line ), pInput[i] ); } @@ -3532,8 +3532,8 @@ ivas_error ivas_reverb_process_fx( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ const Word16 mix_signals, /* i : add reverb to output signal */ - Word32 *pcm_in_fx[], /* i : the PCM audio to apply reverb on */ - Word32 *pcm_out_fx[], /* o : the PCM audio with reverb applied */ + Word32 *pcm_in_fx[], /* i Q11 : the PCM audio to apply reverb on */ + Word32 *pcm_out_fx[], /* o Q11 : the PCM audio with reverb applied */ const Word16 i_ts /* i : subframe index */ ) { @@ -3783,13 +3783,12 @@ void ivas_binaural_reverb_processSubframe_fx( const Word16 numSlots, /* i : number of slots to be processed */ Word32 inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i (Q_in) : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ Word32 inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i (Q_in) : input CLDFB data imag */ - Word32 outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ - Word32 outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o : output CLDFB data imag */ + Word32 outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o (Q_in) : output CLDFB data real */ + Word32 outImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* o (Q_in) : output CLDFB data imag */ ) { /* Declare the required variables */ Word16 idx, bin, ch, sample, invertSampleIndex, tapIdx, *phaseShiftTypePr; - // float **tapRealPr, **tapImagPr; Word32 **tapRealPr_fx, **tapImagPr_fx; push_wmops( "binaural_reverb" ); @@ -3819,11 +3818,11 @@ void ivas_binaural_reverb_processSubframe_fx( { /* Add from pre-delay buffer a sample to the loop buffer, in a time-inverted order. * Also apply the spectral gains determined for the reverberation */ - Word32 temp_1 = Mpy_32_32( hReverb->preDelayBufferReal_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ); - Word32 temp_2 = Mpy_32_32( hReverb->preDelayBufferImag_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ); - hReverb->loopBufReal_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufReal_fx[bin][invertSampleIndex], temp_1 ); + Word32 temp_1 = Mpy_32_32( hReverb->preDelayBufferReal_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ); /*Q_in*/ + Word32 temp_2 = Mpy_32_32( hReverb->preDelayBufferImag_fx[idx][bin], hReverb->reverbEqGains_fx[bin] ); /*Q_in*/ + hReverb->loopBufReal_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufReal_fx[bin][invertSampleIndex], temp_1 ); /*Q_in*/ move32(); - hReverb->loopBufImag_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufImag_fx[bin][invertSampleIndex], temp_2 ); + hReverb->loopBufImag_fx[bin][invertSampleIndex] = L_add( hReverb->loopBufImag_fx[bin][invertSampleIndex], temp_2 ); /*Q_in*/ move32(); hReverb->preDelayBufferReal_fx[idx][bin] = 0; move32(); @@ -3899,17 +3898,16 @@ void ivas_binaural_reverb_processSubframe_fx( { FOR( sample = 0; sample < numSlots; sample++ ) { - // float leftRe, rightRe, leftIm, rightIm; Word32 leftRe_fx, rightRe_fx, leftIm_fx, rightIm_fx; leftRe_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferReal_fx[bin][0][sample] ), - Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][1][sample] ) ); + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][1][sample] ) ); // Q_in rightRe_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferReal_fx[bin][1][sample] ), - Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][0][sample] ) ); + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferReal_fx[bin][0][sample] ) ); // Q_in leftIm_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferImag_fx[bin][0][sample] ), - Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][1][sample] ) ); + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][1][sample] ) ); // Q_in rightIm_fx = L_add( Mpy_32_32( hReverb->binauralCoherenceDirectGains_fx[bin], hReverb->outputBufferImag_fx[bin][1][sample] ), - Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][0][sample] ) ); + Mpy_32_32( hReverb->binauralCoherenceCrossmixGains_fx[bin], hReverb->outputBufferImag_fx[bin][0][sample] ) ); // Q_in hReverb->outputBufferReal_fx[bin][0][sample] = leftRe_fx; // Q_in move32(); @@ -3934,9 +3932,9 @@ void ivas_binaural_reverb_processSubframe_fx( FOR( bin = 0; bin < hReverb->numBins; bin++ ) { - outReal[ch][sample][bin] = hReverb->outputBufferReal_fx[bin][ch][invertSampleIndex]; // Q_in + Q30 + outReal[ch][sample][bin] = hReverb->outputBufferReal_fx[bin][ch][invertSampleIndex]; // Q_in move32(); - outImag[ch][sample][bin] = hReverb->outputBufferImag_fx[bin][ch][invertSampleIndex]; // Q_in + Q30 + outImag[ch][sample][bin] = hReverb->outputBufferImag_fx[bin][ch][invertSampleIndex]; // Q_in move32(); } FOR( ; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) @@ -3962,12 +3960,12 @@ void ivas_binaural_reverb_processSubframe_fx( #ifdef IVAS_FLOAT_FIXED static ivas_error ivas_binaural_reverb_open_fx( REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const Word16 numBins, /* i : number of CLDFB bins */ - const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ - const Word32 sampling_rate, /* i : sampling rate */ - const Word32 *revTimes_fx, /* i : reverberation times T60 for each CLDFB bin in seconds */ - const Word32 *revEnes_fx, /* i : spectrum for reverberated sound at each CLDFB bin */ - const Word16 preDelay /* i : reverb pre-delay in CLDFB slots */ + const Word16 numBins, /* i : Q0 number of CLDFB bins */ + const Word16 numCldfbSlotsPerFrame, /* i : Q0 number of CLDFB slots per frame */ + const Word32 sampling_rate, /* i : Q0 sampling rate */ + const Word32 *revTimes_fx, /* i : Q31 reverberation times T60 for each CLDFB bin in seconds */ + const Word32 *revEnes_fx, /* i : Q31 spectrum for reverberated sound at each CLDFB bin */ + const Word16 preDelay /* i : Q0 reverb pre-delay in CLDFB slots */ ) { Word16 bin, chIdx, k, len, scale, tmp; @@ -4027,7 +4025,7 @@ static ivas_error ivas_binaural_reverb_open_fx( // hReverb->loopBufLength[bin] = (int16_t) ( 1.45 * (int16_t) ( revTimes[bin] * 150.0 ) + 1 ); Word32 L_tmp_BufLength = L_shl( L_shr( Mpy_32_32( revTimes_fx[bin], 1258291200 /*150.0 in Q23*/ ), 23 ), 23 ); L_tmp_BufLength = L_add( Mpy_32_32( 1556925645 /*1.45 in Q30*/, L_tmp_BufLength ), ONE_IN_Q22 ); - hReverb->loopBufLength[bin] = (Word16) L_shr( L_tmp_BufLength, 22 ); + hReverb->loopBufLength[bin] = (Word16) L_shr( L_tmp_BufLength, 22 ); /*Q0*/ move16(); hReverb->loopBufLength[bin] = s_min( hReverb->loopBufLength[bin], hReverb->loopBufLengthMax[bin] ); @@ -4292,8 +4290,8 @@ ivas_error ivas_binaural_reverb_open_fastconv_fx( } ELSE { - revTimes = hHrtfFastConv->fastconvReverberationTimes_fx; - revEne = hHrtfFastConv->fastconvReverberationEneCorrections_fx; + revTimes = hHrtfFastConv->fastconvReverberationTimes_fx; /*Q31*/ + revEne = hHrtfFastConv->fastconvReverberationEneCorrections_fx; /*Q31*/ preDelay = 10; move16(); } @@ -4353,10 +4351,10 @@ ivas_error ivas_binaural_reverb_open_fastconv( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_binaural_reverb_open_parambin( REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ - const Word16 numBins, /* i : number of CLDFB bins */ - const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame */ + const Word16 numBins, /* i : number of CLDFB bins Q0 */ + const Word16 numCldfbSlotsPerFrame, /* i : number of CLDFB slots per frame Q0 */ IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ - const int32_t sampling_rate, /* i : sampling rate */ + const int32_t sampling_rate, /* i : sampling rate Q0 */ const HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : Parametric binauralizer HRTF handle */ ) { @@ -4373,19 +4371,13 @@ ivas_error ivas_binaural_reverb_open_parambin( { revTimes = t60; revEne = ene; - /* Todo Philips: This needs a suitable function for ParamBin here. */ - // if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfFastConv, internal_config, false, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) - // { - // return error; - // } - // preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); - preDelay = (Word16) L_shr_r( Mpy_32_32( 1677721600 /*800 in Q21*/, roomAcoustics->acousticPreDelay_fx /*Q27*/ ), Q17 ); + preDelay = (Word16) L_shr_r( Mpy_32_32( 1677721600 /*800 in Q21*/, roomAcoustics->acousticPreDelay_fx /*Q27*/ ), Q17 ); /*Q0*/ move16(); } ELSE { - revTimes = hHrtfParambin->parametricReverberationTimes_fx; - revEne = hHrtfParambin->parametricReverberationEneCorrections_fx; + revTimes = hHrtfParambin->parametricReverberationTimes_fx; /*Q31*/ + revEne = hHrtfParambin->parametricReverberationEneCorrections_fx; /*Q31*/ preDelay = 10; move16(); } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index c5661dc39403e8646439091c1704ffe9c6ea82e5..b6f6274cf413f44126604b86b023552c28268d15 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -941,7 +941,7 @@ typedef struct ivas_dirac_dec_binaural_data_structure Word32 ChCrossImOut_fx[CLDFB_NO_CHANNELS_MAX]; Word32 ChEneOut_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 ChEneOutPrev_fx[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; - Word32 frameMeanDiffuseness_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 frameMeanDiffuseness_fx[CLDFB_NO_CHANNELS_MAX]; /*Q29*/ Word32 ChCrossReOutPrev_fx[CLDFB_NO_CHANNELS_MAX]; Word32 ChCrossImOutPrev_fx[CLDFB_NO_CHANNELS_MAX]; @@ -2220,7 +2220,7 @@ typedef struct ivas_hrtfs_parambin_struct float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; #else - Word16 hrtfShCoeffsRe_fx[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; /* Q15 */ + Word16 hrtfShCoeffsRe_fx[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; /* Q14 */ Word16 hrtfShCoeffsIm_fx[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; /* Q14 */ #endif @@ -2437,13 +2437,13 @@ typedef struct ivas_mcmasa_ana_data_structure Word16 buffer_intensity_real_vert_q[DIRAC_NO_COL_AVG_DIFF]; Word32 buffer_energy_fx[DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS]; Word16 buffer_energy_q[DIRAC_NO_COL_AVG_DIFF]; - Word32 chnlToFoaMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; - Word32 chnlToFoaEvenMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; + Word32 chnlToFoaMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; // Q31 + Word32 chnlToFoaEvenMtx_fx[FOA_CHANNELS][MCMASA_MAX_ANA_CHANS]; // Q31 Word32 ls_azimuth_fx[MCMASA_MAX_ANA_CHANS]; Word32 prevMultiChEne_fx; Word32 prevDownmixEne_fx; Word32 prevEQ_fx; - Word16 interpolator_fx[L_FRAME48k]; + Word16 interpolator_fx[L_FRAME48k]; // Q15 Word16 chnlToFoaMtx_e; Word16 prevMultiChEne_e; Word16 prevDownmixEne_e;