diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index c1d76ee787d882a0118803218ed93864036cfdd0..54f1a34ec7591f9dbbc6d5ca58a3ea0e60463653 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -132,31 +132,22 @@ typedef struct _IVAS_ISM_METADATA typedef struct { float w, x, y, z; - -} IVAS_QUATERNION; - #ifdef IVAS_FLOAT_FIXED -typedef struct -{ Word32 w_fx, x_fx, y_fx, z_fx; Word16 w_qfact, x_qfact, y_qfact, z_qfact; -} IVAS_QUATERNION_FX; #endif -typedef struct -{ - float x, y, z; +} IVAS_QUATERNION; -} IVAS_VECTOR3; -#ifdef IVAS_FLOAT_FIXED typedef struct { + float x, y, z; +#ifdef IVAS_FLOAT_FIXED Word32 x_fx, y_fx, z_fx; Word16 x_qfact, y_qfact, z_qfact; - -} IVAS_VECTOR3_FX; #endif +} IVAS_VECTOR3; typedef enum { @@ -241,6 +232,9 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG IVAS_VECTOR3 dimensions; /* Room dimensions [m] */ float AbsCoeff[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ IVAS_VECTOR3 ListenerOrigin; /* Listener origin */ +#ifdef IVAS_FLOAT_FIXED + int32_t AbsCoeff_fx[IVAS_ROOM_ABS_COEFF]; /* Absorption coeffs */ +#endif } IVAS_ROOM_ACOUSTICS_CONFIG_DATA; diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 30a0f57671062967edd8ca7eaea01c4b3b1d8679..b3791bbba93350429f9337043cd8fbfe6695c429 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -707,6 +707,7 @@ void stereo_tcx_dec_mode_switch_reconf_To_fixed( fixedToFloat_arr( st->hTcxDec->syn_OverlFB, st->hTcxDec->syn_OverlFB_float, st->hTcxDec->Q_syn_OverlFB, 480 ); fixedToFloat_arr( st->hTcxDec->old_synth, st->hTcxDec->old_synth_float, Q_old_synth, OLD_SYNTH_INTERNAL_DEC ); fixedToFloat_arr( st->hTcxDec->synth_history_fx, st->hTcxDec->synth_history, Q_synth_history, L_PROT48k + L_FRAME_MAX ); + st->hTcxDec->q_synth_history_fx = Q_synth_history; fixedToFloat_arr( st->hTcxDec->ltpGainMemory_fx, st->hTcxDec->ltpGainMemory, 15, N_LTP_GAIN_MEMS ); st->hTcxDec->tcxltp_second_last_pitch_float = fixedToFloat( st->hTcxDec->tcxltp_second_last_pitch, 16 ); st->hTcxDec->tcxltp_third_last_pitch_float = fixedToFloat( st->hTcxDec->tcxltp_third_last_pitch, 16 ); @@ -1409,6 +1410,7 @@ void stereo_tcx_dec_mode_switch_reconf_To_fixed_2( fixedToFloat_arr( st->hTcxDec->syn_OverlFB, st->hTcxDec->syn_OverlFB_float, st->hTcxDec->Q_syn_OverlFB, 480 ); fixedToFloat_arr( st->hTcxDec->old_synth, st->hTcxDec->old_synth_float, Q_old_synth, OLD_SYNTH_INTERNAL_DEC ); fixedToFloat_arr( st->hTcxDec->synth_history_fx, st->hTcxDec->synth_history, Q_synth_history, L_PROT48k + L_FRAME_MAX ); + st->hTcxDec->q_synth_history_fx = Q_synth_history; fixedToFloat_arr( st->hTcxDec->ltpGainMemory_fx, st->hTcxDec->ltpGainMemory, 15, N_LTP_GAIN_MEMS ); st->hTcxDec->tcxltp_second_last_pitch_float = fixedToFloat( st->hTcxDec->tcxltp_second_last_pitch, 16 ); st->hTcxDec->tcxltp_third_last_pitch_float = fixedToFloat( st->hTcxDec->tcxltp_third_last_pitch, 16 ); @@ -1971,6 +1973,8 @@ void fixed_to_float_stereo_tcx_core_dec( fixedToFloat_arr( hTcxDec->old_synth, hTcxDec->old_synth_float, 0, hTcxDec->old_synth_len ); fixedToFloat_arr( hTcxDec->synth_history_fx, hTcxDec->synth_history, 0, NS2SA_fx2( st->output_Fs, PH_ECU_MEM_NS ) ); + st->hTcxDec->q_synth_history_fx = 0; + fixedToFloat_arr( hTcxDec->old_synthFB_fx, hTcxDec->old_synthFB, 0, NS2SA_fx2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) + hTcxDec->old_synth_lenFB ); fixedToFloat_arr( st->old_lsp_q_cng, st->old_lsp_q_cng_float, Q15, M ); fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index d5c44b42a953f4f02555e964de4ace10fdc53318..d23da8458b88386342d02ea5d865715a19b0b3d1 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -48,6 +48,7 @@ #define _180_OVER_PI ( 180.0f / EVS_PI ) #ifdef IVAS_FLOAT_FIXED #define _180_OVER_PI_Q25 1922527233 +#define _180_OVER_PI_FX (Word32) (( 180.0f / EVS_PI ) *ONE_IN_Q10) #define PI_OVER_4_Q29 421657440 #define PI_OVER_Q29 1686629760 #define Q31_0_99 2126008811 @@ -368,6 +369,8 @@ typedef enum #define STEP_PARAM_ISM_POW_RATIO_NBITS_Q15 (4681) /* 1.0f / (float)((1 << PARAM_ISM_POW_RATIO_NBITS) - 1) */ /* ISM DTX */ +#define ISM_Q_STEP_FX 10485760 +#define ISM_Q_STEP_BORDER_FX 20971520 #define ISM_DTX_COH_SCA_BITS 4 #define ISM_DTX_AZI_BITS_HIGH 8 #define ISM_DTX_ELE_BITS_HIGH 7 @@ -1798,10 +1801,14 @@ typedef enum #define ER_LIST_ORIGIN_Y (0.0f) #define ER_LIST_HEIGHT (1.6f) #ifdef IVAS_FLOAT_FIXED -#define ER_LIST_HEIGHT_FX 26214 +#define ER_RADIUS_FX (1* ONE_IN_Q30) //Q2.30 +#define ER_LIST_ORIGIN_X_FX (0) +#define ER_LIST_ORIGIN_Y_FX (0) +#define ER_LIST_HEIGHT_FX (1.6 *ONE_IN_Q22) //Q.22 #endif // IVAS_FLOAT_FIXED + /*----------------------------------------------------------------------------------* * Stereo downmix EVS constants *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c031e2efde6e28bf82def494f02c13675b21328f..ce5bdc114021aee540b26ac733104314ae379dfc 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1212,6 +1212,11 @@ void ivas_param_ism_dec( float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_dec_digest_tc_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif void ivas_ism_dec_digest_tc( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -1246,6 +1251,9 @@ void ivas_param_ism_dec_render_fx( float *output_f[], /* o : rendered time signal */ Word32 *output_f_fx[] ); +void ivas_param_ism_params_to_masa_param_mapping_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); #endif void ivas_param_ism_params_to_masa_param_mapping( diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 65c86cfae94d0f048d6d9cd9125e62c48b69a704..f191f80264d689c4a02c66fb23eff72d1fddca26 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1934,12 +1934,12 @@ void TDREND_MIX_LIST_SetPos_fx( ivas_error TDREND_Update_listener_orientation_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ const Word16 headRotEnabled, /* i : Headrotation flag */ - const IVAS_QUATERNION_FX *headPosition_fx, /* i : Listener orientation */ - const IVAS_VECTOR3_FX *Pos_fx /* i : Listener Position */ + const IVAS_QUATERNION *headPosition_fx, /* i : Listener orientation */ + const IVAS_VECTOR3 *Pos_fx /* i : Listener Position */ ); void QuatToRotMat_fx( - const IVAS_QUATERNION_FX quat, /* i : quaternion describing the rotation Qx */ + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation Qx */ Word32 Rmat[3][3] /* o : real-space rotation matrix for this rotation 2*Qx-32 */ ); diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 9bd5ee36eb65233edc3c238bb4b74c28ab7fc1e3..a48fc0fd2eafd6d9f9d80c94b48f85f3f2769969 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -3244,6 +3244,45 @@ const float ls_elevation_CICP19[11] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0 const float cb_azi_chan[] = { 0.0f, 30.0f, 110.0f, 135.0f }; +#ifdef IVAS_FLOAT_FIXED +const int16_t ls_azimuth_CICP2_idx[2] = { 1, 2 }; +const int16_t ls_elevation_CICP2_idx[2] = { 0, 0 }; + +const int16_t ls_azimuth_CICP6_idx[5] = { 1, 2, 0, 7, 8 }; +const int16_t ls_elevation_CICP6_idx[5] = { 0, 0, 0, 0, 0 }; + +const int16_t ls_azimuth_CICP12_idx[7] = { 1, 2, 0, 7, 8, 9, 10 }; +const int16_t ls_elevation_CICP12_idx[7] = { 0, 0, 0, 0, 0, 0, 0 }; + +const int16_t ls_azimuth_CICP14_idx[7] = { 1, 2, 0, 7, 8, 1, 2 }; +const int16_t ls_elevation_CICP14_idx[7] = { 0, 0, 0, 0, 0, 3, 4 }; + +const int16_t ls_azimuth_CICP16_idx[9] = { 1, 2, 0, 7, 8, 1, 2, 7, 8 }; +const int16_t ls_elevation_CICP16_idx[9] = { 0, 0, 0, 0, 0, 3, 3, 3, 3 }; + + +const int16_t ls_azimuth_CICP19_idx[11] = { 1, 2, 0, 9, 10, 5, 6, 1, 2, 9, 10 }; +const int16_t ls_elevation_CICP19_idx[11] = { 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3 }; + + +const float shoebox_sin_cos_tbl[11][2] ={{0.00000000, 1.00000000 }, //0 + {0.500000000, 0.866025388}, { -0.500000000, 0.866025388}, //30, -30 + {0.573576450 , 0.819152057}, {-0.573576450, 0.819152057}, //35, -35 + {1.00000000 , 0.00000000} , { -1.00000000, 0.00000000 }, //90, -90 + {0.939692616 , -0.342020124}, {-0.939692616,-0.342020124},//110,-110 + {0.707106769 , -0.707106769}, {-0.707106769,-0.707106769}}; //135, -135 + +const Word32 shoebox_sin_cos_tbl_fx[11][2] ={{0,1073741824} , //0 + {536870912, 929887680},{-536870912, 929887680}, //30, -30 + {615873024,879557824},{-615873024,879557824},//35, -35 + {1073741824,0}, {-1073741824,0},//90, -90 + {1008987264,-367241312}, {-1008987264,-367241312},//110,-110 + {759250112,-759250112},{-759250112,-759250112}}; //135, -135 //Q.30 + +#endif + + + const Word32 delta_phi_val[90] = { 0, 1509949440, 754974720, 503316480, 377487360, 301989888, 251658240, 215707056, 188743680, 167772160, 150994944, diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index c271edabdda491d6828d6a02f00d0b0c96bfd92e..cbbe264584ec2ce03c92e3344b570e6ba57e6370 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -356,7 +356,23 @@ extern const float ls_azimuth_CICP16[9]; extern const float ls_elevation_CICP16[9]; extern const float ls_azimuth_CICP19[11]; extern const float ls_elevation_CICP19[11]; - +#ifdef IVAS_FLOAT_FIXED +extern const Word16 ls_azimuth_CICP2_idx[2]; +extern const Word16 ls_elevation_CICP2_idx[2]; +extern const Word16 ls_azimuth_CICP6_idx[5]; +extern const Word16 ls_elevation_CICP6_idx[5]; +extern const Word16 ls_azimuth_CICP12_idx[7]; +extern const Word16 ls_elevation_CICP12_idx[7]; +extern const Word16 ls_azimuth_CICP14_idx[7]; +extern const Word16 ls_elevation_CICP14_idx[7]; +extern const Word16 ls_azimuth_CICP16_idx[9]; +extern const Word16 ls_elevation_CICP16_idx[9]; +extern const Word16 ls_azimuth_CICP19_idx[11]; +extern const Word16 ls_elevation_CICP19_idx[11]; + +extern const float shoebox_sin_cos_tbl[11][2]; +extern const Word32 shoebox_sin_cos_tbl_fx[11][2]; +#endif extern const float cb_azi_chan[]; extern const Word32 delta_phi_val[90]; extern const Word32 inv_delta_phi_val[90]; diff --git a/lib_com/low_rate_band_att_fx.c b/lib_com/low_rate_band_att_fx.c index 0e835a37db9bbf988ab9238cc19e257b968df444..e4889c3956455b153cc94a01d9c5ef97710ff59f 100644 --- a/lib_com/low_rate_band_att_fx.c +++ b/lib_com/low_rate_band_att_fx.c @@ -339,7 +339,7 @@ void fine_gain_dec_fx exp1 = sub(14, exp1); L_tmp = L_mult0(fg_pred[band], tmp1); /*12+exp1 */ - fg_pred[band] = round_fx(L_shl(L_tmp, sub(16, exp1))); /*12+exp1+16-exp1-16=12 */ + fg_pred[band] = round_fx_sat(L_shl_sat(L_tmp, sub(16, exp1))); /*12+exp1+16-exp1-16=12 */ } } } diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 4c60f85c7591f1f2ddb6fade97328d640d19f87e..b55135baf9f2ed592767b965835346a31fe9338f 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -7642,6 +7642,15 @@ void generate_comfort_noise_dec_hf_ivas_fx( Word16 * bpf_noise_buf ); + void post_decoder_ivas_fx( + Decoder_State *st, + Word16 synth_buf[], + Word16 pit_gain[], + Word16 pitch[], + Word16 signal_out[], + Word16 *bpf_noise_buf + ); + void cldfb_synth_set_bandsToZero( Decoder_State *st, Word32 **rAnalysis, @@ -9331,3 +9340,30 @@ uint32_t mvl2s_r( int16_t y[], /* o : output vector */ const int16_t n /* i : vector size */ ); + +void decoder_tcx_post_ivas_fx(Decoder_State *st_fx, + Word16 *synth, + Word16 *synthFB, + Word16 *A, + Word16 bfi, + Word16 MCT_flag +); + +void con_tcx_ivas_fx( + Decoder_State *st, /* i/o: coder memory state */ + Word16 synth[], /* i/o: synth[] *//*Q0 */ + const Word16 coh, /* i : coherence of stereo signal */ + Word16 * noise_seed, /* i/o: noise seed for stereo */ + const Word16 only_left, /* i : TD-PLC only in left channel */ + const Word16* A_cng /* i : CNG LP filter coefficients */ +); + +void ivas_mdct_core_reconstruct_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *x_fx[][NB_DIV], /* i/o: synthesis @internal_FS */ // Q(q_x) + Word16 signal_outFB_fx[CPE_CHANNELS][L_FRAME_PLUS], /* o : synthesis @output_FS */ // e_sig + Word16 fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + Word16 q_x, + Word16 e_sig +); diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 205e1df3de115683369ed8ea65508f11010ab328..b9aee1ac93d09fd7e5e17aa72a310fe175fdd596 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -333,6 +333,7 @@ void open_decoder_LPD( set16_fx(hTcxDec->old_synth, 0, OLD_SYNTH_INTERNAL_DEC); set16_fx(hTcxDec->synth_history_fx, 0, L_PROT48k + L_FRAME_MAX); + hTcxDec->q_synth_history_fx = 0; } set16_fx(st->syn, 0, M+1); @@ -1313,6 +1314,7 @@ void open_decoder_LPD_ivas_fx( set16_fx( hTcxDec->syn_OverlFB, 0, L_FRAME_MAX / 2 ); set16_fx( hTcxDec->old_synth, 0, OLD_SYNTH_INTERNAL_DEC ); set16_fx( hTcxDec->synth_history_fx, 0, L_PROT48k + L_FRAME_MAX ); + hTcxDec->q_synth_history_fx = 0; } set16_fx( st->syn, 0, M + 1 ); set16_fx( st->mem_syn_r, 0, L_SYN_MEM ); diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index b0ce60e1d3c161ba251edc4f1f2310cb73b11645..b2a8fce404e4381e748356551e52a8eb2e0337c1 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -1588,6 +1588,332 @@ void decoder_tcx_post(Decoder_State *st_fx, } } +#ifdef IVAS_FLOAT_FIXED +void decoder_tcx_post_ivas_fx(Decoder_State *st_fx, + Word16 *synth, + Word16 *synthFB, + Word16 *A, + Word16 bfi, + Word16 MCT_flag + ) +{ + Word16 i; + Word16 level_syn; + Word16 level_syn_e; + Word32 step; + Word16 gainCNG,gainCNG_e; + Word16 xn_buf[L_FRAME_MAX]; + Word16 tmp1, tmp2, s; + Word32 tmp32; + Word32 tmp32_1, tmp32_2; + TCX_DEC_HANDLE hTcxDec; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + hTcxDec = st_fx->hTcxDec; + + /* TCX output */ + Copy( synth, xn_buf, st_fx->L_frame ); + + /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */ + test(); + test(); + IF (!st_fx->bfi && st_fx->prev_bfi && EQ_16(st_fx->last_core,ACELP_CORE)) + { + hTcxDec->tcxltp_last_gain_unmodified = 0; + move16(); + } + + IF ( st_fx->hTcxLtpDec != NULL && st_fx->element_mode > EVS_MONO && ( st_fx->clas_dec == UNVOICED_CLAS || st_fx->clas_dec == INACTIVE_CLAS ) ) + { + /* deactivate TCX LTP for non-voiced frames */ + st_fx->hTcxLtpDec->tcxltp = 0; + move16(); + st_fx->hTcxLtpDec->tcxltp_gain = 0; + move16(); + } + + IF (bfi != 0 && st_fx->use_partial_copy == 0) + { + test(); + /* run lpc gain compensation not for waveform adjustment */ + IF ( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16(st_fx->plcInfo.concealment_method,TCX_TONAL))) + { + UWord32 dmy; + tmp32_1 /*gainHelperFB*/ = L_shl_r(L_deposit_h(hTcxDec->gainHelper) ,sub(hTcxDec->gainHelper_e, 31-28));/*Q28*/ + tmp32_2 /*stepCompensateFB*/= L_shl_r(L_deposit_h(hTcxDec->stepCompensate),sub(hTcxDec->stepCompensate_e,31-28));/*Q28*/ + + Mpy_32_32_ss(tmp32_2/*Q28*/, + L_shl(L_mult0(st_fx->L_frame, + getInvFrameLen(hTcxDec->L_frameTCX)/*Q21*/)/*Q21*/, + 8)/*Q29*/, + &tmp32_2, + &dmy ); /*Q26*/ + + tmp32_2 = L_shl(tmp32_2,3-1); /*Q28*/ + + FOR( i=0; i < hTcxDec->L_frameTCX; i++ ) + { + tmp32 = L_shl(tmp32_1/*Q28*/,-(28-15)); /*16Q15*/ +#ifdef BASOP_NOGLOB + synthFB[i] = round_fx_sat(L_shl_sat(Mpy_32_16_1(tmp32,synthFB[i]), 16)); +#else + synthFB[i] = round_fx(L_shl(Mpy_32_16_1(tmp32,synthFB[i]), 16)); +#endif + move16(); + tmp32_1 = L_sub(tmp32_1 , tmp32_2); + } + } + tmp32_1 /*gainHelper*/ = L_shl_r(L_deposit_h(hTcxDec->gainHelper) ,sub(hTcxDec->gainHelper_e, 31-28));/*Q28*/ + tmp32_2 /*stepCompensate*/= L_shl_r(L_deposit_h(hTcxDec->stepCompensate),sub(hTcxDec->stepCompensate_e,31-28));/*Q28*/ + FOR( i=0; i < st_fx->L_frame; i++ ) + { + tmp32 = L_shl(tmp32_1/*Q28*/,-(28-15)); /*16Q15*/ + xn_buf[i] = extract_l(Mpy_32_16_1(tmp32,xn_buf[i])); + move16(); + tmp32_1 = L_sub(tmp32_1 , tmp32_2); + } + } + + /* PLC: [TCX: Fade-out] + * PLC: estimate and update CNG energy */ + + /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */ + s = sub(getScaleFactor16(synthFB, hTcxDec->L_frameTCX), 4); + { + Word64 tmp64 = 0; + move64(); + FOR (i = 0; i < hTcxDec->L_frameTCX; i++) + { + tmp1 = shl(synthFB[i], s); + tmp64 = W_mac0_16_16(tmp64, tmp1, tmp1); + } + tmp32 = W_sat_l(tmp64); + } + tmp32 = Mpy_32_16_1(tmp32, getInvFrameLen(hTcxDec->L_frameTCX)); + tmp2 = norm_l(tmp32); +#ifdef BASOP_NOGLOB + tmp1 = round_fx_o(L_shl(tmp32, tmp2), &Overflow); +#else + tmp1 = round_fx(L_shl(tmp32, tmp2)); +#endif + s = sub(sub(sub(1, shl(s, 1)), 6/*table lookup for inverse framelength*/), tmp2); + tmp1 = Sqrt16(tmp1, &s); + move16(); + level_syn = tmp1; /*Q0*/ + + /* PLC: [TCX: Fade-out] + * PLC: estimate and update CNG energy */ + + level_syn_e = add(s,15); + test(); + test(); + IF (bfi == 0 && st_fx->tcxonly != 0 && ( NE_16(st_fx->element_mode, IVAS_CPE_MDCT) || MCT_flag ) && EQ_16(st_fx->clas_dec , UNVOICED_CLAS)) + { + + Word16 Qnew_levelBackgroundTrace; + Qnew_levelBackgroundTrace = 0; + move16(); + minimumStatistics(hTcxDec->conNoiseLevelMemory, /*Q15*/ + &hTcxDec->conNoiseLevelIndex, /*Q0 */ + &hTcxDec->conCurrLevelIndex, /*Q0 */ + &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/ + &hTcxDec->conLastFrameLevel, /*Q15*/ + level_syn, /*Q15*/ + hTcxDec->conNoiseLevelMemory_e, + hTcxDec->conCngLevelBackgroundTrace_e, + &Qnew_levelBackgroundTrace, + &hTcxDec->conLastFrameLevel_e, + level_syn_e /*scaling of level_syn*/ + ); + + /*note: All parameters being different from Q0 have to have the same Q-format*/ + + hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace; + move16(); + } + + /* PLC: [TCX: Fade-out] + * PLC: fade-out in time domain */ + IF (bfi != 0) + { + Word32 conceal_eof_gain32; + Word32 conceal_eof_gainFB; + move16(); + move16(); + gainCNG = 1; + gainCNG_e = 14+15+6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */ + IF (st_fx->tcxonly != 0) + { + /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/ + + IF(level_syn != 0) + { + BASOP_Util_Divide_MantExp ( + hTcxDec->conCngLevelBackgroundTrace, + hTcxDec->conCngLevelBackgroundTrace_e, + level_syn, + level_syn_e, + &gainCNG, + &gainCNG_e); + } + if ( st_fx->element_mode == IVAS_CPE_MDCT && !MCT_flag ) + { + if ( st_fx->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) + { + gainCNG = 0; + } + else if ( st_fx->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) + { + gainCNG *= 1.f - (float) ( st_fx->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } + } + ELSE + { + /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/ + IF(level_syn != 0) + { + BASOP_Util_Divide_MantExp ( + st_fx->cngTDLevel, + st_fx->cngTDLevel_e, + level_syn, + level_syn_e, + &gainCNG, + &gainCNG_e); + } + } + + if ((EQ_16(st_fx->nbLostCmpt, 1))) + { + hTcxDec->conceal_eof_gain = 16384/*1.0f Q14*/; /*Q14*/ move16(); + } + + /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */ + tmp2 = BASOP_Util_Add_MantExp( + mult_r(hTcxDec->conceal_eof_gain /*Q14*/, + hTcxDec->damping /*Q14*/), + 15-13/*->Q15*/, + mult_r(gainCNG/*Q15*/,sub(0x4000, hTcxDec->damping/*Q14*/)) /*Q14*/, + add(gainCNG_e,15-14)/*->Q15*/, + &tmp1); + tmp2 = BASOP_Util_Add_MantExp(hTcxDec->conceal_eof_gain, 15-14, negate(tmp1), tmp2, &tmp1); + +#ifdef BASOP_NOGLOB + step = L_shl_o(L_mult(tmp1, getInvFrameLen(st_fx->L_frame)), sub(tmp2, 6/*scaling from table lookup*/ + 1/*go to Q30*/), &Overflow); /*Q30*/ +#else + step = L_shl(L_mult(tmp1, getInvFrameLen(st_fx->L_frame)), sub(tmp2,6/*scaling from table lookup*/ +1/*go to Q30*/)); /*Q30*/ +#endif + { + Word32 stepFB; + UWord32 dmy; + conceal_eof_gainFB = L_deposit_h(hTcxDec->conceal_eof_gain); /*Q30*/ + Mpy_32_32_ss(step,L_shl(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)),8),&stepFB ,&dmy ); +#ifdef BASOP_NOGLOB + stepFB = L_shl_o(stepFB, 3 - 1, &Overflow); /*Q30*/ +#else + stepFB = L_shl(stepFB,3-1); /*Q30*/ +#endif + FOR( i=0; i < hTcxDec->L_frameTCX; i++ ) + { + synthFB[i] = round_fx(L_shl(Mpy_32_16_1(conceal_eof_gainFB, synthFB[i]),1)); + move16(); +#ifdef BASOP_NOGLOB + conceal_eof_gainFB = L_sub_o(conceal_eof_gainFB, stepFB, &Overflow); +#else + conceal_eof_gainFB = L_sub(conceal_eof_gainFB, stepFB); +#endif + } + } + conceal_eof_gain32 = L_deposit_h(hTcxDec->conceal_eof_gain); /*Q30*/ + FOR( i=0; i < st_fx->L_frame; i++ ) + { + xn_buf[i] = round_fx(L_shl(Mpy_32_16_1(conceal_eof_gain32 /*Q30*/, xn_buf[i]),1)); + move16(); +#ifdef BASOP_NOGLOB + conceal_eof_gain32 = L_sub_o(conceal_eof_gain32, step, &Overflow); +#else + conceal_eof_gain32 = L_sub(conceal_eof_gain32,step); +#endif + } +#ifdef BASOP_NOGLOB + hTcxDec->conceal_eof_gain = round_fx_o(conceal_eof_gain32, &Overflow); /*Q14*/ move16(); +#else + hTcxDec->conceal_eof_gain = round_fx(conceal_eof_gain32); /*Q14*/ move16(); +#endif + /* run lpc gain compensation not for waveform adjustment */ test(); + IF ( 0 == st_fx->enablePlcWaveadjust || EQ_16(st_fx->plcInfo.concealment_method,TCX_TONAL)) + { +#ifdef BASOP_NOGLOB + st_fx->plcInfo.recovery_gain = extract_h(L_shl_o(Mpy_32_16_1(conceal_eof_gainFB, + st_fx->last_concealed_gain_syn_deemph), + st_fx->last_concealed_gain_syn_deemph_e, &Overflow + ));/*Q30->Q14*/ +#else + st_fx->plcInfo.recovery_gain = extract_h(L_shl(Mpy_32_16_1(conceal_eof_gainFB, + st_fx->last_concealed_gain_syn_deemph), + st_fx->last_concealed_gain_syn_deemph_e + ));/*Q30->Q14*/ +#endif + } + ELSE + { + st_fx->plcInfo.recovery_gain = extract_h(conceal_eof_gainFB); /*Q14*/ + } + st_fx->plcInfo.step_concealgain_fx = +#ifdef BASOP_NOGLOB + round_fx_sat(L_shl_sat(L_mult0( round_fx_sat(step), round_fx_sat(L_shl_sat(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)), 8))), 3)); /*Q15*/ +#else + round_fx(L_shl(L_mult0( + round_fx(step), + round_fx(L_shl(L_mult0(st_fx->L_frame, getInvFrameLen(hTcxDec->L_frameTCX)),8))),3)); /*Q15*/ +#endif + } + + /*-----------------------------------------------------------* + * Memory update * + *-----------------------------------------------------------*/ + + /* Update synth, exc and old_Aq */ + tcx_decoder_memory_update(xn_buf, /*Q0*/ + synth, /*Q0*/ + A, + st_fx, + 0 + ); + + + /* PLC: [TCX: Memory update] */ + + st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr]; + move32(); + st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr+1]; + move32(); + Copy32(&st_fx->old_pitch_buf_fx[st_fx->nb_subfr+2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr); + set32_fx(&st_fx->old_pitch_buf_fx[st_fx->nb_subfr+2], st_fx->old_fpitch, st_fx->nb_subfr); +#ifdef BASOP_NOGLOB /*TBV st_fx->old_fpitch seems to have an odd value for this bitstream stv48n1_dtx_sw_164_1280_48kHz.f06.COD at frame 10 */ + st_fx->bfi_pitch_fx = shl_sat(round_fx(st_fx->old_fpitch),6); +#else + st_fx->bfi_pitch_fx = shl(round_fx(st_fx->old_fpitch),6); +#endif + st_fx->bfi_pitch_frame = st_fx->L_frame; + move16(); + + st_fx->mem_pitch_gain[2*st_fx->nb_subfr+1] = st_fx->mem_pitch_gain[st_fx->nb_subfr+1]; + move16(); + st_fx->mem_pitch_gain[2*st_fx->nb_subfr] = st_fx->mem_pitch_gain[st_fx->nb_subfr]; + move16(); + + FOR (i = 0; i < st_fx->nb_subfr; i++) + { + st_fx->mem_pitch_gain[2*st_fx->nb_subfr-1 - i] = st_fx->mem_pitch_gain[st_fx->nb_subfr-1 - i]; + move16(); + st_fx->mem_pitch_gain[st_fx->nb_subfr-1 - i] = hTcxDec->tcxltp_last_gain_unmodified; + move16(); + } +} +#endif static Word32 CalculateAbsEnergy( /* o : normalized result Q31 */ const Word32 L_off, /* i : initial sum value Qn */ diff --git a/lib_dec/er_dec_tcx_fx.c b/lib_dec/er_dec_tcx_fx.c index ca81d2706eb0501d16df1f7d1f7b5a248e7eb5ab..c8fed1e05ffed4f7fc869154eba8e1abec42b95b 100644 --- a/lib_dec/er_dec_tcx_fx.c +++ b/lib_dec/er_dec_tcx_fx.c @@ -1080,3 +1080,961 @@ void con_tcx( return; } +#ifdef IVAS_FLOAT_FIXED +void con_tcx_ivas_fx( + Decoder_State *st, /* i/o: coder memory state */ + Word16 synth[], /* i/o: synth[] *//*Q0 */ + const Word16 coh, /* i : coherence of stereo signal */ + Word16 * noise_seed, /* i/o: noise seed for stereo */ + const Word16 only_left, /* i : TD-PLC only in left channel */ + const Word16* A_cng /* i : CNG LP filter coefficients */ +) +{ + Word16 i, s, c, L_frame, L_subfr, fLowPassFilter, T0; + Word16 n, mem_syn_r_size_old, mem_syn_r_size_new; + Word16 *noise; + Word16 mem_syn[M], *syn; + Word16 *exc, buf[OLD_EXC_SIZE_DEC+L_FRAME_MAX+L_FRAME_MAX/NB_SUBFR+1+L_FRAME_MAX/2]; + Word16 pre_emph_buf; + Word16 hp_filt[L_FIR_FER2]; + Word16 alpha; + Word16 tmp_deemph, gain, gainCNG, gain_inov; + Word16 *pt_exc, *pt1_exc; + Word16 Tc, tmpSeed; + Word16 fUseExtrapolatedPitch; + Word16 *ana_window; + Word16 r_h[M+1], A_local[M+1], mem, r_l[M+1]; + PWord16 const *w; + Word16 W1, W2, W12; + Word16 Q_r; + Word16 tmp16, tmp16_2, tmp_loop, tmp_e, gain_tmp; + Word16 gainCNG_e, noise_e, gain_inov_e ;/*Exponents for gainCNG, noise, gain_inov*/ + Word16 Q_syn; /*Q format of temporary synthesis buffer syn*/ + Word32 L_tmp, L_tmp2, step32_tmp; + Word32 predPitchLag, pitch_buf[NB_SUBFR16k], step32, gain32; + Word16 extrapolationFailed; + Word16 gainSynthDeemph; + Word16 gainSynthDeemph_e; + Word32 old_pitch_buf[2*NB_SUBFR16k+2]; + Word16 Q_exc, new_Q, exp_scale; + Word16 offset; + HQ_DEC_HANDLE hHQ_core; + TCX_LTP_DEC_HANDLE hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec; + + hTcxLtpDec = st->hTcxLtpDec; + hHQ_core = st->hHQ_core; + hTcxDec = st->hTcxDec; + + /* inits */ + alpha = 0; + move16(); + fUseExtrapolatedPitch = 0; + move16(); + extrapolationFailed = 1; + move16(); + + noise_e = 0; + move16(); + Q_syn = -1; /*Q format of temporary synthesis buffer syn*/ move16(); + offset = 0; + move16(); + + /* Framing parameters */ + L_frame = hTcxDec->L_frameTCX; + move16(); + /* L_subfr = st->L_frameTCX/st->nb_subfr */ + L_subfr = mult_r(hTcxDec->L_frameTCX,div_s(1,st->nb_subfr)); + assert( L_subfr == hTcxDec->L_frameTCX/st->nb_subfr ); + move32(); + w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument*/ + W1 = st->hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + W2 = shr(st->hTcxCfg->tcx_mdct_window_lengthFB, 1); + W12 = shr(W1,1); + + /* take the previous frame last pitch */ + Tc = round_fx(st->old_fpitchFB); + + + set16_fx(buf,0, OLD_EXC_SIZE_DEC + L_FRAME_MAX + L_FRAME_MAX / NB_SUBFR + 1 + L_FRAME_MAX / 2); /* initialize buf with 0 */ + //set16_fx(buf,0,shr(sizeof(buf),1)); /* initialize buf with 0 */ + + c = BASOP_Util_Divide1616_Scale( + L_frame, + st->L_frame, + &s + ); + + FOR (i=0; i < (2*NB_SUBFR16k+2); i++) + { + old_pitch_buf[i] = L_shl(Mpy_32_16_1(st->old_pitch_buf_fx[i],c),s); + move32(); + } + + /* set excitation memory*/ + exc = buf+OLD_EXC_SIZE_DEC; + tmp_deemph = synth[-1]; + move16(); + pre_emph_buf = synth[-1]; + move16(); + + test(); + IF ( (EQ_16( st->nbLostCmpt, 1 ))|| hTcxDec->tcxConceal_recalc_exc) + { + /* apply pre-emphasis to the signal */ + mem = synth[-((shr(L_frame,1))+ hTcxDec->pit_max_TCX+M+M)-1]; + Q_exc = E_UTIL_f_preemph3(&(synth[-((shr(L_frame,1))+ hTcxDec->pit_max_TCX+2*M)]), st->preemph_fac, add(add(shr(L_frame,1), hTcxDec->pit_max_TCX),shl(M,1)), &mem,1); + st->Mode2_lp_gainc = L_deposit_l(0); + + st->Mode2_lp_gainp = get_gain2( synth-2*L_subfr, synth-2*L_subfr-Tc, shl(L_subfr,1) ); + move32(); + + st->Mode2_lp_gainp = L_max(st->Mode2_lp_gainp,0); + st->Mode2_lp_gainp = L_min(st->Mode2_lp_gainp,65536l/*1.0f Q16*/); + st->Mode2_lp_gainp = L_shl(st->Mode2_lp_gainp, 13); + + ana_window = buf; + ham_cos_window(ana_window, mult(L_frame,24576/*0.75f Q15*/), shr(L_frame,2)); + + /* Autocorrelation */ + autocorr_fx(&(synth[-L_frame-1]), M, r_h ,r_l , &Q_r , L_frame, ana_window, 0, 0); + + /* Lag windowing */ + lag_wind( r_h,r_l, M, st->output_Fs, LAGW_STRONG ); + + /* Levinson Durbin */ + E_LPC_lev_dur(r_h, r_l, A_local, NULL, M, NULL); + + /* copy for multiple frame loss */ + Copy(A_local, st->old_Aq_12_8_fx, M+1); + + /* Residu */ + assert((2*L_subfr+Tc+1+M) <= hTcxDec->old_synth_lenFB); + + BASOP_SATURATE_WARNING_OFF_EVS /*saturation possible in case of spiky synthesis*/ + Residu3_fx( + A_local, + &(synth[-(2*L_subfr+Tc+1+M)]), /*Qx = Q0*/ + &(exc[-(2*L_subfr+Tc+1+M)]), /*Qx+1 = Q1*/ + add(add(add(shl(L_subfr,1),Tc),1),M), + 1); + BASOP_SATURATE_WARNING_ON_EVS + } + ELSE + { + /* apply pre-emphasis to the signal */ + mem = synth[-L_frame-1]; + Q_exc = E_UTIL_f_preemph3(&(synth[-L_frame]), st->preemph_fac, L_frame, &mem, 1); + Copy(st->old_Aq_12_8_fx, A_local, M+1); + + offset = shr(L_frame,1); + IF(GE_16(st->last_good, UNVOICED_TRANSITION)) + { + tmp16 = s_max(Tc - shr(L_frame,1), 0); + Copy_Scale_sig(hTcxDec->old_excFB_fx, &(exc[-tmp16]), offset+tmp16, Q_exc-st->Q_exc); + } + ELSE { + Copy_Scale_sig(hTcxDec->old_excFB_fx, &(exc[-2*L_subfr]), 2*L_subfr+offset, Q_exc-st->Q_exc); + } + } + + /*-----------------------------------------------------------------* + * PLC: Construct the harmonic part of excitation + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( GT_16(st->last_good, UNVOICED_CLAS)&&!(EQ_16(st->last_good,UNVOICED_TRANSITION)&&EQ_16(st->core_ext_mode,GENERIC))) + { + + IF ( EQ_16(st->nbLostCmpt,1)|| hTcxDec->tcxConceal_recalc_exc) + { + calcGainc( exc, Q_exc, st->old_fpitchFB, L_subfr, st->Mode2_lp_gainp, &(st->Mode2_lp_gainc)); + } + + tmp16 = 0; + move16(); + if (GT_32(st->output_Fs , 25600)) + { + tmp16 = 1; + move16(); + } + + test(); + test(); + test(); + test(); + IF( ((EQ_16(st->nbLostCmpt,1))|| hTcxDec->tcxConceal_recalc_exc)&&GE_16(st->rf_frame_type,RF_TCXFD)&&LE_16(st->rf_frame_type,RF_TCXTD2)&&st->use_partial_copy) + { + Word32 tcxltp_pitch_tmp = L_add(L_deposit_h(hTcxLtpDec->tcxltp_pitch_int), L_shl(L_deposit_l(div_s(hTcxLtpDec->tcxltp_pitch_fr,st->pit_res_max)),1)); /*15Q16*/ + Word16 scale_tmp = mult_r(hTcxDec->L_frameTCX, getInvFrameLen(st->L_frame)); /*getInvFrameLen()->9Q6*/ + Word16 tmp_shift = norm_s(scale_tmp); + predPitchLag = L_shl(Mpy_32_16_1(tcxltp_pitch_tmp, shl(scale_tmp, tmp_shift)), sub(9, tmp_shift)); + + T0 = round_fx(predPitchLag); + + test(); + test(); + test(); + if ( (T0 > 0) + && (NE_16(T0,Tc) ) + && (LT_32(L_deposit_h(abs_s(sub(T0,Tc)))/*Q16*/ , L_mult(4915/*.15f Q15*//*Q15*/,Tc/*Q0*/) /*Q16*/ ) ) + ) + { + fUseExtrapolatedPitch = 1; + move16(); + } + } + ELSE + { + + pitch_pred_linear_fit( + st->nbLostCmpt, + st->last_good, + old_pitch_buf, + &(st->old_fpitchFB), + &predPitchLag, + hTcxDec->pit_min_TCX, + hTcxDec->pit_max_TCX, + st->mem_pitch_gain, + tmp16, + st->plc_use_future_lag, + &extrapolationFailed, + st->nb_subfr + ); + + T0 = round_fx(predPitchLag); + test(); + test(); + test(); + if ( (T0 > 0) + && (NE_16(T0,Tc) ) + && (LT_32(L_deposit_h(abs_s(sub(T0,Tc)))/*Q16*/ , L_mult(4915/*.15f Q15*//*Q15*/,Tc/*Q0*/) /*Q16*/ ) ) + && (extrapolationFailed == 0) + ) + { + fUseExtrapolatedPitch = 1; + move16(); + } + } + + + fLowPassFilter = 0; + move16(); + pt_exc = exc + offset; + pt1_exc = pt_exc - Tc; + + if (fUseExtrapolatedPitch != 0) + { + pt_exc = buf; + } + test(); + IF( LT_16(st->stab_fac_fx ,32767/*1.f Q15*/)&&EQ_16(st->nbLostCmpt,1)) + { + /* pitch cycle is first low-pass filtered */ + + IF (LE_32(st->output_Fs , 16000)) + { + FOR( i=0 ; i< Tc; i++ ) + { + move16(); + *pt_exc++ = mac_r(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac( + L_mult(174/* 0.0053f Q15*/, pt1_exc[-5]), + 0/* 0.0000f Q15*/, pt1_exc[-4]), + -1442/*-0.0440f Q15*/, pt1_exc[-3]), + 0/* 0.0000f Q15*/, pt1_exc[-2]), + 8641/* 0.2637f Q15*/, pt1_exc[-1]), + 18022/* 0.5500f Q15*/, pt1_exc[0] ), + 8641/* 0.2637f Q15*/, pt1_exc[1] ), + 0/* 0.0000f Q15*/, pt1_exc[2] ), + -1442/*-0.0440f Q15*/, pt1_exc[3] ), + 0/* 0.0000f Q15*/, pt1_exc[4] ), + 174/* 0.0053f Q15*/, pt1_exc[5] ); + pt1_exc++; + } + } + ELSE /*(st->output_Fs >= 32000)*/ + { + FOR( i=0 ; i< Tc; i++ ) + { + move16(); + *pt_exc++ = mac_r(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac(L_mac( + L_mult(-174/*-0.0053f Q15*/, pt1_exc[-5]), + -121/*-0.0037f Q15*/, pt1_exc[-4]), + -459/*-0.0140f Q15*/, pt1_exc[-3]), + 590/* 0.0180f Q15*/, pt1_exc[-2]), + 8743/* 0.2668f Q15*/, pt1_exc[-1]), + 16355/* 0.4991f Q15*/, pt1_exc[0] ), + 8743/* 0.2668f Q15*/, pt1_exc[1] ), + 590/* 0.0180f Q15*/, pt1_exc[2] ), + -459/*-0.0140f Q15*/, pt1_exc[3] ), + -121/*-0.0037f Q15*/, pt1_exc[4] ), + -174/*-0.0053f Q15*/, pt1_exc[5] ); + pt1_exc++; + } + } + + fLowPassFilter = 1; + move16(); + } + ELSE + { + /* copy the first pitch cycle without low-pass filtering */ + FOR( i=0 ; i < Tc; i++ ) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + fLowPassFilter = 1; + move16(); + } + + if (fUseExtrapolatedPitch != 0) + { + pt1_exc = buf; + } + tmp16 = add(sub(L_frame,imult1616(fLowPassFilter,Tc)),L_subfr); + FOR (i = 0; i < tmp16; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + + IF (fUseExtrapolatedPitch != 0) + { + get_subframe_pitch(st->nb_subfr, + st->old_fpitch, + /* predPitchLag * L_frame/st->L_frame, */ + L_shr(Mpy_32_16_1(predPitchLag/*Q16*/, + mult_r(st->L_frame/*Q0*/, + getInvFrameLen(L_frame)/*Q21*/ + )/*Q6*/ + )/*Q7*/, + 7-16)/*Q16*/, + pitch_buf); + + PulseResynchronization(buf, exc, L_frame, st->nb_subfr, st->old_fpitchFB, predPitchLag); + } + ELSE + { + set32_fx( pitch_buf, st->old_fpitch, st->nb_subfr); + } + + IF ( EQ_16(st->nbLostCmpt , 1)) + { + pt_exc = exc+L_frame; + IF (T0 == 0) + { + pt1_exc = pt_exc - Tc; + } + ELSE + { + pt1_exc = pt_exc - T0; + } + + tmp_loop = shr(L_frame,1); + FOR (i = 0; i < tmp_loop; i++) + { + *pt_exc++ = *pt1_exc++; + move16(); + } + } + + if (fUseExtrapolatedPitch != 0) + { + st->old_fpitchFB = predPitchLag; + move16(); + } + st->bpf_gain_param = 0; + move16(); + + /* PLC: calculate damping factor */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + alpha = 1.0f; + if (st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } + else if (st->element_mode != IVAS_CPE_MDCT) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } +#else + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &(st->Mode2_lp_gainp), 0);/*Q14*/ +#endif + IF ( EQ_16(st->nbLostCmpt , 1)) + { + st->cummulative_damping = 32767/*1.f Q15*/; + move16(); + } + ELSE + { +#ifdef BASOP_NOGLOB + st->cummulative_damping = shl_sat(mult_r_sat(st->cummulative_damping/*Q15*/,alpha/*Q14*/),1)/*Q15*/; +#else + st->cummulative_damping = shl(mult_r(st->cummulative_damping/*Q15*/,alpha/*Q14*/),1)/*Q15*/; +#endif + } + + gain32 = L_add(2147483647l/*1.f Q31*/, 0); /*Q31*/ + gain = 32767/*1.f Q15*/; /*Q15*/ move16(); + if( EQ_16(st->rf_frame_type, RF_TCXTD1)&&EQ_16(st->use_partial_copy,1)) + { + gain32 = 1073741824l/*0.5f Q31*/; + gain = 16384/*0.5f Q15*/; + } + + /*step = (1.0f/(L_frame+(L_frame/2))) * (gain - alpha);*/ + tmp16 = shr(imult1616(3,L_frame),1); + tmp_e = norm_s(tmp16); + tmp16 = shl(tmp16,tmp_e); + tmp16 = div_s(16384/*1.f Q14*/,tmp16);/*Q15,1+tmp_e-15*/ + tmp16_2 = sub(shr(gain,1),alpha)/*Q14*/; + step32 = L_shl(L_mult(tmp16,tmp16_2)/*Q30, 1+tmp_e-15*/,add(1-14,tmp_e))/*Q31*/; + + /* PLC: Apply fade out */ + tmp_loop = shr(imult1616(L_frame,3),1); + FOR ( i=offset; i < tmp_loop; i++ ) + { +#ifdef BASOP_NOGLOB + exc[i] = mult_r(exc[i], round_fx_sat(gain32))/*Q1*/; + move16(); + gain32 = L_sub_sat(gain32, step32); +#else + exc[i] = mult_r(exc[i],round_fx(gain32))/*Q1*/; + move16(); + gain32 = L_sub(gain32, step32); +#endif + + } + + /* update old exc without random part */ + offset = s_max(round_fx(st->old_fpitchFB) - shr(L_frame,1), 0); + Copy(exc+L_frame-offset, hTcxDec->old_excFB_fx, shr(L_frame,1)+offset); + /* copy old_exc as 16kHz for acelp decoding */ + IF ( EQ_16(st->nbLostCmpt, 1)) + { + lerp(exc - shr(L_frame,1), st->old_exc_fx, L_EXC_MEM_DEC, add(L_frame, shr(L_frame,1))); + } + ELSE + { + Copy(st->old_exc_fx+L_FRAME16k, st->old_exc_fx, L_FRAME16k/2); + lerp(exc, st->old_exc_fx+L_FRAME16k/2, L_FRAME16k, L_frame); + } + st->Q_exc = Q_exc; + } + ELSE + { + /* No harmonic part */ + set16_fx(&exc[0], 0, add(L_frame,shr(L_frame,1))); + IF ( EQ_16(st->nbLostCmpt , 1)) + { + calcGainc2(&exc[0], Q_exc, L_subfr, &(st->Mode2_lp_gainc)); + } + set32_fx( pitch_buf, L_deposit_h(L_SUBFR), st->nb_subfr); + /* PLC: calculate damping factor */ +#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + alpha = 1.0f; + if (st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } + else if (st->element_mode != IVAS_CPE_MDCT) + { + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &(st->lp_gainp), 0); + } +#else + alpha = Damping_fact(st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac_fx, &(st->Mode2_lp_gainp), 0);/*Q14*/ +#endif + } + + /*-----------------------------------------------------------------* + * Construct the random part of excitation + *-----------------------------------------------------------------*/ +#ifndef IVAS_CODE_CON_TCX + IF (coh != -16384) + { + Word16 tmpSeed1; + Word16 alpha_coh; + Word16 random1, random2; + + tmpSeed1 = *noise_seed; + noise = buf; + noise_e = 1; + Word16 e = 0; + alpha_coh = 0; + + IF(NE_16(coh, 16384)) + { + alpha_coh = Sqrt16(div_s((16384 - coh), (16384 + coh)), &e); + } + IF (st->idchan == 1) + { + alpha_coh = negate(alpha_coh); + } + + FOR (i = 0; i < L_frame + L_FIR_FER2 - 1; i++) + { + random1 = own_random2_fx(&tmpSeed1); + random2 = own_random2_fx(&tmpSeed1); + noise[i] = add(shr(random1, noise_e), shr(mult(alpha_coh, random2), noise_e)); + } + + IF (st->idchan == 1 || only_left) + { + *noise_seed = tmpSeed1; + } + + FOR (; i < L_frame + (L_frame / 2) + 2 * L_FIR_FER2; i++) + { + random1 = own_random2_fx(&tmpSeed1); + random2 = own_random2_fx(&tmpSeed1); + noise[i] = add(shr(random1, noise_e), shr(mult(alpha_coh, random2), noise_e)); + } + } + ELSE +#endif /*IVAS_CODE_CON_TCX*/ + { + tmpSeed = st->seed_acelp; + move16(); + noise = buf; + noise_e = 1;/*set exponent of noise to 1*/ move16(); + + tmp_loop = add(L_frame, L_FIR_FER2 - 1); + FOR(i = 0; i < tmp_loop; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise[i] = shr(tmpSeed, noise_e); + move16(); + } + st->seed_acelp = tmpSeed; + move16(); + + tmp_loop = add(add(L_frame, shr(L_frame, 1)), shl(L_FIR_FER2, 1)); + FOR(; i < tmp_loop; i++) + { + tmpSeed = own_random2_fx(tmpSeed); + noise[i] = shr(tmpSeed, noise_e); + move16(); + } + } + test(); + IF (EQ_16(st->last_good , VOICED_CLAS)||EQ_16(st->last_good,ONSET)) + { + tmp16 = 19661/*0.6f Q15*/; + move16(); + if ( LE_32(st->output_Fs,16000)) + { + tmp16 = 6554/*0.2f Q15*/; + move16(); + } + + mem = noise[0]; + move16(); + preemph_copy_fx(&noise[1], &noise[1], tmp16, L_frame+(L_frame/2)+L_FIR_FER2, &mem); + } + /* high rate filter tuning */ + IF ( LE_32(st->output_Fs,16000)) + { + FOR( i=0; i< L_FIR_FER2; i++ ) + { + hp_filt[i] = h_high3_16[i]; + move16(); + } + } + ELSE /*(st->output_Fs==32000)*/ + { + FOR( i=0; i< L_FIR_FER2; i++ ) + { + hp_filt[i] = h_high3_32[i]; + move16(); + } + } + IF ( EQ_16(st->nbLostCmpt,1)) + { + highPassFiltering(st->last_good, add(add(L_frame, shr(L_frame,1)),L_FIR_FER2), noise, hp_filt, L_FIR_FER2); + } + ELSE + { + IF(GT_16( st->last_good , UNVOICED_TRANSITION)) + { + tmp_loop = add(add(L_frame,shr(L_frame,1)),L_FIR_FER2); + gain_tmp = negate(add(-32768,st->cummulative_damping));/*Q15*/ + FOR( i=0 ; i < tmp_loop; i++ ) + { + Word16 j; + L_tmp2 = 0; move32(); + for (j=11; j>0; j--) + { + L_tmp2 = L_mac(L_tmp2, noise[i+L_FIR_FER2-j], hp_filt[L_FIR_FER2-j]); + } + L_tmp2 = Mpy_32_16_1(L_tmp2, st->cummulative_damping/*Q15*/);/*Q0, noise_e*/ + noise[i] = mac_r(L_tmp2, gain_tmp,noise[i]);/*Q15, noise_e*/ + } + } + } + + /* PLC: [TCX: Fade-out] retrieve background level */ +#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + tmp16 = 32767; + IF (A_cng != NULL) + { + gainSynthDeemph = shr(getLevelSynDeemph(&(tmp16), A_cng, M, shr(L_frame, 2), st->preemph_fac, 1, &gainSynthDeemph_e) , 2); + } + ELSE + { + gainSynthDeemph = getLevelSynDeemph(&(tmp16), A_local, M, shr(L_frame, 2), st->preemph_fac, 1, &gainSynthDeemph_e); + } +#else + tmp16 = 32767; + move16(); + gainSynthDeemph = getLevelSynDeemph(&(tmp16), A_local, M, shr(L_frame,2), st->preemph_fac, 1, &gainSynthDeemph_e); +#endif + IF (0 != st->tcxonly) + { + /* gainCNG = st->conCngLevelBackgroundTrace/gainSynthDeemph; */ + BASOP_Util_Divide_MantExp(hTcxDec->conCngLevelBackgroundTrace, + hTcxDec->conCngLevelBackgroundTrace_e, + gainSynthDeemph, gainSynthDeemph_e, + &gainCNG, &gainCNG_e); +#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + IF (st->element_mode == IVAS_CPE_MDCT && A_cng != NULL) + { + IF (GT_16(st->nbLostCmpt, add(MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME, MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN))) + { + gainCNG = 0; + } + ELSE IF (GT_16(st->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME)) + { + gainCNG *= 1.f - (float)(st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif + } + ELSE + { + /* gainCNG = st->cngTDLevel/gainSynthDeemph; */ + BASOP_Util_Divide_MantExp(st->cngTDLevel, + st->cngTDLevel_e, + gainSynthDeemph, gainSynthDeemph_e, + &gainCNG, &gainCNG_e); + } + + gain32 = L_add(st->Mode2_lp_gainc, 0); /* start-of-the-frame gain - Q16*/ + IF( EQ_16(st->rf_frame_type, RF_TCXTD1)&&EQ_16(st->use_partial_copy,1)) + { + gain32 = Mpy_32_16_1(gain32, 22938/*0.7f Q15*/); + } + L_tmp = L_shl(gain32,1); + + IF (GT_32(L_shl(L_deposit_h(gainCNG),sub(gainCNG_e,31-16)/*Q16*/) , L_tmp)) + { + gainCNG_e = sub(15+1,norm_l(L_tmp)); + gainCNG = extract_l(L_shr(L_tmp,gainCNG_e));/*Q15,gainCNG_e*/ + gainCNG_e = sub(gainCNG_e,1); + } + + /* st->Mode2_lp_gainc = alpha * (st->Mode2_lp_gainc) + (1.0f - alpha) * gainCNG;*/ /* end-of-the-frame gain */ + + L_tmp = Mpy_32_16_1(st->Mode2_lp_gainc,alpha)/*Q15*/; + L_tmp2 = L_mult(sub(16384/*1.f Q14*/,alpha)/*Q14*/,gainCNG/*Q15,gainCNG_e*/);/*Q30,gainCNG_e*/ + st->Mode2_lp_gainc = BASOP_Util_Add_Mant32Exp(L_tmp,31-15,L_tmp2,add(gainCNG_e,31-30),&tmp_e);/*Q31*/ move32(); + st->Mode2_lp_gainc = L_shl(st->Mode2_lp_gainc,sub(tmp_e,31-16)); + move32(); + + /* PLC: [TCX: Fade-out] Linearly attenuate the gain through the frame */ + /*step = (1.0f/L_frame) * (gain - (st->Mode2_lp_gainc));*/ + L_tmp = L_sub(gain32,st->Mode2_lp_gainc);/*Q16*/ + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp,tmp_e);/*Q16,-tmp_e*/ + step32 = Mpy_32_16_1(L_tmp/*Q16,-tmp_e*/,getInvFrameLen(L_frame)/*W16Q21*/);/*Q22,-tmp_e*/ + step32 = L_shl(step32,sub((25-22),tmp_e));/*Q25*/ + + pt_exc = noise + L_FIR_FER2/2; + + /*gain_inov = 1.0f / (float)sqrt( dot_product( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );*//* normalize energy */ + L_tmp = Dot_productSq16HQ(0,pt_exc/*Q0,15+1*/,L_frame,&tmp_e)/*Q31,tmp_e+16+16*/; + L_tmp = Mpy_32_16_1(L_tmp,getInvFrameLen(L_frame)/*W16Q21*/)/*W32Q37,tmp_e+16+16*//*Q5,tmp_e*/; + tmp_e = add(tmp_e,31-5);/*-->Q31*/ + gain_inov = 0; + gain_inov_e = 0; + move16(); + move16(); + IF(NE_32(L_tmp, 0)) + { + gain_inov = round_fx(ISqrt32(L_tmp,&tmp_e));/*Q15,tmp_e*/ + gain_inov_e = tmp_e; + move16(); + } + test(); + test(); + IF (EQ_16(st->last_good , UNVOICED_CLAS)&&NE_16(st->core_ext_mode,UNVOICED)) + { + gain_inov = mult_r(gain_inov,26214/*0.8f Q15*/); + } + ELSE IF (!( EQ_16(st->last_good , UNVOICED_CLAS)||EQ_16(st->last_good,UNVOICED_TRANSITION))) + { + /*gain_inov *= (1.1f- 0.75*st->lp_gainp);*/ + L_tmp = Mpy_32_16_1(L_sub(590558016l/*1.1f Q29*/, Mpy_32_16_1(st->Mode2_lp_gainp,24576))/*Q29*/,gain_inov/*Q15,gain_inov_e*/);/*Q29,gain_inov_e*/ + tmp_e = norm_l(L_tmp); + L_tmp = L_shl(L_tmp,tmp_e); + gain_inov_e = add(sub(gain_inov_e,tmp_e),31-29);/*->Q31*/ + gain_inov = round_fx(L_tmp);/*Q15,gain_inov_e*/ + } + + st->Mode2_lp_gainp = L_shr(L_deposit_h(alpha/*Q14*/)/*Q14+16*/,1);/*Q29*/ + pt_exc = noise; /* non-causal ringing of the FIR filter */ + + tmp_e = norm_l(gain32); + tmp_e = sub(tmp_e,5); /*5 Bit additional Headroom for the gain - should be enough*/ + gain32 = L_shl(gain32,tmp_e);/*Q16,-tmp_e*/ + L_tmp = Mpy_32_16_1(gain32/*Q16,-tmp_e*/, gain_inov/*Q15,gain_inov_e*/)/*Q16,gain_inov_e-tmp_e*/; + + gain_tmp = round_fx(L_tmp);/*Q0, gain_inov_e-tmp_e*/ + + FOR( i=0 ; i< L_FIR_FER2/2; i++ ) + { + *pt_exc = mult_r(*pt_exc,gain_tmp);/*Q-15,noise_e+gain_inov_e-tmp_e*/ move16(); + pt_exc++; + } + tmp16 = add(L_frame,L_FIR_FER2/2); + step32_tmp = L_shl(step32/*Q25*/,sub(tmp_e,(25-16)));/*Q16,-tmp_e*/ + FOR( i=0 ; i< tmp16; i++ ) /* Actual filtered random part of excitation */ + { + *pt_exc = mult_r(*pt_exc, gain_tmp); + move16(); + pt_exc++; + gain32 = L_sub(gain32/*Q16,-tmp_e*/,step32_tmp);/*Q16,-tmp_e*/ + gain_tmp = mult_r(round_fx(gain32/*Q16,-tmp_e*/)/*Q0*/, gain_inov/*Q15,gain_inov_e*/)/*Q0,gain_inov_e-tmp_e*/; + } + tmp16 = shr(L_frame,1); + FOR( i=0 ; i< tmp16; i++ ) /* causal ringing of the FIR filter */ + { + *pt_exc = mult_r(*pt_exc , gain_tmp); + move16(); + pt_exc++; + } + noise_e = add(sub(add(noise_e,gain_inov_e),tmp_e),15);/*--> noise is Q0, noise_e*/ + /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/ + + /*-----------------------------------------------------------------* + * Construct the total excitation + *-----------------------------------------------------------------*/ + + IF( GE_16(st->last_good , UNVOICED_TRANSITION)) + { + tmp16 = add(L_frame,shr(L_frame,1)); + FOR( i=0 ; i< tmp16; i++ ) + { +#ifdef BASOP_NOGLOB + exc[i] = add_sat(exc[i], shl_sat(noise[i + (L_FIR_FER2 / 2)], Q_exc + noise_e));/*Q1*/ move16(); +#else + exc[i] = add(exc[i] , shl(noise[i+(L_FIR_FER2/2)],Q_exc+noise_e));/*Q1*/ move16(); +#endif + } + } + ELSE + { + bufferCopyFx(noise+L_FIR_FER2/2, exc, add(L_frame , shr(L_frame,1)),0/*Q_noise*/, noise_e, Q_exc, 0/*exc_e*/); + Copy(exc+L_frame-2*L_subfr, hTcxDec->old_excFB_fx, 2*L_subfr+shr(L_frame,1)); + /* copy old_exc as 16kHz for acelp decoding */ + IF ( EQ_16(st->nbLostCmpt, 1)) + { + lerp(exc, st->old_exc_fx, L_EXC_MEM_DEC, add(L_frame, shr(L_frame,1))); + } + ELSE { + Copy(st->old_exc_fx+L_FRAME16k, st->old_exc_fx, L_FRAME16k/2); + lerp(exc, st->old_exc_fx+L_FRAME16k/2, L_FRAME16k, L_frame); + } + st->Q_exc = Q_exc; + } + /*buf[0;L_FIR_FER2 + L_Frame + L_Frame/2] Q0, noise_e*/ + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1*/ + + /* Update Pitch Lag memory */ + Copy32( &st->old_pitch_buf_fx[st->nb_subfr], st->old_pitch_buf_fx, st->nb_subfr ); + Copy32( pitch_buf, &st->old_pitch_buf_fx[st->nb_subfr], st->nb_subfr ); + + /*----------------------------------------------------------* + * - compute the synthesis speech * + *----------------------------------------------------------*/ + + syn = buf + M; + Copy(synth-M, buf, M); + + new_Q = sub(Q_exc, 3); + new_Q = s_max(new_Q, -1); + + tmp16 = s_min(new_Q, st->prev_Q_syn); + st->prev_Q_syn = new_Q; + move16(); + + exp_scale = sub(tmp16, Q_exc-1); + Q_syn = tmp16; + move16(); + + Copy_Scale_sig(buf, mem_syn, M, exp_scale); + +#ifdef BASOP_NOGLOB + tmp_deemph = shl_sat(tmp_deemph,Q_syn); +#else + tmp_deemph = shl(tmp_deemph,Q_syn); +#endif + st->Q_syn = Q_syn; + + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame] Q1: exc*/ + /*buf[0;M] Q0: mem_syn*/ +#ifndef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + if (A_cng != NULL) + { + Word16 alpha_delayed; + + alpha_delayed = 16384; + IF (st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE) + { + alpha_delayed = Damping_fact(st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_DELAY_4_LSP_FADE, st->last_good, st->stab_fac_fx, &(st->Mode2_lp_gainp), ACELP_CORE); + } + + IF (st->plcBackgroundNoiseUpdated && alpha_delayed != 16384) + { + Word16 lsp_local[M], lsp_fade[M], alpha_inv; + + alpha_inv = 16384 - alpha_delayed; + + E_LPC_a_lsp_conversion(A_local, lsp_local, lsp_local, M); + + FOR (i = 0; i < M; i++) + { + lsp_fade[i] = alpha_delayed * lsp_local[i] + alpha_inv * st->lspold_cng[i]; + } + + E_LPC_f_lsp_a_conversion(lsp_fade, A_local, M); + } + } +#endif + E_UTIL_synthesis( + sub(Q_exc, Q_syn), + A_local, + &exc[0], + &syn[0], + add(L_frame, shr(L_frame,1)), + mem_syn, + 1, + M); + + /*buf[OLD_EXC_SIZE_DEC;3/2 L_frame-1] Q1: exc*/ + /*buf[0;M-1] Q0: mem_syn*/ + /*buf[M;3/2 L_frame-1] Q-1: syn*/ + + n = extract_h(L_mult(L_frame,9216/*(float)N_ZERO_MDCT_NS/(float)FRAME_SIZE_NS Q15*/)); + + /* update ACELP synthesis memory */ + mem_syn_r_size_old = shr(L_frame,4); /* replace 1.25/20.0 by shr(4) */ + /* copy mem_syn as 16kHz */ + mem_syn_r_size_new = shr(L_FRAME16k,4); /* replace 1.25/20.0 by shr(4) */ + + Copy(syn+L_frame-L_SYN_MEM, st->mem_syn_r, L_SYN_MEM); + lerp(st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_old, st->mem_syn_r+L_SYN_MEM-mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old); + Copy(st->mem_syn_r+L_SYN_MEM-M, st->mem_syn2_fx, M); + + /* Deemphasis and output synth and ZIR */ + deemph_fx(syn, st->preemph_fac, add(L_frame,shr(L_frame,1)), &tmp_deemph); + bufferCopyFx(syn+L_frame-M-1, st->syn, 1+M, Q_syn, 0, 0, 0); + + + lerp( syn+L_frame-shr(L_frame, 1), hTcxDec->old_syn_Overl, shr(st->L_frame, 1), shr(L_frame, 1) ); + Copy(syn+L_frame-n, hHQ_core->old_out_fx, sub(L_frame,n)); + + FOR (i=0; i < W12; i++) + { + hHQ_core->old_out_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[i].v.re,w[i].v.re), hHQ_core->old_out_fx[i+n])); + } + FOR ( ; i < W1; i++) + { + hHQ_core->old_out_fx[i+n] = round_fx(Mpy_32_16_1(L_mult(w[W12-1-(i-W12)].v.im,w[W12-1-(i-W12)].v.im), hHQ_core->old_out_fx[i+n])); + } + + set16_fx(&hHQ_core->old_out_fx[W1+n], 0, n); + + hHQ_core->Q_old_wtda = Q_syn; + move16(); + + /* As long as there is no synth scaling factor introduced, which + is given to the outside, there might occur overflows here */ + BASOP_SATURATE_WARNING_OFF_EVS + bufferCopyFx(syn, synth, L_frame, Q_syn, 0, 0, 0); + BASOP_SATURATE_WARNING_ON_EVS + + Copy_Scale_sig(syn+L_frame, hTcxDec->syn_OverlFB, shr(L_frame,1), negate(Q_syn)); + + /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */ + IF(st->hWIDec != NULL) + { + lerp(exc, st->hWIDec->old_exc2_fx, L_EXC_MEM, L_frame); + lerp(syn, st->hWIDec->old_syn2_fx, L_EXC_MEM, L_frame); + } + +#ifdef BASOP_NOGLOB + st->bfi_pitch_fx/*Q6*/ = round_fx_sat(L_shl_sat(pitch_buf[st->nb_subfr-1]/*15Q16*/,6/*Q6*/)); +#else + st->bfi_pitch_fx/*Q6*/ = round_fx(L_shl(pitch_buf[st->nb_subfr-1]/*15Q16*/,6/*Q6*/)); +#endif + move16(); + st->bfi_pitch_frame = st->L_frame; + move16(); + + /* create aliasing and windowing need for transition to TCX10/5 */ + bufferCopyFx(syn+L_frame, hTcxDec->syn_Overl_TDACFB, shr(L_frame,1),Q_syn,0,-1,0); + + FOR (i=0 ; i < W12 ; i++) + { + buf[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i] , w[i].v.re); + move16(); + } + FOR ( ; i syn_Overl_TDACFB[i],w[W12-1-(i-W12)].v.im); + move16(); + } + + + FOR (i=0; isyn_Overl_TDACFB[i] = add_sat(buf[i] , buf[W1-1-i]); + move16(); + } + + FOR (i=0; isyn_Overl_TDACFB[W2+i] = add_sat(buf[W2+i] , buf[W1-1-W2-i]); + move16(); + } + + FOR (i=0 ; i < W12 ; i++) + { + hTcxDec->syn_Overl_TDACFB[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i],w[i].v.re); + move16(); + } + FOR ( ; i syn_Overl_TDACFB[i] = mult_r(hTcxDec->syn_Overl_TDACFB[i],w[W12-1-(i-W12)].v.im); + move16(); + } + + st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP; + + synth[-1] = pre_emph_buf; + move16(); + + /* update memory for low band */ + Scale_sig(hTcxDec->old_syn_Overl, shr(st->L_frame, 1), sub(-1, Q_syn)); + lerp(hTcxDec->syn_OverlFB, hTcxDec->syn_Overl, shr(st->L_frame, 1), shr(L_frame, 1) ); + lerp(hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDAC, shr(st->L_frame, 1), shr(L_frame, 1) ); + lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, L_frame ); + + st->old_enr_LP = Enr_1_Az_fx(A_local, L_SUBFR); /*Q3*/ + + return; +} +#endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 6d7cd107d7b754cfa15222018247882198b45a07..37e1b0be361b74f6ee4b6bbb5137743f3bb2cde5 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -108,6 +108,7 @@ ivas_error ivas_core_dec( float synth[CPE_CHANNELS][L_FRAME48k]; float tmp_buffer[L_FRAME48k]; #ifdef IVAS_FLOAT_FIXED + Word32 synth_fx[CPE_CHANNELS][L_FRAME48k]; set_zero( tmp_buffer, L_FRAME48k ); Word16 tmp_buffer_fx[L_FRAME48k]; set_s(tmp_buffer_fx, 0, L_FRAME48k); @@ -540,7 +541,7 @@ ivas_error ivas_core_dec( floatToFixed_arr16( st->mem_syn2, st->mem_syn2_fx, Q_mem_syn, M ); floatToFixed_arr16( st->mem_syn1, st->mem_syn1_fx, Q_mem_syn, M ); floatToFixed_arr16( st->agc_mem2, st->agc_mem_fx, Q_agc_mem, 2 ); - floatToFixed_arr16( st->syn_float, st->syn, Q_mem_deemph, M + 1 ); + floatToFixed_arr( st->syn_float, st->syn, Q_mem_deemph, M + 1 ); st->mem_deemph_fx = (Word16) floatToFixed( st->mem_deemph, Q_mem_deemph ); st->psf_lp_noise_fx = (Word16) floatToFixed( st->psf_lp_noise, Q7 ); /*Used floatToFixed because does not give error in case of garbage value*/ st->lp_noise = float_to_fix16( st->lp_noise_float, Q7 ); @@ -611,10 +612,11 @@ ivas_error ivas_core_dec( IF( st->hTcxDec ) { floatToFixed_arr16( st->hTcxDec->FBTCXdelayBuf_float, st->hTcxDec->FBTCXdelayBuf, Q_prev_synth_buffer, 111 ); - floatToFixed_arr16( st->hTcxDec->syn_Overl_float, st->hTcxDec->syn_Overl, Q_syn_Overl, 320 ); + floatToFixed_arr( st->hTcxDec->syn_Overl_float, st->hTcxDec->syn_Overl, Q_syn_Overl, 320 ); floatToFixed_arr16( st->hTcxDec->old_syn_Overl_float, st->hTcxDec->old_syn_Overl, Q_old_syn_Overl, L_FRAME32k / 2 ); } floatToFixed_arr16( st->prev_synth_buffer, st->prev_synth_buffer_fx, Q_prev_synth_buffer, 96 ); + st->q_prev_synth_buffer_fx = Q_prev_synth_buffer; IF( st->cldfbAna ) { floatToFixed_arr32( st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q10, st->cldfbAna->cldfb_state_length ); @@ -675,6 +677,7 @@ ivas_error ivas_core_dec( st->psf_lp_noise = fixedToFloat( st->psf_lp_noise_fx, Q7 ); /*psf_lp_noise_fx has Q7*/ fixedToFloat_arr( st->hb_prev_synth_buffer_fx, st->hb_prev_synth_buffer, Q_hb_prev_synth_buffer, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); fixedToFloat_arr( st->prev_synth_buffer_fx, st->prev_synth_buffer, Q_prev_synth_buffer, 96 ); + st->q_prev_synth_buffer_fx = Q_prev_synth_buffer; fixedToFloat_arr( st->mem_syn_clas_estim_fx, st->mem_syn_clas_estim, Q_mem_syn_clas_estim, 258 ); st->enr_old = fixedToFloat( st->enr_old_fx, 0 ); st->lp_gainc = fixedToFloat( st->lp_gainc_fx, 3 ); /*Q3*/ @@ -919,6 +922,7 @@ ivas_error ivas_core_dec( hHQ_core->ph_ecu_active_fx = hHQ_core->ph_ecu_active; floatToFixed_arr( hHQ_core->mag_chg_1st, hHQ_core->mag_chg_1st_fx, Q15, LGW_MAX ); floatToFixed_arr( hHQ_core->Xavg, hHQ_core->Xavg_fx, 0, LGW_MAX ); + hHQ_core->mean_prev_fx = floatToFixed(hHQ_core->mean_prev, 0); hHQ_core->beta_mute_fx = (Word16) floatToFixed( hHQ_core->beta_mute, Q15 ); hHQ_core->env_stab_plc_fx = (Word16) floatToFixed( hHQ_core->env_stab_plc, Q15 ); floatToFixed_arr( st->t_audio_q, st->t_audio_q_fx, -1, L_FRAME ); @@ -930,6 +934,7 @@ ivas_error ivas_core_dec( fixedToFloat_arr( output_fx, output[n], Q_output, L_FRAME48k ); #ifndef IVAS_FLOAT_CONV_TO_BE_REMOVED + hHQ_core->mean_prev = fixedToFloat(hHQ_core->mean_prev_fx, 0); fixedToFloat_arr( hHQ_core->old_out_fx, hHQ_core->old_out, hHQ_core->Q_old_wtda, L_FRAME48k ); fixedToFloat_arr( hHQ_core->old_out_LB_fx, hHQ_core->old_outLB, hHQ_core->Q_old_wtda_LB, L_FRAME32k ); fixedToFloat_arr( st->hTcxDec->old_syn_Overl, st->hTcxDec->old_syn_Overl_float, -1, L_FRAME32k / 2 ); @@ -1285,236 +1290,160 @@ ivas_error ivas_core_dec( * TD-BWE for ACELP to TCX transitions *---------------------------------------------------------------------*/ - if ( st->last_core == ACELP_CORE && ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) && st->hBWE_TD != NULL ) +#ifdef IVAS_FLOAT_FIXED + Word32 hb_synth_fx[CPE_CHANNELS][L_FRAME48k]; + if (st->last_core == ACELP_CORE && (st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE) && st->hBWE_TD != NULL) { - //Delete from here - Word32 hb_synth_fx[CPE_CHANNELS][L_FRAME48k]; - FOR( int ch_ind = 0; ch_ind < n_channels; ch_ind++ ) + FOR(int ch_ind = 0; ch_ind < n_channels; ch_ind++) + { + FOR(int ind = 0; ind < L_FRAME48k; ind++) { - FOR( int ind = 0; ind < L_FRAME48k; ind++ ) - { - hb_synth_fx[ch_ind][ind] = (Word32) ( hb_synth[ch_ind][ind] * ( 1 << 11 ) ); - } + hb_synth_fx[ch_ind][ind] = (Word32)(hb_synth[ch_ind][ind] * (1 << 11)); } - if ( st->hBWE_TD != NULL ) + } + if (st->hBWE_TD != NULL) + { + for (int i = 0; i < L_SHB_LAHEAD; i++) { - for ( int i = 0; i < L_SHB_LAHEAD; i++ ) - { - st->hBWE_TD->syn_overlap_fx_32[i] = st->hBWE_TD->syn_overlap[i] * ( 1 << 11 ); - } - for ( int i = 0; i < INTERP_3_2_MEM_LEN; i++ ) - { - st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i] = st->hBWE_TD->int_3_over_2_tbemem_dec[i] * ( 1 << 11 ); - } - for ( int i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = st->hBWE_TD->genSHBsynth_Hilbert_Mem[i] * ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] = st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i] * ( 1 << 11 ); - } - for ( int i = 0; i < L_SHB_TRANSITION_LENGTH; i++ ) - { - st->hBWE_TD->old_tbe_synth_fx_32[i] = st->hBWE_TD->old_tbe_synth[i] * ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++ ) - { - st->hBWE_TD->mem_resamp_HB_32k_fx_32[i] = st->hBWE_TD->mem_resamp_HB_32k[i] * ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32[i] = st->hBWE_TD->state_lsyn_filt_dwn_shb[i] * ( 1 << 11 ); - st->hBWE_TD->state_lsyn_filt_shb_fx_32[i] = st->hBWE_TD->state_lsyn_filt_shb[i] * ( 1 << 11 ); - } - for ( int i = 0; i < INTERP_3_1_MEM_LEN; i++ ) - { - st->hBWE_TD->mem_resamp_HB_fx_32[i] = st->hBWE_TD->mem_resamp_HB[i] * ( 1 << 11 ); - } + st->hBWE_TD->syn_overlap_fx_32[i] = st->hBWE_TD->syn_overlap[i] * (1 << 11); } - //Delete till here - - - if ( ( st->bwidth == SWB || st->bwidth == FB ) && ( st->last_extl == SWB_TBE || st->last_extl == FB_TBE ) ) + for (int i = 0; i < INTERP_3_2_MEM_LEN; i++) { - GenTransition_fixed( st->hBWE_TD, &hb_synth_fx[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); + st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i] = st->hBWE_TD->int_3_over_2_tbemem_dec[i] * (1 << 11); } - else if ( st->bwidth == WB && st->last_extl == WB_TBE ) + for (int i = 0; i < HILBERT_MEM_SIZE; i++) { - GenTransition_WB_fixed( st->hBWE_TD, &hb_synth_fx[n], output_Fs ); - - move16(); - } - - // Delete from here - FOR( int ch_ind = 0; ch_ind < n_channels; ch_ind++ ) + st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = st->hBWE_TD->genSHBsynth_Hilbert_Mem[i] * (1 << 11); + } + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) { - FOR( int ind = 0; ind < L_FRAME48k; ind++ ) - { - hb_synth[ch_ind][ind] = ( (float) hb_synth_fx[ch_ind][ind] / ( 1 << 11 ) ); - } + st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] = st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i] * (1 << 11); } - if ( st->hBWE_TD != NULL ) + for (int i = 0; i < L_SHB_TRANSITION_LENGTH; i++) { - for ( int i = 0; i < L_SHB_LAHEAD; i++ ) - { - st->hBWE_TD->syn_overlap[i] = (float) st->hBWE_TD->syn_overlap_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < INTERP_3_2_MEM_LEN; i++ ) - { - st->hBWE_TD->int_3_over_2_tbemem_dec[i] = (float) st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - st->hBWE_TD->genSHBsynth_Hilbert_Mem[i] = (float) st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] / ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local[i] = (float) st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < L_SHB_TRANSITION_LENGTH; i++ ) - { - st->hBWE_TD->old_tbe_synth[i] = (float) st->hBWE_TD->old_tbe_synth_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++ ) - { - st->hBWE_TD->mem_resamp_HB_32k[i] = (float) st->hBWE_TD->mem_resamp_HB_32k_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++ ) - { - st->hBWE_TD->state_lsyn_filt_dwn_shb[i] = (float) st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32[i] / ( 1 << 11 ); - st->hBWE_TD->state_lsyn_filt_shb[i] = (float) st->hBWE_TD->state_lsyn_filt_shb_fx_32[i] / ( 1 << 11 ); - } - for ( int i = 0; i < INTERP_3_1_MEM_LEN; i++ ) - { - st->hBWE_TD->mem_resamp_HB[i] = (float) st->hBWE_TD->mem_resamp_HB_fx_32[i] / ( 1 << 11 ); - } + st->hBWE_TD->old_tbe_synth_fx_32[i] = st->hBWE_TD->old_tbe_synth[i] * (1 << 11); } - // Delete till here + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP + 1; i++) + { + st->hBWE_TD->mem_resamp_HB_32k_fx_32[i] = st->hBWE_TD->mem_resamp_HB_32k[i] * (1 << 11); + } + for (int i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++) + { + st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32[i] = st->hBWE_TD->state_lsyn_filt_dwn_shb[i] * (1 << 11); + st->hBWE_TD->state_lsyn_filt_shb_fx_32[i] = st->hBWE_TD->state_lsyn_filt_shb[i] * (1 << 11); + } + for (int i = 0; i < INTERP_3_1_MEM_LEN; i++) + { + st->hBWE_TD->mem_resamp_HB_fx_32[i] = st->hBWE_TD->mem_resamp_HB[i] * (1 << 11); + } + } } + /*cldfb struct*/ - /*---------------------------------------------------------------------* - * Postprocessing for ACELP/MDCT core switching - *---------------------------------------------------------------------*/ - - /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ - if ( sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT && !( st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) + /*------------------fix-to-fix-start---------------------*/ + /*core_switching_post_dec*/ + Q_synth = 0; + if (st->hHQ_core != NULL) { - mvr2r( synth[n], hSCE->save_synth, output_frame ); + st->hHQ_core->Q_old_postdec = 0; + st->hHQ_core->Q_old_wtda = 0; } + st->bws_cnt = st->bws_cnt; + st->coder_type = st->coder_type; + st->prev_coder_type = st->prev_coder_type; + st->prev_bws_cnt = st->prev_bws_cnt; + st->old_ppp_mode = st->old_ppp_mode; + /*------------------fix-to-fix-end-----------------------*/ -#ifdef IVAS_FLOAT_FIXED - - { - -#ifndef IVAS_CODE_TO_BE_REMOVED - /*cldfb struct*/ - - /*------------------fix-to-fix-start---------------------*/ - /*core_switching_post_dec*/ - Q_synth = 0; - if ( st->hHQ_core != NULL ) - { - st->hHQ_core->Q_old_postdec = 0; - st->hHQ_core->Q_old_wtda = 0; - } - st->bws_cnt = st->bws_cnt; - st->coder_type = st->coder_type; - st->prev_coder_type = st->prev_coder_type; - st->prev_bws_cnt = st->prev_bws_cnt; - st->old_ppp_mode = st->old_ppp_mode; - - /*------------------fix-to-fix-end-----------------------*/ - - Word16 *synth_fx16; - Word16 *output_mem_fx; - Word32 *output_fx32; + Word16 *synth_fx16; + Word16 *output_mem_fx; + Word32 *output_fx32; - synth_fx16 = (Word16 *) malloc( L_FRAME48k * sizeof( Word16 ) ); - output_fx32 = (Word32 *) malloc( L_FRAME48k * sizeof( Word32 ) ); - output_mem_fx = (Word16 *) malloc( NS2SA( st->output_Fs, 3125000 ) * sizeof( Word16 ) ); + synth_fx16 = (Word16 *)malloc(L_FRAME48k * sizeof(Word16)); + output_fx32 = (Word32 *)malloc(L_FRAME48k * sizeof(Word32)); + output_mem_fx = (Word16 *)malloc(NS2SA(st->output_Fs, 3125000) * sizeof(Word16)); - IF( p_output_mem != NULL ) - { - floatToFixed_arr( p_output_mem, output_mem_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); - } - ELSE - { - set16_fx( output_mem_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); - } + IF(p_output_mem != NULL) + { + floatToFixed_arr(p_output_mem, output_mem_fx, 0, NS2SA(st->output_Fs, 3125000)); + } + ELSE + { + set16_fx(output_mem_fx, 0, NS2SA(st->output_Fs, 3125000)); + } - floatToFixed_arr( synth[n], synth_fx16, Q_synth, L_FRAME48k ); - floatToFixed_arrL( output[n], output_fx32, 4, L_FRAME48k ); + floatToFixed_arr(synth[n], synth_fx16, Q_synth, L_FRAME48k); + floatToFixed_arrL(output[n], output_fx32, 4, L_FRAME48k); - tmp = extract_l( L_shr( st->output_Fs, 13 ) ); - Word16 Fs_kHz = shl( add( tmp, 1 ), 3 ); + tmp = extract_l(L_shr(st->output_Fs, 13)); + Word16 Fs_kHz = shl(add(tmp, 1), 3); - Word16 delta = 1; - move16(); - IF( GE_16( output_frame, L_FRAME16k ) ) - { - delta = shr( Fs_kHz, 3 ); - } + Word16 delta = 1; + move16(); + IF(GE_16(output_frame, L_FRAME16k)) + { + delta = shr(Fs_kHz, 3); + } - Word16 delay_comp = i_mult2( delta, HQ_DELAY_COMP ); + Word16 delay_comp = i_mult2(delta, HQ_DELAY_COMP); - if ( st->hBWE_FD != NULL ) - { - st->hBWE_FD->mem_deemph_old_syn_fx = (Word16)floatToFixed( st->hBWE_FD->mem_deemph_old_syn, 0 ); - } - IF( st->hHQ_core != NULL ) - { - floatToFixed_arr( st->hHQ_core->old_out, st->hHQ_core->old_out_fx, 0, L_FRAME48k ); - floatToFixed_arr( st->hHQ_core->fer_samples, st->hHQ_core->fer_samples_fx, 0, NS2SA( st->output_Fs, 3000000 ) ); - FOR( i = 0; i < SFM_N_WB; ++i ) - { - st->hHQ_core->prev_env_fx[i] = floatToFixed( st->hHQ_core->prev_env[i], st->hHQ_core->prev_env_Q[i] ); - } - floatToFixed_arrL( st->hHQ_core->prev_normq, st->hHQ_core->prev_normq_fx, 14, SFM_N_WB ); - } - floatToFixed_arr( st->previoussynth, st->previoussynth_fx, 0, L_FRAME48k ); - floatToFixed_arr( st->delay_buf_out, st->delay_buf_out_fx, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); + if (st->hBWE_FD != NULL) + { + st->hBWE_FD->mem_deemph_old_syn_fx = (Word16)floatToFixed(st->hBWE_FD->mem_deemph_old_syn, 0); + } + IF(st->hHQ_core != NULL) + { + floatToFixed_arr(st->hHQ_core->old_out, st->hHQ_core->old_out_fx, 0, L_FRAME48k); + floatToFixed_arr(st->hHQ_core->fer_samples, st->hHQ_core->fer_samples_fx, 0, NS2SA(st->output_Fs, 3000000)); + FOR(i = 0; i < SFM_N_WB; ++i) + { + st->hHQ_core->prev_env_fx[i] = floatToFixed(st->hHQ_core->prev_env[i], st->hHQ_core->prev_env_Q[i]); + } + floatToFixed_arrL(st->hHQ_core->prev_normq, st->hHQ_core->prev_normq_fx, 14, SFM_N_WB); + } + floatToFixed_arr(st->previoussynth, st->previoussynth_fx, 0, L_FRAME48k); + floatToFixed_arr(st->delay_buf_out, st->delay_buf_out_fx, 0, HQ_DELTA_MAX * HQ_DELAY_COMP); - if ( st->hTcxDec != NULL ) - { - st->hTcxDec->conceal_eof_gain = (Word16)floatToFixed( st->hTcxDec->conceal_eof_gain_float, 14 ); - } + if (st->hTcxDec != NULL) + { + st->hTcxDec->conceal_eof_gain = (Word16)floatToFixed(st->hTcxDec->conceal_eof_gain_float, 14); + } - /*size of synth is choosen as delay comp to start with*/ - // synth //Q0 -> Qsynth - // output_fx //Q ? - // delay_buf_buf //Q0 -> Q_old_postdec - // fer_samples //Q0 -> Q? - /*-------------------cldfb-start-------------------------*/ + /*size of synth is choosen as delay comp to start with*/ + // synth //Q0 -> Qsynth + // output_fx //Q ? + // delay_buf_buf //Q0 -> Q_old_postdec + // fer_samples //Q0 -> Q? + /*-------------------cldfb-start-------------------------*/ - Word16 cldfb_size = (Word16) ( st->L_frame / 16 + 0.5 ); + Word16 cldfb_size = (Word16)(st->L_frame / 16 + 0.5); - floatToFixed_arrL( st->bpf_noise_buf_float, st->bpf_noise_buf_32, 11, L_FRAME_16k ); - if ( st->cldfbAna != NULL ) - { - floatToFixed_arrL( st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, 10, st->cldfbAna->cldfb_size ); - } - if ( st->cldfbSyn != NULL ) - { - floatToFixed_arrL( st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, 4, st->cldfbSyn->p_filter_length ); - } - if ( st->cldfbBPF != NULL ) - { - floatToFixed_arrL( st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, 11, st->cldfbBPF->cldfb_size ); - } + floatToFixed_arrL(st->bpf_noise_buf_float, st->bpf_noise_buf_32, 11, L_FRAME_16k); + if (st->cldfbAna != NULL) + { + floatToFixed_arrL(st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, 10, st->cldfbAna->cldfb_size); + } + if (st->cldfbSyn != NULL) + { + floatToFixed_arrL(st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, 4, st->cldfbSyn->p_filter_length); + } + if (st->cldfbBPF != NULL) + { + floatToFixed_arrL(st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, 11, st->cldfbBPF->cldfb_size); + } - /*-------------------cldfb-end---------------------------*/ + /*-------------------cldfb-end---------------------------*/ st->stab_fac_fx = float_to_fix16(st->stab_fac, Q15); floatToFixed_arr(st->old_exc, st->old_exc_fx, st->Q_exc, L_EXC_MEM_DEC); IF(st->hWIDec != NULL) { - floatToFixed_arr(st->hWIDec->old_exc2,st->hWIDec->old_exc2_fx, st->Q_exc, L_EXC_MEM); + floatToFixed_arr(st->hWIDec->old_exc2, st->hWIDec->old_exc2_fx, st->Q_exc, L_EXC_MEM); } if (st->hBWE_TD != NULL) { - floatToFixed_arr(st->hBWE_TD->old_bwe_exc,st->hBWE_TD->old_bwe_exc_fx, st->Q_exc, PIT16k_MAX * 2); + floatToFixed_arr(st->hBWE_TD->old_bwe_exc, st->hBWE_TD->old_bwe_exc_fx, st->Q_exc, PIT16k_MAX * 2); } if (st->hGSCDec != NULL) { @@ -1533,290 +1462,353 @@ ivas_error ivas_core_dec( st->hBPF->pst_lp_ener_fx = float_to_fix16(st->hBPF->pst_lp_ener, Q8); st->hBPF->psf_att_fx = float_to_fix16(st->hBPF->psf_att, Q15); } -#endif - if ( ( error = core_switching_post_dec_ivas_fx( st, synth_fx16, output_fx32, output_mem_fx, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE, &Q_synth ) ) != IVAS_ERR_OK ) - { - return error; - } -#ifndef IVAS_CODE_TO_BE_REMOVED - fixedToFloat_arr(st->old_exc_fx, st->old_exc, st->Q_exc, L_EXC_MEM_DEC); - if (st->hMusicPF != NULL) - { - fixedToFloat_arr(st->hMusicPF->dct_post_old_exc_fx, st->hMusicPF->dct_post_old_exc, st->Q_exc, DCT_L_POST - OFFSET2); - } - if (st->hBPF) { - fixedToFloat_arr(st->hBPF->pst_old_syn_fx, st->hBPF->pst_old_syn, st->Q_syn2 - 1, NBPSF_PIT_MAX); - st->hBPF->pst_mem_deemp_err = fixedToFloat(st->hBPF->pst_mem_deemp_err_fx, st->Q_syn2 - 1); - fixedToFloat_arr(st->hBPF->mem_mean_pit_fx, st->hBPF->mem_mean_pit, Q4, L_TRACK_HIST); - Copy(st->hBPF->Track_on_hist_fx, st->hBPF->Track_on_hist, L_TRACK_HIST); - Copy(st->hBPF->vibrato_hist_fx, st->hBPF->vibrato_hist, L_TRACK_HIST); - st->hBPF->pst_lp_ener = fixedToFloat(st->hBPF->pst_lp_ener_fx, Q8); - st->hBPF->psf_att = fixedToFloat(st->hBPF->psf_att_fx, Q15); - } - - /*-------------------cldfb-start-------------------------*/ - /*note : cldfb_size here signifies the original size which was assigned to cldfb_state_fx buffer not its current size*/ + Word32 old_syn_12k8_16k_fx[L_FRAME16k]; + Word16 gb, norm, q_audio, old_syn_fx; + old_syn_fx = Q11; + floatToFixed_arrL(old_syn_12k8_16k[n], old_syn_12k8_16k_fx, old_syn_fx, L_FRAME16k); + norm = norm_arr_s(st->t_audio_q, L_FRAME); + gb = find_guarded_bits_fx(L_FRAME); + floatToFixed_arr(st->t_audio_q, st->t_audio_q_fx, norm - gb, L_FRAME); + q_audio = norm - gb; - if ( st->cldfbAna != NULL ) - { - fixedToFloat_arrL( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, 10, st->cldfbAna->cldfb_state_length ); - } - if ( st->cldfbSyn != NULL ) +#endif + test(); test(); test(); test(); + IF ( EQ_16(st->last_core, ACELP_CORE) && (EQ_16(st->core, TCX_20_CORE) || EQ_16(st->core, TCX_10_CORE) || EQ_16(st->core, HQ_CORE) ) && st->hBWE_TD != NULL ) + { + test(); test(); test(); test(); + IF ( (EQ_16(st->bwidth, SWB) || EQ_16(st->bwidth, FB) ) && (EQ_16(st->last_extl, SWB_TBE) || EQ_16(st->last_extl, FB_TBE) ) ) { - fixedToFloat_arrL( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, 4, st->cldfbSyn->p_filter_length ); + GenTransition_fixed( st->hBWE_TD, &hb_synth_fx[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); } - if ( st->cldfbBPF != NULL ) + ELSE IF (EQ_16(st->bwidth, WB) && EQ_16(st->last_extl, WB_TBE) ) { - fixedToFloat_arrL( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, 11, st->cldfbBPF->cldfb_state_length ); - } + GenTransition_WB_fixed( st->hBWE_TD, &hb_synth_fx[n], output_Fs ); - /*-------------------cldfb-end---------------------------*/ + move16(); + } + } - fixedToFloat_arr( synth_fx16, synth[n], Q_synth, L_FRAME48k ); - fixedToFloat_arrL( output_fx32, output[n], 4, L_FRAME48k ); - fixedToFloat_arr( st->delay_buf_out_fx, st->delay_buf_out, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); - IF ( st->hHQ_core != NULL ) - { - fixedToFloat_arr( st->hHQ_core->old_out_fx, st->hHQ_core->old_out, 0, L_FRAME48k ); - fixedToFloat_arr( st->hHQ_core->fer_samples_fx, st->hHQ_core->fer_samples, 0, NS2SA( st->output_Fs, 3000000 ) ); - FOR( i = 0; i < SFM_N_WB; ++i ) - { - st->hHQ_core->prev_env[i] = fixedToFloat( st->hHQ_core->prev_env_fx[i], st->hHQ_core->prev_env_Q[i] ); - } - fixedToFloat_arrL( st->hHQ_core->prev_normq_fx, st->hHQ_core->prev_normq, 14, SFM_N_WB ); - } - fixedToFloat_arr( st->previoussynth_fx, st->previoussynth, 0, L_FRAME48k ); + /*---------------------------------------------------------------------* + * Postprocessing for ACELP/MDCT core switching + *---------------------------------------------------------------------*/ + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ + test(); test(); test(); + IF (sba_dirac_stereo_flag && NE_16(st->element_mode, IVAS_CPE_MDCT) && !(EQ_32(st->core_brate, SID_2k40) && EQ_16(st->cng_type, FD_CNG))) + { + Copy(synth_fx[n], hSCE->save_synth_fx, output_frame); + } + IF ( ( error = core_switching_post_dec_ivas_fx( st, synth_fx16, output_fx32, output_mem_fx, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE, &Q_synth ) ) != IVAS_ERR_OK ) + { + return error; + } - /*------------------reset-code-start---------------------*/ + /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ + test(); test(); test(); + IF (sba_dirac_stereo_flag && hSCE && EQ_32(st->core_brate, SID_2k40) && EQ_16(st->cng_type, FD_CNG)) + { + Copy(synth_fx[n], hSCE->save_synth_fx, output_frame); + } - /*reset function flags*/ - Word8 reset_wb_tbe_extras = 0; - Word8 reset_wb_tbe_synth = 0; - Word8 reset_swb_tbe = 0; - Word8 reset_swb_tbe_synth = 0; - Word8 reset_fb_tbe_synth = 0; + /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ + test(); test(); test(); test(); test(); + IF (EQ_16(n, 0) && EQ_16(st->element_mode, IVAS_CPE_MDCT) && EQ_16(st->last_core, ACELP_CORE) && NE_16(st->core, ACELP_CORE) && (EQ_16(nchan_out, 1) || (hCPE != NULL && EQ_16(hCPE->last_element_mode, IVAS_CPE_DFT)))) + { + Copy(sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX); + } + /*---------------------------------------------------------------------* + * Pre-processing for bandwidth switching + *---------------------------------------------------------------------*/ - if ( st->hBWE_FD != NULL ) - { - st->hBWE_FD->mem_deemph_old_syn = fixedToFloat( st->hBWE_FD->mem_deemph_old_syn_fx, 0 ); - } + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx, old_syn_fx, q_audio ); - IF( st->bws_cnt == 0 || ( st->bws_cnt > 0 && NE_16( st->coder_type, INACTIVE ) && NE_16( st->coder_type, AUDIO ) ) ) - { - st->attenu1 = fixedToFloat( st->attenu_fx, 15 ); - } - IF( ( NE_16( st->last_extl, SWB_BWE ) && EQ_16( st->extl, SWB_BWE ) ) || ( NE_16( st->last_extl, FB_BWE ) && EQ_16( st->extl, FB_BWE ) ) || - ( ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_extl, SWB_TBE ) ) && st->extl < 0 && NE_16( st->core, HQ_CORE ) ) || ( EQ_16( st->last_core, ACELP_CORE ) && EQ_16( st->core, ACELP_CORE ) && ( ( NE_16( st->prev_coder_type, INACTIVE ) && EQ_16( st->coder_type, INACTIVE ) ) || ( NE_16( st->prev_coder_type, AUDIO ) && EQ_16( st->coder_type, AUDIO ) ) ) && st->bws_cnt > 0 ) ) - { - fixedToFloat_arrL( st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame ); +#ifdef IVAS_FLOAT_FIXED + if (st->last_core == ACELP_CORE && (st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE) && st->hBWE_TD != NULL) + { + // Delete from here + FOR(int ch_ind = 0; ch_ind < n_channels; ch_ind++) + { + fixedToFloat_arrL(hb_synth_fx[ch_ind], hb_synth[ch_ind], 11, L_FRAME48k); + } + if (st->hBWE_TD != NULL) + { + + fixedToFloat_arrL(st->hBWE_TD->syn_overlap_fx_32, st->hBWE_TD->syn_overlap, 11, L_SHB_LAHEAD); + fixedToFloat_arrL(st->hBWE_TD->int_3_over_2_tbemem_dec_fx_32, st->hBWE_TD->int_3_over_2_tbemem_dec, 11, INTERP_3_2_MEM_LEN); + fixedToFloat_arrL(st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, st->hBWE_TD->genSHBsynth_Hilbert_Mem, 11, HILBERT_MEM_SIZE); + fixedToFloat_arrL(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, 11, 2 * ALLPASSSECTIONS_STEEP); + fixedToFloat_arrL(st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth, 11, L_SHB_TRANSITION_LENGTH); + fixedToFloat_arrL(st->hBWE_TD->mem_resamp_HB_32k_fx_32, st->hBWE_TD->mem_resamp_HB_32k, 11, 2 * ALLPASSSECTIONS_STEEP + 1); + fixedToFloat_arrL(st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, st->hBWE_TD->state_lsyn_filt_dwn_shb, 11, 2 * ALLPASSSECTIONS_STEEP + 1); + fixedToFloat_arrL(st->hBWE_TD->state_lsyn_filt_shb_fx_32, st->hBWE_TD->state_lsyn_filt_shb, 11, 2 * ALLPASSSECTIONS_STEEP + 1); + + fixedToFloat_arrL(st->hBWE_TD->mem_resamp_HB_fx_32, st->hBWE_TD->mem_resamp_HB, 11, INTERP_3_1_MEM_LEN); + + } + } + if (sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT && !(st->core_brate == SID_2k40 && st->cng_type == FD_CNG)) + { + mvr2r(synth[n], hSCE->save_synth, output_frame); + } + fixedToFloat_arr(st->old_exc_fx, st->old_exc, st->Q_exc, L_EXC_MEM_DEC); + if (st->hMusicPF != NULL) + { + fixedToFloat_arr(st->hMusicPF->dct_post_old_exc_fx, st->hMusicPF->dct_post_old_exc, st->Q_exc, DCT_L_POST - OFFSET2); + } + if (st->hBPF) { + fixedToFloat_arr(st->hBPF->pst_old_syn_fx, st->hBPF->pst_old_syn, st->Q_syn2 - 1, NBPSF_PIT_MAX); + st->hBPF->pst_mem_deemp_err = fixedToFloat(st->hBPF->pst_mem_deemp_err_fx, st->Q_syn2 - 1); + fixedToFloat_arr(st->hBPF->mem_mean_pit_fx, st->hBPF->mem_mean_pit, Q4, L_TRACK_HIST); + Copy(st->hBPF->Track_on_hist_fx, st->hBPF->Track_on_hist, L_TRACK_HIST); + Copy(st->hBPF->vibrato_hist_fx, st->hBPF->vibrato_hist, L_TRACK_HIST); + st->hBPF->pst_lp_ener = fixedToFloat(st->hBPF->pst_lp_ener_fx, Q8); + st->hBPF->psf_att = fixedToFloat(st->hBPF->psf_att_fx, Q15); + } - st->hBWE_FD->prev_Energy = fixedToFloat( st->hBWE_FD->prev_Energy_fx, 0 ); // setting to zero - st->hBWE_FD->prev_td_energy = st->hBWE_FD->prev_td_energy_fx; // setting to zero - st->hBWE_FD->prev_weight = fixedToFloat( st->hBWE_FD->prev_weight_fx, 15 ); // 6554; /*0.2 in Q15*/ - st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat( st->prev_fb_ener_adjust_fx, 0 ); // setting to zero - fixedToFloat_arr( st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); // setting to zero - } + /*-------------------cldfb-start-------------------------*/ - /* reset WB BWE buffers */ + /*note : cldfb_size here signifies the original size which was assigned to cldfb_state_fx buffer not its current size*/ - IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && st->hBWE_FD != NULL) - { - // set16_fx( st->hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); - fixedToFloat_arrL( st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame ); + if (st->cldfbAna != NULL) + { + fixedToFloat_arrL(st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, 10, st->cldfbAna->cldfb_state_length); + } + if (st->cldfbSyn != NULL) + { + fixedToFloat_arrL(st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, 4, st->cldfbSyn->p_filter_length); + } + if (st->cldfbBPF != NULL) + { + fixedToFloat_arrL(st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, 11, st->cldfbBPF->cldfb_state_length); + } - st->hBWE_FD->prev_Energy_wb = st->hBWE_FD->prev_Energy_wb_fx; - fixedToFloat_arr( st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); // setting to zero - } + /*-------------------cldfb-end---------------------------*/ - /* reset TBE buffers */ - if ( st->hBWE_TD != NULL ) - { - IF( ( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || EQ_16( st->extl, SWB_CNG ) ) && - ( NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || EQ_16( st->last_core, HQ_CORE ) ) ) || - ( LT_16( st->bwidth, st->last_bwidth ) && NE_16( st->last_extl, SWB_TBE ) ) || st->old_ppp_mode || ( ( EQ_16( st->prev_coder_type, AUDIO ) || EQ_16( st->prev_coder_type, INACTIVE ) ) && st->bws_cnt > 0 ) || ( st->bws_cnt == 0 && EQ_16( st->prev_bws_cnt, N_WS2N_FRAMES ) ) ) - { + fixedToFloat_arr(synth_fx16, synth[n], Q_synth, L_FRAME48k); + fixedToFloat_arrL(output_fx32, output[n], 4, L_FRAME48k); + fixedToFloat_arr(st->delay_buf_out_fx, st->delay_buf_out, 0, HQ_DELTA_MAX * HQ_DELAY_COMP); + IF(st->hHQ_core != NULL) + { + fixedToFloat_arr(st->hHQ_core->old_out_fx, st->hHQ_core->old_out, 0, L_FRAME48k); + fixedToFloat_arr(st->hHQ_core->fer_samples_fx, st->hHQ_core->fer_samples, 0, NS2SA(st->output_Fs, 3000000)); + FOR(i = 0; i < SFM_N_WB; ++i) + { + st->hHQ_core->prev_env[i] = fixedToFloat(st->hHQ_core->prev_env_fx[i], st->hHQ_core->prev_env_Q[i]); + } + fixedToFloat_arrL(st->hHQ_core->prev_normq_fx, st->hHQ_core->prev_normq, 14, SFM_N_WB); + } + fixedToFloat_arr(st->previoussynth_fx, st->previoussynth, 0, L_FRAME48k); - reset_swb_tbe = 1; - reset_swb_tbe_synth = 1; - fixedToFloat_arr( st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); - IF( EQ_16( output_frame, L_FRAME16k ) ) - { - /* reset in case that SWB TBE layer is transmitted, but the output x`x`is 16kHz sampled */ - fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); - } - fixedToFloat_arr( st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN ); - st->hBWE_TD->prev_pow_exc16kWhtnd = (float)st->hBWE_TD->prev_pow_exc16kWhtnd_fx / 32767; - st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; - } - ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && - ( NE_32( st->last_total_brate, st->total_brate ) || NE_16( st->last_bwidth, st->bwidth ) || - NE_16( st->last_codec_mode, MODE1 ) || NE_16( st->rf_flag, st->rf_flag_last ) ) ) - { - fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_zero_swb_fx, st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER ); // setting to zero - st->hBWE_TD->gain_prec_swb = fixedToFloat( st->hBWE_TD->gain_prec_swb_fx, 14 ); /* Q14 = 1 */ - } - ELSE IF( st->hBWE_TD != NULL && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) - { - /*------------TBEreset_dec_ivas_fx-start------------------*/ - IF( NE_16( st->last_core, ACELP_CORE ) ) - { - fixedToFloat_arr( st->hBWE_TD->old_bwe_exc_fx, st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); // setting to zero - st->hBWE_TD->bwe_non_lin_prev_scale = fixedToFloat( st->hBWE_TD->bwe_non_lin_prev_scale_fx, 0 ); // setting to zero - } - IF( EQ_16( st->bwidth, WB ) ) - { - reset_wb_tbe_extras = 1; - reset_wb_tbe_synth = 1; - - fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, 7 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, 10 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4 ); - fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); - fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); - } - ELSE IF( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) - { - reset_swb_tbe = 1; - reset_swb_tbe_synth = 1; - fixedToFloat_arr( st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero - st->hBWE_TD->prev_pow_exc16kWhtnd = (float) st->hBWE_TD->prev_pow_exc16kWhtnd_fx/32767; /*Q15 1.f*/ - st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; /*Q15 1.f */ - - IF( EQ_16( st->bwidth, FB ) ) - { - IF( st->hBWE_FD != NULL ) - { - st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat( st->prev_fb_ener_adjust_fx, 0 ); - } - fixedToFloat_arr( st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); - st->hBWE_TD->fb_tbe_demph = fixedToFloat( st->hBWE_TD->fb_tbe_demph_fx, 0 ); // setting to zero - reset_fb_tbe_synth = 1; - } - } - /*------------TBEreset_dec_ivas_fx-end--------------------*/ - } + /*------------------reset-code-start---------------------*/ - IF( EQ_16( st->extl, FB_TBE ) && ( NE_16( st->last_extl, FB_TBE ) || NE_16( st->L_frame, st->last_L_frame ) ) ) - { - fixedToFloat_arr( st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); - st->hBWE_TD->fb_tbe_demph = fixedToFloat( st->hBWE_TD->fb_tbe_demph_fx, 0 ); // setting to zero - reset_fb_tbe_synth = 1; - } + /*reset function flags*/ + Word8 reset_wb_tbe_extras = 0; + Word8 reset_wb_tbe_synth = 0; + Word8 reset_swb_tbe = 0; + Word8 reset_swb_tbe_synth = 0; + Word8 reset_fb_tbe_synth = 0; + if (st->hBWE_FD != NULL) + { + st->hBWE_FD->mem_deemph_old_syn = fixedToFloat(st->hBWE_FD->mem_deemph_old_syn_fx, 0); + } - IF( NE_16( st->last_extl, WB_TBE ) && EQ_16( st->extl, WB_TBE ) ) - { - reset_wb_tbe_extras = 1; - reset_wb_tbe_synth = 1; - fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); // setting to zero - fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); // setting to zero - } + IF(st->bws_cnt == 0 || (st->bws_cnt > 0 && NE_16(st->coder_type, INACTIVE) && NE_16(st->coder_type, AUDIO))) + { + st->attenu1 = fixedToFloat(st->attenu_fx, 15); + } + IF((NE_16(st->last_extl, SWB_BWE) && EQ_16(st->extl, SWB_BWE)) || (NE_16(st->last_extl, FB_BWE) && EQ_16(st->extl, FB_BWE)) || + ((EQ_16(st->last_core, HQ_CORE) || EQ_16(st->last_extl, SWB_TBE)) && st->extl < 0 && NE_16(st->core, HQ_CORE)) || (EQ_16(st->last_core, ACELP_CORE) && EQ_16(st->core, ACELP_CORE) && ((NE_16(st->prev_coder_type, INACTIVE) && EQ_16(st->coder_type, INACTIVE)) || (NE_16(st->prev_coder_type, AUDIO) && EQ_16(st->coder_type, AUDIO))) && st->bws_cnt > 0)) + { + fixedToFloat_arrL(st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame); - IF( reset_swb_tbe ) - { - fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER ); // setting to zero - - st->hBWE_TD->tbe_demph = fixedToFloat( st->hBWE_TD->tbe_demph_fx, 0 ); // setting to zero - st->hBWE_TD->tbe_premph = fixedToFloat( st->hBWE_TD->tbe_premph_fx, 0 ); // setting to zero - st->hBWE_TD->gain_prec_swb = fixedToFloat( st->hBWE_TD->gain_prec_swb_fx, 14 ); // setting to zero - } - IF( reset_swb_tbe_synth ) - { - fixedToFloat_arrL( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, st->hBWE_TD->genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); // setting to zero // setting to zero - fixedToFloat_arr( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero - } - IF( reset_wb_tbe_extras ) - { - fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb2, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero - } - IF( reset_wb_tbe_synth ) - { - fixedToFloat_arr( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero - fixedToFloat_arr( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero - // fixedToFloat(st->hBWE_TD->state_32and48k_WB_upsample_fx, st->hBWE_TD->state_32and48k_WB_upsample,0, 2 * ALLPASSSECTIONS_STEEP); buffer not there in float code* - fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB, 0, INTERP_3_1_MEM_LEN ); // setting to zero - } - IF( reset_fb_tbe_synth ) - { - fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[0], st->hBWE_TD->fbbwe_hpf_mem[0], 0, 4 ); // setting to zero - fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[1], st->hBWE_TD->fbbwe_hpf_mem[1], 0, 4 ); // setting to zero - fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[2], st->hBWE_TD->fbbwe_hpf_mem[2], 0, 4 ); // setting to zero - fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[3], st->hBWE_TD->fbbwe_hpf_mem[3], 0, 4 ); // setting to zero - st->hBWE_TD->prev_fbbwe_ratio = fixedToFloat( st->hBWE_TD->prev_fbbwe_ratio_fx, 0 ); // scaling unknown setting to 1 - } - } - /* Interp_3_2 CNG buffers reset */ - IF(st->hTdCngDec != NULL && EQ_32( st->output_Fs, 48000 ) && ( ( GT_32( st->last_core_brate, SID_2k40 ) ) && ( EQ_32( st->core_brate, FRAME_NO_DATA ) || EQ_32( st->core_brate, SID_2k40 ) ) ) ) - { - fixedToFloat_arr( st->interpol_3_2_cng_dec_fx, st->hTdCngDec->interpol_3_2_cng_dec, 0, INTERP_3_2_MEM_LEN ); - } + st->hBWE_FD->prev_Energy = fixedToFloat(st->hBWE_FD->prev_Energy_fx, 0); // setting to zero + st->hBWE_FD->prev_frica_flag = st->hBWE_FD->prev_frica_flag; // fixed + st->hBWE_FD->prev_td_energy = st->hBWE_FD->prev_td_energy_fx; // setting to zero + st->hBWE_FD->prev_weight = fixedToFloat(st->hBWE_FD->prev_weight_fx, 15); // 6554; /*0.2 in Q15*/ + st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat(st->prev_fb_ener_adjust_fx, 0); // setting to zero + fixedToFloat_arr(st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k); // setting to zero + } - /*------------------reset-code-end-----------------------*/ + /* reset WB BWE buffers */ - free( synth_fx16 ); - free( output_fx32 ); - free( output_mem_fx ); -#endif - } -#else - if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) + IF(NE_16(st->last_extl, WB_BWE) && EQ_16(st->extl, WB_BWE) && st->hBWE_FD != NULL) { - return error; + // set16_fx( st->hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); + fixedToFloat_arrL(st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame); + + IF(NE_16(st->last_extl, SWB_BWE) && NE_16(st->last_extl, FB_BWE)) + { + st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode; + } + st->hBWE_FD->prev_Energy_wb = st->hBWE_FD->prev_Energy_wb_fx; + st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm; + st->hBWE_FD->prev_flag = st->hBWE_FD->prev_flag; + fixedToFloat_arr(st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k); // setting to zero } -#endif - /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ - if ( sba_dirac_stereo_flag && hSCE && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) + /* reset TBE buffers */ + if (st->hBWE_TD != NULL) { - mvr2r( synth[n], hSCE->save_synth, output_frame ); + IF(((EQ_16(st->extl, SWB_TBE) || EQ_16(st->extl, FB_TBE) || EQ_16(st->extl, SWB_CNG)) && + (NE_16(st->L_frame, st->last_L_frame) || (NE_16(st->last_extl, SWB_TBE) && NE_16(st->last_extl, FB_TBE)) || EQ_16(st->last_core, HQ_CORE))) || + (LT_16(st->bwidth, st->last_bwidth) && NE_16(st->last_extl, SWB_TBE)) || st->old_ppp_mode || ((EQ_16(st->prev_coder_type, AUDIO) || EQ_16(st->prev_coder_type, INACTIVE)) && st->bws_cnt > 0) || (st->bws_cnt == 0 && EQ_16(st->prev_bws_cnt, N_WS2N_FRAMES))) + { + + reset_swb_tbe = 1; + reset_swb_tbe_synth = 1; + + fixedToFloat_arr(st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2); + + IF(EQ_16(output_frame, L_FRAME16k)) + { + /* reset in case that SWB TBE layer is transmitted, but the output x`x`is 16kHz sampled */ + fixedToFloat_arr(st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1); + } + fixedToFloat_arr(st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN); + st->hBWE_TD->prev_pow_exc16kWhtnd = (float)st->hBWE_TD->prev_pow_exc16kWhtnd_fx / 32767; + st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; + } + ELSE IF((EQ_16(st->extl, SWB_TBE) || EQ_16(st->extl, FB_TBE)) && + (NE_32(st->last_total_brate, st->total_brate) || NE_16(st->last_bwidth, st->bwidth) || + NE_16(st->last_codec_mode, MODE1) || NE_16(st->rf_flag, st->rf_flag_last))) + { + fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_zero_swb_fx, st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER); // setting to zero + st->hBWE_TD->gain_prec_swb = fixedToFloat(st->hBWE_TD->gain_prec_swb_fx, 14); /* Q14 = 1 */ + } + ELSE IF(st->hBWE_TD != NULL && (st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE)) + { + /*------------TBEreset_dec_ivas_fx-start------------------*/ + IF(NE_16(st->last_core, ACELP_CORE)) + { + fixedToFloat_arr(st->hBWE_TD->old_bwe_exc_fx, st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2); // setting to zero + st->hBWE_TD->bwe_non_lin_prev_scale = fixedToFloat(st->hBWE_TD->bwe_non_lin_prev_scale_fx, 0); // setting to zero + } + IF(EQ_16(st->bwidth, WB)) + { + reset_wb_tbe_extras = 1; + reset_wb_tbe_synth = 1; + + fixedToFloat_arr(st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, 7); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, 10); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4); + fixedToFloat_arr(st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD); + fixedToFloat_arrL(st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2); + } + ELSE IF(EQ_16(st->bwidth, SWB) || EQ_16(st->bwidth, FB)) + { + reset_swb_tbe = 1; + reset_swb_tbe_synth = 1; + fixedToFloat_arr(st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2); // setting to zero + fixedToFloat_arr(st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1); // setting to zero + st->hBWE_TD->prev_pow_exc16kWhtnd = (float)st->hBWE_TD->prev_pow_exc16kWhtnd_fx / 32767; /*Q15 1.f*/ + st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; /*Q15 1.f */ + + IF(EQ_16(st->bwidth, FB)) + { + IF(st->hBWE_FD != NULL) + { + st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat(st->prev_fb_ener_adjust_fx, 0); + } + fixedToFloat_arr(st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER); + st->hBWE_TD->fb_tbe_demph = fixedToFloat(st->hBWE_TD->fb_tbe_demph_fx, 0); // setting to zero + reset_fb_tbe_synth = 1; + } + } + /*------------TBEreset_dec_ivas_fx-end--------------------*/ + } + + IF(EQ_16(st->extl, FB_TBE) && (NE_16(st->last_extl, FB_TBE) || NE_16(st->L_frame, st->last_L_frame))) + { + fixedToFloat_arr(st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER); + st->hBWE_TD->fb_tbe_demph = fixedToFloat(st->hBWE_TD->fb_tbe_demph_fx, 0); // setting to zero + reset_fb_tbe_synth = 1; + } + + + IF(NE_16(st->last_extl, WB_TBE) && EQ_16(st->extl, WB_TBE)) + { + reset_wb_tbe_extras = 1; + reset_wb_tbe_synth = 1; + fixedToFloat_arr(st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4); // setting to zero + fixedToFloat_arr(st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD); // setting to zero + fixedToFloat_arrL(st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2); // setting to zero + } + + IF(reset_swb_tbe) + { + fixedToFloat_arrL(st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, (2 * ALLPASSSECTIONS_STEEP + 1)); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER); // setting to zero + fixedToFloat_arr(st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER); // setting to zero + + st->hBWE_TD->tbe_demph = fixedToFloat(st->hBWE_TD->tbe_demph_fx, 0); // setting to zero + st->hBWE_TD->tbe_premph = fixedToFloat(st->hBWE_TD->tbe_premph_fx, 0); // setting to zero + st->hBWE_TD->gain_prec_swb = fixedToFloat(st->hBWE_TD->gain_prec_swb_fx, 14); // setting to zero + } + IF(reset_swb_tbe_synth) + { + fixedToFloat_arrL(st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, st->hBWE_TD->genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE); // setting to zero // setting to zero + fixedToFloat_arr(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, 0, 2 * ALLPASSSECTIONS_STEEP); // setting to zero + } + IF(reset_wb_tbe_extras) + { + fixedToFloat_arr(st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb2, 0, 2 * ALLPASSSECTIONS_STEEP + 1); // setting to zero + fixedToFloat_arr(st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3, 0, 2 * ALLPASSSECTIONS_STEEP + 1); // setting to zero + } + IF(reset_wb_tbe_synth) + { + fixedToFloat_arr(st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb, 0, 2 * ALLPASSSECTIONS_STEEP); // setting to zero + fixedToFloat_arr(st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb, 0, 2 * ALLPASSSECTIONS_STEEP); // setting to zero + // fixedToFloat(st->hBWE_TD->state_32and48k_WB_upsample_fx, st->hBWE_TD->state_32and48k_WB_upsample,0, 2 * ALLPASSSECTIONS_STEEP); buffer not there in float code* + fixedToFloat_arr(st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB, 0, INTERP_3_1_MEM_LEN); // setting to zero + } + IF(reset_fb_tbe_synth) + { + fixedToFloat_arrL(st->hBWE_TD->fbbwe_hpf_mem_fx[0], st->hBWE_TD->fbbwe_hpf_mem[0], 0, 4); // setting to zero + fixedToFloat_arrL(st->hBWE_TD->fbbwe_hpf_mem_fx[1], st->hBWE_TD->fbbwe_hpf_mem[1], 0, 4); // setting to zero + fixedToFloat_arrL(st->hBWE_TD->fbbwe_hpf_mem_fx[2], st->hBWE_TD->fbbwe_hpf_mem[2], 0, 4); // setting to zero + fixedToFloat_arrL(st->hBWE_TD->fbbwe_hpf_mem_fx[3], st->hBWE_TD->fbbwe_hpf_mem[3], 0, 4); // setting to zero + st->hBWE_TD->prev_fbbwe_ratio = fixedToFloat(st->hBWE_TD->prev_fbbwe_ratio_fx, 0); // scaling unknown setting to 1 + } + } + /* Interp_3_2 CNG buffers reset */ + IF(st->hTdCngDec != NULL && EQ_32(st->output_Fs, 48000) && ((GT_32(st->last_core_brate, SID_2k40)) && (EQ_32(st->core_brate, FRAME_NO_DATA) || EQ_32(st->core_brate, SID_2k40)))) + { + fixedToFloat_arr(st->interpol_3_2_cng_dec_fx, st->hTdCngDec->interpol_3_2_cng_dec, 0, INTERP_3_2_MEM_LEN); + } + + /*------------------reset-code-end-----------------------*/ + + free(synth_fx16); + free(output_fx32); + free(output_mem_fx); + + if (sba_dirac_stereo_flag && hSCE && st->core_brate == SID_2k40 && st->cng_type == FD_CNG) + { + mvr2r(synth[n], hSCE->save_synth, output_frame); } /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ - if ( n == 0 && st->element_mode == IVAS_CPE_MDCT && st->last_core == ACELP_CORE && st->core != ACELP_CORE && ( nchan_out == 1 || ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_DFT ) ) ) + if (n == 0 && st->element_mode == IVAS_CPE_MDCT && st->last_core == ACELP_CORE && st->core != ACELP_CORE && (nchan_out == 1 || (hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_DFT))) { - mvr2r( sts[0]->previoussynth, sts[1]->previoussynth, st->hTcxDec->L_frameTCX ); + mvr2r(sts[0]->previoussynth, sts[1]->previoussynth, st->hTcxDec->L_frameTCX); } - /*---------------------------------------------------------------------* - * Pre-processing for bandwidth switching - *---------------------------------------------------------------------*/ - -#ifdef IVAS_FLOAT_FIXED - Word32 old_syn_12k8_16k_fx[L_FRAME16k]; - Word16 gb, norm, q_audio, old_syn_fx; - old_syn_fx = Q11; - floatToFixed_arrL(old_syn_12k8_16k[n], old_syn_12k8_16k_fx, old_syn_fx, L_FRAME16k); - norm = norm_arr_s(st->t_audio_q, L_FRAME); - gb = find_guarded_bits_fx(L_FRAME); - floatToFixed_arr(st->t_audio_q, st->t_audio_q_fx, norm - gb, L_FRAME); - q_audio = norm - gb; - - ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx, old_syn_fx, q_audio ); st->enerLH = fixedToFloat(st->enerLH_fx, st->enerLH_fx_Q); // Q / 2 st->tilt_wb = fix16_to_float(st->tilt_wb_fx, 11); st->enerLL = fixedToFloat(st->enerLL_fx, st->enerLL_fx_Q); - -#else - bw_switching_pre_proc( st, old_syn_12k8_16k, last_element_brate, nchan_out ); #endif - /*---------------------------------------------------------------------* * WB TBE decoding * WB BWE decoding @@ -2409,211 +2401,248 @@ ivas_error ivas_core_dec( * - core switching in DFT stereo * - updates for potential TD->DFT stereo switching *----------------------------------------------------------------*/ - - // TO DO delete below +#ifdef IVAS_FLOAT_FIXED + // TO DO delete below Word32 output_fx[CPE_CHANNELS][L_FRAME48k]; Word32 synth_fx[CPE_CHANNELS][L_FRAME48k]; - Word32 hb_synth_fx[CPE_CHANNELS][L_FRAME48k]; - FOR( int ch_ind = 0; ch_ind < n_channels; ch_ind++ ) + FOR(int ch_ind = 0; ch_ind < n_channels; ch_ind++) { - FOR( int ind = 0; ind < L_FRAME48k; ind++ ) - { - output_fx[ch_ind][ind] = (Word32) ( output[ch_ind][ind] * ( 1 << 11 ) ); - synth_fx[ch_ind][ind] = (Word32) ( synth[ch_ind][ind] * ( 1 << 11 ) ); - hb_synth_fx[ch_ind][ind] = (Word32) ( hb_synth[ch_ind][ind] * ( 1 << 11 ) ); - } + FOR(int ind = 0; ind < L_FRAME48k; ind++) + { + output_fx[ch_ind][ind] = (Word32)(output[ch_ind][ind] * (1 << 11)); + synth_fx[ch_ind][ind] = (Word32)(synth[ch_ind][ind] * (1 << 11)); + hb_synth_fx[ch_ind][ind] = (Word32)(hb_synth[ch_ind][ind] * (1 << 11)); + } } Word16 q_DFT[2] = { 3, 3 }; Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; - IF( DFT != NULL ) + IF(DFT != NULL) { - FOR( int ind = 0; ind < CPE_CHANNELS; ind++ ) + FOR(int ind = 0; ind < CPE_CHANNELS; ind++) + { + FOR(int j = 0; j < STEREO_DFT_BUF_MAX; j++) { - FOR( int j = 0; j < STEREO_DFT_BUF_MAX; j++ ) - { - DFT_fx[ind][j] = (Word32) ( DFT[ind][j] * ( 1 << q_DFT[ind] ) ); - } + DFT_fx[ind][j] = (Word32)(DFT[ind][j] * (1 << q_DFT[ind])); } + } } - if ( hCPE != NULL ) + if (hCPE != NULL) { - FOR( int ch_ind = 0; ch_ind < n_channels; ch_ind++ ) + FOR(int ch_ind = 0; ch_ind < n_channels; ch_ind++) + { + if (hCPE->hCoreCoder[ch_ind] != NULL) { - if ( hCPE->hCoreCoder[ch_ind] != NULL ) + if (hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL) + { + FOR(int ind = 0; ind < L_FRAME32k; ind++) { - if ( hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL ) - { - FOR( int ind = 0; ind < L_FRAME32k; ind++ ) - { - hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx[ind] = hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB[ind] * ( 1 << 11 ); - } - FOR( int ind = 0; ind < L_FRAME48k; ind++ ) - { - hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx[ind] = (Word32) ( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out[ind] * ( 1 << 11 ) ); - } - } - FOR( int ind = 0; ind < HQ_DELTA_MAX * HQ_DELAY_COMP; ind++ ) - { - hCPE->hCoreCoder[ch_ind]->delay_buf_out32_fx[ind] = (Word32) ( hCPE->hCoreCoder[ch_ind]->delay_buf_out[ind] * ( 1 << 11 ) ); - } - if ( hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_float != NULL ) - { - FOR( int ind = 0; ind < L_FRAME16k; ind++ ) - { - hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_32[ind] = (Word32) ( hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_float[ind] * ( 1 << 11 ) ); - } - } + hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx[ind] = hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB[ind] * (1 << 11); } - if ( hCPE->input_mem[ch_ind] ) + FOR(int ind = 0; ind < L_FRAME48k; ind++) { - FOR( int ind = 0; ind < NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ); ind++ ) - { - hCPE->input_mem_fx[ch_ind][ind] = (Word32) ( hCPE->input_mem[ch_ind][ind] * ( 1 << 11 ) ); - } + hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx[ind] = (Word32)(hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out[ind] * (1 << 11)); } - if ( hCPE->input_mem_LB[ch_ind] ) + } + FOR(int ind = 0; ind < HQ_DELTA_MAX * HQ_DELAY_COMP; ind++) + { + hCPE->hCoreCoder[ch_ind]->delay_buf_out32_fx[ind] = (Word32)(hCPE->hCoreCoder[ch_ind]->delay_buf_out[ind] * (1 << 11)); + } + if (hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_float != NULL) + { + FOR(int ind = 0; ind < L_FRAME16k; ind++) { - FOR( int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++ ) - { - hCPE->input_mem_LB_fx[ch_ind][ind] = (Word32) ( hCPE->input_mem_LB[ch_ind][ind] * ( 1 << 11 ) ); - } + hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_32[ind] = (Word32)(hCPE->hCoreCoder[ch_ind]->p_bpf_noise_buf_float[ind] * (1 << 11)); } - if ( hCPE->input_mem_BPF[0] != NULL ) + } + } + if (hCPE->input_mem[ch_ind]) + { + FOR(int ind = 0; ind < NS2SA(output_Fs, STEREO_DFT32MS_OVL_NS); ind++) + { + hCPE->input_mem_fx[ch_ind][ind] = (Word32)(hCPE->input_mem[ch_ind][ind] * (1 << 11)); + } + } + if (hCPE->input_mem_LB[ch_ind]) + { + FOR(int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++) + { + hCPE->input_mem_LB_fx[ch_ind][ind] = (Word32)(hCPE->input_mem_LB[ch_ind][ind] * (1 << 11)); + } + } + if (hCPE->input_mem_BPF[0] != NULL) + { + FOR(int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++) + { + hCPE->input_mem_BPF_fx[0][ind] = (Word32)(hCPE->input_mem_BPF[0][ind] * (1 << 11)); + } + } + IF(hCPE->output_mem[ch_ind] != NULL) + { + FOR(Word32 k = 0; k < NS2SA(hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS); k++) + { + hCPE->output_mem_fx[ch_ind][k] = (Word32)(hCPE->output_mem[ch_ind][k] * (1 << OUTPUT_Q)); + } + } + IF(hCPE->hStereoDft != NULL) + { + FOR(int ind = 0; ind < NS2SA(16000, DELAY_BWE_TOTAL_NS); ind++) + { + hCPE->hStereoDft->ap_delay_mem_fx[ind] = (Word32)(hCPE->hStereoDft->ap_delay_mem[ind] * (1 << 11)); + } + hCPE->hStereoDft->q_ap_delay_mem_fx = 11; + FOR(int ind = 0; ind < NS2SA(16000, STEREO_DFT32MS_OVL_NS); ind++) + { + hCPE->hStereoDft->buff_LBTCX_mem_fx[ind] = (Word32)(hCPE->hStereoDft->buff_LBTCX_mem[ind] * (1 << 11)); + } + IF(hCPE->hStereoDft->hTcxLtpDec != NULL) + { + FOR(Word32 p = 0; p < L_FRAME48k; p++) { - FOR( int ind = 0; ind < STEREO_DFT32MS_OVL_16k; ind++ ) - { - hCPE->input_mem_BPF_fx[0][ind] = (Word32) ( hCPE->input_mem_BPF[0][ind] * ( 1 << 11 ) ); - } + hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); } - IF(hCPE->output_mem[ch_ind] != NULL) + FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) { - FOR(Word32 k = 0; k < NS2SA(hCPE->hCoreCoder[0]->output_Fs, STEREO_DFT32MS_OVL_NS); k++) - { - hCPE->output_mem_fx[ch_ind][k] = (Word32)(hCPE->output_mem[ch_ind][k] * (1 << OUTPUT_Q)); - } + hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); } - IF( hCPE->hStereoDft != NULL ) - { - FOR( int ind = 0; ind < NS2SA( 16000, DELAY_BWE_TOTAL_NS ); ind++ ) - { - hCPE->hStereoDft->ap_delay_mem_fx[ind] = (Word32) ( hCPE->hStereoDft->ap_delay_mem[ind] * ( 1 << 11 ) ); - } - hCPE->hStereoDft->q_ap_delay_mem_fx = 11; - FOR( int ind = 0; ind < NS2SA( 16000, STEREO_DFT32MS_OVL_NS ); ind++ ) - { - hCPE->hStereoDft->buff_LBTCX_mem_fx[ind] = (Word32) ( hCPE->hStereoDft->buff_LBTCX_mem[ind] * ( 1 << 11 ) ); - } - IF(hCPE->hStereoDft->hTcxLtpDec != NULL) - { - FOR(Word32 p = 0; p < L_FRAME48k; p++) - { - hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); - } - FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) - { - hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); - } - hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); - hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain = (Word16)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); - } + hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); + hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain = (Word16)(hCPE->hStereoDft->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); + } - } - IF(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec != NULL) - { - FOR(Word32 p = 0; p < L_FRAME48k; p++) - { - hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); - } - FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) - { - hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); - } - hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); - hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain = (Word16)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); - } - IF(hCPE->hCoreCoder[ch_ind]->hTcxDec != NULL) - { - FOR(Word32 k = 0; k < 111; k++) - { - hCPE->hCoreCoder[ch_ind]->hTcxDec->FBTCXdelayBuf_32[k] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxDec->FBTCXdelayBuf_float[k] * (1 << OUTPUT_Q)); - } - } } + IF(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec != NULL) + { + FOR(Word32 p = 0; p < L_FRAME48k; p++) + { + hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); + } + FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) + { + hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); + } + hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); + hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain = (Word16)(hCPE->hCoreCoder[ch_ind]->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); + } + IF(hCPE->hCoreCoder[ch_ind]->hTcxDec != NULL) + { + FOR(Word32 k = 0; k < 111; k++) + { + hCPE->hCoreCoder[ch_ind]->hTcxDec->FBTCXdelayBuf_32[k] = (Word32)(hCPE->hCoreCoder[ch_ind]->hTcxDec->FBTCXdelayBuf_float[k] * (1 << OUTPUT_Q)); + } + } + } } - if ( hSCE != NULL ) + if (hSCE != NULL) { - if ( hSCE->hCoreCoder[0] != NULL ) + if (hSCE->hCoreCoder[0] != NULL) + { + if (hSCE->hCoreCoder[0]->hHQ_core != NULL) { - if ( hSCE->hCoreCoder[0]->hHQ_core != NULL ) - { - FOR( int ind = 0; ind < L_FRAME32k; ind++ ) - { - hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx[ind] = hSCE->hCoreCoder[0]->hHQ_core->old_outLB[ind] * ( 1 << 11 ); - } - FOR( int ind = 0; ind < L_FRAME48k; ind++ ) - { - hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx[ind] = (Word32) ( hSCE->hCoreCoder[0]->hHQ_core->old_out[ind] * ( 1 << 11 ) ); - } - } - FOR( int ind = 0; ind < HQ_DELTA_MAX * HQ_DELAY_COMP; ind++ ) - { - hSCE->hCoreCoder[0]->delay_buf_out32_fx[ind] = (Word32) ( hSCE->hCoreCoder[0]->delay_buf_out[ind] * ( 1 << 11 ) ); - } - IF(hSCE->hCoreCoder[0]->hTcxDec != NULL) - { - FOR(Word32 k = 0; k < 111; k++) - { - hSCE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32[k] = (Word32)(hSCE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_float[k] * (1 << OUTPUT_Q)); - } - } - IF(hSCE->hCoreCoder[0]->hTcxLtpDec != NULL) - { - FOR(Word32 p = 0; p < L_FRAME48k; p++) - { - hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); - } - FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) - { - hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); - } - hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); - hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain = (Word16)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); - } + FOR(int ind = 0; ind < L_FRAME32k; ind++) + { + hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx[ind] = hSCE->hCoreCoder[0]->hHQ_core->old_outLB[ind] * (1 << 11); + } + FOR(int ind = 0; ind < L_FRAME48k; ind++) + { + hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx[ind] = (Word32)(hSCE->hCoreCoder[0]->hHQ_core->old_out[ind] * (1 << 11)); + } + } + FOR(int ind = 0; ind < HQ_DELTA_MAX * HQ_DELAY_COMP; ind++) + { + hSCE->hCoreCoder[0]->delay_buf_out32_fx[ind] = (Word32)(hSCE->hCoreCoder[0]->delay_buf_out[ind] * (1 << 11)); + } + IF(hSCE->hCoreCoder[0]->hTcxDec != NULL) + { + FOR(Word32 k = 0; k < 111; k++) + { + hSCE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_32[k] = (Word32)(hSCE->hCoreCoder[0]->hTcxDec->FBTCXdelayBuf_float[k] * (1 << OUTPUT_Q)); + } + } + IF(hSCE->hCoreCoder[0]->hTcxLtpDec != NULL) + { + FOR(Word32 p = 0; p < L_FRAME48k; p++) + { + hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_out_32[p] = (Word32)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_out_float[p] * (1u << OUTPUT_Q)); + } + FOR(Word32 p = 0; p < TCXLTP_MAX_DELAY; p++) + { + hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_in_32[p] = (Word32)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_mem_in_float[p] * (1u << OUTPUT_Q)); + } + hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_post_prev = (Word16)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_post_prev_float * ONE_IN_Q15); + hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain = (Word16)(hSCE->hCoreCoder[0]->hTcxLtpDec->tcxltp_gain_float * ONE_IN_Q15); } + } } + Word32 exp_max = 0; + Word32 output_fx_loc[L_FRAME48k]; + floatToFixed_arr(st->tilt_code_dec, st->tilt_code_dec_fx, 15, 5); + floatToFixed_arr(st->old_synth_sw, st->old_synth_sw_fx, -2, 429); + st->prev_tilt_code_dec_fx = floatToFixed(st->prev_tilt_code_dec, Q15); + FOR(Word16 ind = 0; ind < 16; ind++) { + st->mem_AR_fx[ind] = (Word16)(st->mem_AR[ind] * 2.56f); + } + fixedToFloat_arr(st->old_synth_sw_fx, st->old_synth_sw, 0, 429); + + if ((st->codec_mode == MODE1 && st->hTcxDec != NULL) && ((st->core == ACELP_CORE && !(st->bfi == 1 && st->con_tcx == 1)) || st->core == HQ_CORE)) + { + double max_prev_synth_buffer = 0.0f, max_old_out = 0.0f, max_delay_buf_out = 0.0f, max_ouput = 0.0f, max_synth_history = 0.0f; + Word32 exp_prev_synth_buffer = 0, exp_old_out = 0, exp_delay_buf_out = 0, exp_ouput = 0, exp_synth_history = 0; + /*Find a commen maximum exp*/ + exp_max = 20; + + for (i = 0; i < NS2SA(st->output_Fs, DELAY_CLDFB_NS); i++) + { + f2fix_16(&st->delay_buf_out[i], &st->delay_buf_out_fx[i], exp_max); + } + for (i = NS2SA(st->output_Fs, N_ZERO_MDCT_NS); i < NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS); i++) + { + f2fix_16(&st->hHQ_core->old_out[i], &st->hHQ_core->old_out_fx[i], exp_max); + } + for (i = 0; i < NS2SA(48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS); i++) + { + f2fix_16(&st->prev_synth_buffer[i], &st->prev_synth_buffer_fx[i], exp_max); + } + for (i = output_frame; i < 2 * output_frame - NS2SA(st->output_Fs, DELAY_CLDFB_NS) + NS2SA(st->output_Fs, PH_ECU_MEM_NS); i++) + { + f2fix_16(&st->hTcxDec->synth_history[i], &st->hTcxDec->synth_history_fx[i], exp_max); + } + for (i = 0; i < output_frame; i++) + { + f2fix(&output[n][i], &output_fx_loc[i], exp_max); + } + } +#endif - if ( st->element_mode != IVAS_CPE_DFT ) + IF ( NE_16(st->element_mode, IVAS_CPE_DFT )) { - if ( st->element_mode != IVAS_CPE_MDCT || sba_dirac_stereo_flag ) + IF ( NE_16(st->element_mode, IVAS_CPE_MDCT) || sba_dirac_stereo_flag ) { ivas_post_proc_fx( hSCE, hCPE, n, synth_fx[n], NULL, output_frame, sba_dirac_stereo_flag ); - } /* update OLA buffers - needed for switching to DFT stereo */ - if ( !sba_dirac_stereo_flag ) + IF ( !sba_dirac_stereo_flag ) { - if ( hCPE != NULL ) + IF ( hCPE != NULL ) { stereo_td2dft_update_fx( hCPE, n, &output_fx[n], &synth_fx[n], &hb_synth_fx[n], output_frame ); } } } - else /* IVAS_CPE_DFT */ + ELSE /* IVAS_CPE_DFT */ { Word16 q = 11; - if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) + IF ( EQ_16(hCPE->last_element_mode, IVAS_CPE_MDCT )) { stereo_mdct2dft_update_fx( hCPE, output_fx[0], synth_fx[0] ); } stereo_dft_dec_core_switching_fx( hCPE, output_fx[0], synth_fx[0], hb_synth_fx[0], DFT_fx, output_frame, use_cldfb_for_dft, 0, &q, q_DFT ); - if ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + IF (EQ_16(hCPE->nchan_out, 1) && EQ_16(hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF )) { /* mono output for non-residual coding modes uses CLDFB instead of DFT - requires DFT buffer update in case of bitrate switching */ stereo_td2dft_update_fx( hCPE, n, &output_fx[n], &synth_fx[n], &hb_synth_fx[n], output_frame ); @@ -2622,6 +2651,45 @@ ivas_error ivas_core_dec( Copy32( synth_fx[n], output_fx[n], output_frame ); + /*--------------------------------------------------------* + * Common updates + *--------------------------------------------------------*/ + + /*Scale Memories*/ +#if 0 + test(); test(); test(); test(); test(); + IF ((EQ_16(st->codec_mode, MODE1) && st->hTcxDec != NULL) && ((EQ_16(st->core, ACELP_CORE) && !(EQ_16(st->bfi, 1) && EQ_16(st->con_tcx, 1))) || EQ_16(st->core, HQ_CORE))) + { + Word16 exp_prev_synth_buffer = 0, exp_old_out = 0, exp_delay_buf_out = 0, exp_ouput = 0, exp_synth_history = 0, temp = 0; move16(); move16(); move16(); move16(); move16(); move16(); + exp_ouput = Find_Max_Norm32(output_fx[n], output_frame); + exp_prev_synth_buffer = Find_Max_Norm16(st->prev_synth_buffer_fx, NS2SA(48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)); + exp_old_out = Find_Max_Norm16(st->hHQ_core->old_out_fx + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), NS2SA(st->output_Fs, N_ZERO_MDCT_NS) + NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS) - NS2SA(st->output_Fs, N_ZERO_MDCT_NS)); + exp_delay_buf_out = Find_Max_Norm16(st->delay_buf_out_fx, NS2SA(st->output_Fs, DELAY_CLDFB_NS)); + exp_synth_history = Find_Max_Norm16(st->hTcxDec->synth_history_fx + output_frame, 2 * output_frame - NS2SA(st->output_Fs, DELAY_CLDFB_NS) + NS2SA(st->output_Fs, PH_ECU_MEM_NS) - output_frame); + + exp_max = max(exp_synth_history, exp_ouput); move16(); + exp_max = max(exp_max, exp_prev_synth_buffer); move16(); + exp_max = max(exp_max, exp_old_out); move16(); + exp_max = max(exp_max, exp_delay_buf_out); move16(); + + Copy32(output_fx[n], output_fx_loc, output_frame); + Scale_sig32(output_fx_loc, output_frame, exp_max); + Scale_sig(st->delay_buf_out_fx, NS2SA(st->output_Fs, DELAY_CLDFB_NS), exp_delay_buf_out); + Scale_sig(st->hHQ_core->old_out_fx + NS2SA(st->output_Fs, N_ZERO_MDCT_NS), NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS) - NS2SA(st->output_Fs, N_ZERO_MDCT_NS), exp_old_out); + Scale_sig(st->prev_synth_buffer_fx, NS2SA(48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS), exp_synth_history); + Scale_sig(st->hTcxDec->synth_history_fx + output_frame, 2 * output_frame - NS2SA(st->output_Fs, DELAY_CLDFB_NS) + NS2SA(st->output_Fs, PH_ECU_MEM_NS) - output_frame, exp_synth_history); + + st->hTcxDec->q_synth_history_fx = exp_synth_history; + } +#endif + /* Save synthesis for HQ FEC */ + save_synthesis_hq_fec_fx( st, output_fx[n], output_frame, hCPE ); + + /* Updates */ + + ivas_updt_dec_common_fx( st, NORMAL_HQ_CORE, -1, output_fx[n], 11 ); + +#ifdef IVAS_FLOAT_FIXED // TO DO delete below FOR( int ch_ind = 0; ch_ind < n_channels; ch_ind++ ) { @@ -2788,139 +2856,20 @@ ivas_error ivas_core_dec( } } - /*--------------------------------------------------------* - * Common updates - *--------------------------------------------------------*/ - - /* Save synthesis for HQ FEC */ -#ifdef IVAS_FLOAT_FIXED - Word32 exp_max = 0; - Word32 output_fx_loc[L_FRAME48k]; - if ( ( st->codec_mode == MODE1 && st->hTcxDec != NULL ) && ( ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) ) || st->core == HQ_CORE ) ) - { - double max_prev_synth_buffer = 0.0f, max_old_out = 0.0f, max_delay_buf_out = 0.0f, max_ouput = 0.0f, max_synth_history = 0.0f; - Word32 exp_prev_synth_buffer = 0, exp_old_out = 0, exp_delay_buf_out = 0, exp_ouput = 0, exp_synth_history = 0; - - /*Find maximum values for all the buffers*/ - for ( i = 0; i < NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ); i++ ) - { - max_prev_synth_buffer = max( max_prev_synth_buffer, fabs( st->prev_synth_buffer[i] ) ); - } - if ( (Word16) max_prev_synth_buffer != 0 ) - { - frexp( max_prev_synth_buffer, &exp_prev_synth_buffer ); - } - - for ( i = NS2SA( st->output_Fs, N_ZERO_MDCT_NS ); i < NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) + NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ); i++ ) - { - max_old_out = max( max_old_out, fabs( st->hHQ_core->old_out[i] ) ); - } - if ( (Word16) max_old_out != 0 ) - { - frexp( max_old_out, &exp_old_out ); - } - - for ( i = 0; i < NS2SA( st->output_Fs, DELAY_CLDFB_NS ); i++ ) - { - max_delay_buf_out = max( max_delay_buf_out, fabs( st->delay_buf_out[i] ) ); - } - if ( (Word16) max_delay_buf_out != 0 ) - { - frexp( max_delay_buf_out, &exp_delay_buf_out ); - } - - for ( i = 0; i < output_frame; i++ ) - { - max_ouput = max( max_ouput, fabs( output[n][i] ) ); - } - if ( (Word16) max_ouput != 0 ) - { - frexp( max_ouput, &exp_ouput ); - } - - for ( i = output_frame; i < 2 * output_frame - NS2SA( st->output_Fs, DELAY_CLDFB_NS ) + NS2SA( st->output_Fs, PH_ECU_MEM_NS ); i++ ) - { - max_synth_history = max( max_synth_history, fabs( st->hTcxDec->synth_history[i] ) ); - } - - if ( (Word16) max_synth_history != 0 ) - { - frexp( max_synth_history, &exp_synth_history ); - } - - /*Find a commen maximum exp*/ - exp_max = max( exp_synth_history, exp_ouput ); - exp_max = max( exp_max, exp_prev_synth_buffer ); - exp_max = max( exp_max, exp_old_out ); - exp_max = max( exp_max, exp_delay_buf_out ); - - for ( i = 0; i < NS2SA( st->output_Fs, DELAY_CLDFB_NS ); i++ ) - { - f2fix_16( &st->delay_buf_out[i], &st->delay_buf_out_fx[i], exp_max ); - } - for ( i = NS2SA( st->output_Fs, N_ZERO_MDCT_NS ); i < NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ); i++ ) - { - f2fix_16( &st->hHQ_core->old_out[i], &st->hHQ_core->old_out_fx[i], exp_max ); - } - for ( i = 0; i < NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ); i++ ) - { - f2fix_16( &st->prev_synth_buffer[i], &st->prev_synth_buffer_fx[i], exp_max ); - } - for ( i = output_frame; i < 2 * output_frame - NS2SA( st->output_Fs, DELAY_CLDFB_NS ) + NS2SA( st->output_Fs, PH_ECU_MEM_NS ); i++ ) - { - f2fix_16( &st->hTcxDec->synth_history[i], &st->hTcxDec->synth_history_fx[i], exp_max ); - } - for ( i = 0; i < output_frame; i++ ) - { - f2fix( &output[n][i], &output_fx_loc[i], exp_max ); - } - } - save_synthesis_hq_fec_fx( st, output_fx_loc, output_frame, hCPE ); - //save_synthesis_hq_fec(st, output[n], output_frame, hCPE); - if ( ( st->codec_mode == MODE1 && st->hTcxDec != NULL ) && ( ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) ) || st->core == HQ_CORE ) ) + if ((st->last_codec_mode == MODE1 && st->hTcxDec != NULL) && ((st->last_core == ACELP_CORE && !(st->bfi == 1 && st->last_con_tcx == 1)) || st->last_core == HQ_CORE)) { - /*dumps*/ - float track = 0; - for ( i = 0; i < 2 * output_frame + NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ); i++ ) - { - fix2f_16( &st->hTcxDec->synth_history_fx[i], &track, exp_max ); - fix2f_16( &st->hTcxDec->synth_history_fx[i], &st->hTcxDec->synth_history[i], exp_max ); - -#ifdef DUMPS_ENABLED - dbgwrite_txt( &track, 1, "Fixed_code_synth_history_fx.txt", NULL ); - dbgwrite_txt( &st->hTcxDec->synth_history[i], 1, "Float_code_synth_history_fx.txt", NULL ); -#endif - } - } -#else - save_synthesis_hq_fec( st, output[n], output_frame, hCPE ); -#endif - - /* Updates */ -#ifdef IVAS_FLOAT_FIXED -#if 1 // Conversion - floatToFixed_arrL(output[n], output_fx_loc, 11, 960); - floatToFixed_arr(st->tilt_code_dec, st->tilt_code_dec_fx, 15, 5); - floatToFixed_arr(st->old_synth_sw, st->old_synth_sw_fx, -2, 429); - st->prev_tilt_code_dec_fx = floatToFixed(st->prev_tilt_code_dec, Q15); - FOR(Word16 ind = 0; ind < 16; ind++) { - st->mem_AR_fx[ind] = (Word16)(st->mem_AR[ind] * 2.56f); + for (i = 0; i < 2 * output_frame + NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS); i++) + { + fix2f_16(&st->hTcxDec->synth_history_fx[i], &st->hTcxDec->synth_history[i], exp_max); + } } - fixedToFloat_arr(st->old_synth_sw_fx, st->old_synth_sw, 0, 429); -#endif - ivas_updt_dec_common_fx( st, NORMAL_HQ_CORE, -1, output_fx_loc, 11 ); -#if 1 fixedToFloat_arr(st->old_synth_sw_fx, st->old_synth_sw, -2, 429); FOR(Word16 ind = 0; ind < 16; ind++) { st->mem_AR[ind] = st->mem_AR_fx[ind] / 2.56f; } st->prev_tilt_code_dec = fixedToFloat(st->prev_tilt_code_dec_fx, Q15); #endif -#else - updt_dec_common( st, NORMAL_HQ_CORE, -1, output[n] ); -#endif - } /* n_channels loop */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 3124e1bd9c53c17783df2fd5ce2ef23e9c26b0df..0dfec42d4a9eb137593ad846f2cc42f79809e9f5 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1013,8 +1013,7 @@ ivas_error ivas_init_decoder_front( return error; } #ifdef IVAS_FLOAT_FIXED - error = ivas_orient_trk_SetTrackingType_fx( st_ivas->hHeadTrackData->OrientationTracker_fx, st_ivas->hDecoderConfig->orientation_tracking ); - st_ivas->hHeadTrackData->OrientationTracker->orientation_tracking = st_ivas->hHeadTrackData->OrientationTracker_fx->orientation_tracking_fx; + error = ivas_orient_trk_SetTrackingType_fx( st_ivas->hHeadTrackData->OrientationTracker, st_ivas->hDecoderConfig->orientation_tracking ); IF( ( error ) != IVAS_ERR_OK ) { return error; @@ -2026,7 +2025,11 @@ ivas_error ivas_init_decoder( } granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); +#ifdef IVAS_FLOAT_FIXED + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); +#else n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); +#endif // IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED IF ( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) @@ -2080,7 +2083,11 @@ ivas_error ivas_init_decoder( { granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); +#ifdef IVAS_FLOAT_FIXED + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); +#else n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); +#endif // IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED IF ( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ) != IVAS_ERR_OK ) @@ -2095,7 +2102,11 @@ ivas_error ivas_init_decoder( { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); +#ifdef IVAS_FLOAT_FIXED + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); +#else n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); +#endif #ifdef IVAS_FLOAT_FIXED IF ( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) @@ -2229,7 +2240,11 @@ ivas_error ivas_init_decoder( * CLDFB handles for rendering *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses ); +#else ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses ); +#endif // IVAS_FLOAT_FIXED FOR ( i = 0; i < numCldfbAnalyses; i++ ) { @@ -2278,7 +2293,11 @@ ivas_error ivas_init_decoder( { /* no module has yet open the TC buffer, open a default one */ +#ifdef IVAS_FLOAT_FIXED + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); +#else n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); +#endif #ifdef IVAS_FLOAT_FIXED IF ( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 48cea7061e6302822d7e59f1844e39a54cd6eb4a..8e99bd186a22e0828c629d0c2e97d82a7ae3f599 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -44,11 +44,37 @@ #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" +#ifdef IVAS_FLOAT_FIXED +#include "ivas_rom_com_fx.h" +#endif // IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------* * Local function definitions *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_dec_dequant_DOA_fx( + PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ + const Word16 nchan_ism /* i : number of ISM channels */ +) +{ + Word16 i; + PARAM_ISM_CONFIG_HANDLE hParamIsm; + + hParamIsm = hParamIsmDec->hParamIsm; + + assert( nchan_ism <= MAX_NUM_OBJECTS ); + + /* Get the azimuth and elevation values */ + FOR ( i = 0; i < nchan_ism; i++ ) + { + hParamIsmDec->azimuth_values_fx[i] = ism_dequant_meta_fx( hParamIsm->azi_index[i], ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); + hParamIsmDec->elevation_values_fx[i] = ism_dequant_meta_fx( hParamIsm->ele_index[i], ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); + } + + return; +} +#endif // IVAS_FLOAT_FIXED static void ivas_param_ism_dec_dequant_DOA( PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ const int16_t nchan_ism /* i : number of ISM channels */ @@ -71,6 +97,27 @@ static void ivas_param_ism_dec_dequant_DOA( return; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_dec_dequant_powrat_fx( + PARAM_ISM_DEC_HANDLE hParamIsmDec /* i/o: decoder ParamISM handle */ +) +{ + Word16 band_idx, slot_idx; + PARAM_ISM_CONFIG_HANDLE hParamIsm; + + hParamIsm = hParamIsmDec->hParamIsm; + /* Get the power ratio values */ + for ( band_idx = 0; band_idx < hParamIsm->nbands; band_idx++ ) + { + for ( slot_idx = 0; slot_idx < hParamIsm->nblocks[band_idx]; slot_idx++ ) + { + hParamIsmDec->power_ratios_fx[band_idx][slot_idx][0] = add( shr( div_s( ( hParamIsm->power_ratios_idx[band_idx][slot_idx] ), ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ), 1 ), 16384 ); + hParamIsmDec->power_ratios_fx[band_idx][slot_idx][1] = sub( 32767, hParamIsmDec->power_ratios_fx[band_idx][slot_idx][0] ); + } + } + return; +} +#endif // IVAS_FLOAT_FIXED static void ivas_param_ism_dec_dequant_powrat( PARAM_ISM_DEC_HANDLE hParamIsmDec /* i/o: decoder ParamISM handle */ @@ -1181,8 +1228,36 @@ void ivas_param_ism_dec( /* De-quantization */ if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) { +#ifdef IVAS_FLOAT_FIXED + ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism ); + fixedToFloat_arrL( hParamIsmDec->azimuth_values_fx, hParamIsmDec->azimuth_values, 22, st_ivas->nchan_ism ); + fixedToFloat_arrL( hParamIsmDec->elevation_values_fx, hParamIsmDec->elevation_values, 22, st_ivas->nchan_ism ); + for ( int i = 0; i < 11; i++ ) + { + for ( int j = 0; j < 1; j++ ) + { + for ( int k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios_fx[i][j][k] = (Word16) floatToFixed( hParamIsmDec->power_ratios[i][j][k], 15 ); + } + } + } + ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec ); + for ( int i = 0; i < 11; i++ ) + { + for ( int j = 0; j < 1; j++ ) + { + for ( int k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios[i][j][k] = fixedToFloat( hParamIsmDec->power_ratios_fx[i][j][k], 15 ); + } + } + } +#else ivas_param_ism_dec_dequant_DOA( hParamIsmDec, st_ivas->nchan_ism ); ivas_param_ism_dec_dequant_powrat( hParamIsmDec ); +#endif // IVAS_FLOAT_FIXED + st_ivas->hISMDTX.dtx_flag = 0; } else @@ -1353,6 +1428,108 @@ void ivas_param_ism_dec( * * *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_dec_digest_tc_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + IF( st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0 ) ) + { + Word16 i, num_objects; + Word32 azimuth_fx, elevation_fx; + + /* we have a full frame interpolator, adapt it */ + /* for BE testing */ + IF( ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ) == st_ivas->hTcBuffer->n_samples_available ) + { + int16_t interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + + IF( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + st_ivas->hIsmRendererData->interpolator_fx[0] = 0; + FOR( i = 1; i < interpolator_length; i++ ) + { + Word16 tmp = div_s( 1, interpolator_length - 1 ); + st_ivas->hIsmRendererData->interpolator_fx[i] = add( st_ivas->hIsmRendererData->interpolator_fx[i - 1], tmp ); // Q15 + } + } + ELSE + { + FOR( i = 0; i < interpolator_length; i++ ) + { + st_ivas->hIsmRendererData->interpolator_fx[i] = div_s( i, sub( interpolator_length, 1 ) ); // Q15 + } + } + } + ELSE + { + ivas_jbm_dec_get_adapted_linear_interpolator_fx( (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ), st_ivas->hTcBuffer->n_samples_available, st_ivas->hIsmRendererData->interpolator_fx ); + } + + /* also get the gains here */ + num_objects = st_ivas->nchan_transport; + FOR( i = 0; i < num_objects; i++ ) + { + Copy32( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmRendererData->prev_gains_fx[i], MAX_OUTPUT_CHANNELS ); + + IF( st_ivas->intern_config == IVAS_AUDIO_CONFIG_STEREO ) + { + Word16 gains_fx[2]; + ivas_ism_get_stereo_gains_fx( (Word16) st_ivas->hIsmMetaData[i]->azimuth, (Word16) st_ivas->hIsmMetaData[i]->elevation, &gains_fx[0], &gains_fx[1] ); + st_ivas->hIsmRendererData->gains_fx[i][0] = L_shr( L_deposit_h( gains_fx[0] ), 1 ); + st_ivas->hIsmRendererData->gains_fx[i][1] = L_shr( L_deposit_h( gains_fx[1] ), 1 ); + } + ELSE + { + // TODO tmu review when #215 is resolved + azimuth_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->azimuth_fx, 2097152 ), Q22 ); + elevation_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->elevation_fx, 2097152 ), Q22 ); + + IF( ( st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) && + st_ivas->hCombinedOrientationData == NULL ) + { + IF( st_ivas->hIntSetup.is_planar_setup ) + { + /* If no elevation support in output format, then rendering should be done with zero elevation */ + elevation_fx = 0; + } + + IF( st_ivas->hEFAPdata != NULL ) + { + azimuth_fx = L_shl( azimuth_fx, Q22 ); + elevation_fx = L_shl( elevation_fx, Q22 ); + efap_determine_gains_fixed( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); + } + } + ELSE IF( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + /*get HOA gets for direction (ACN/SN3D)*/ + Word16 azi = shr( extract_h( st_ivas->hIsmMetaData[i]->azimuth_fx ), 22 - 16 ); + Word16 ele = shr( extract_h( st_ivas->hIsmMetaData[i]->elevation_fx ), 22 - 16 ); + ivas_dirac_dec_get_response_fx( azi, ele, st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIntSetup.ambisonics_order ); + } + } + } + } + + return; +} +#endif void ivas_ism_dec_digest_tc( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ @@ -1374,6 +1551,39 @@ void ivas_ism_dec_digest_tc( /* we have a full frame interpolator, adapt it */ /* for BE testing */ +#ifdef IVAS_FLOAT_FIXED + IF((st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC) == st_ivas->hTcBuffer->n_samples_available) + { + int16_t interpolator_length = (int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC); + + IF(st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV) + { + st_ivas->hIsmRendererData->interpolator_fx[0] = 0; + FOR(i = 1; i < interpolator_length; i++) + { + Word16 tmp = div_s(1, interpolator_length - 1); + st_ivas->hIsmRendererData->interpolator_fx[i] = add(st_ivas->hIsmRendererData->interpolator_fx[i - 1], tmp); // Q15 + } + } + ELSE + { + FOR(i = 0; i < interpolator_length; i++) + { + st_ivas->hIsmRendererData->interpolator_fx[i] = div_s(i, sub(interpolator_length, 1)); // Q15 + } + } + } + ELSE + { + ivas_jbm_dec_get_adapted_linear_interpolator_fx((int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC), st_ivas->hTcBuffer->n_samples_available, st_ivas->hIsmRendererData->interpolator_fx); + } + FOR(i = 0; i < (int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC); i++) + { + st_ivas->hIsmRendererData->interpolator[i] = fixedToFloat(st_ivas->hIsmRendererData->interpolator_fx[i], Q15); + } +#else if ( ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ) == st_ivas->hTcBuffer->n_samples_available ) { int16_t interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); @@ -1390,9 +1600,9 @@ void ivas_ism_dec_digest_tc( } else { - for ( i = 0; i < interpolator_length; i++ ) + for (i = 0; i < interpolator_length; i++) { - st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); + st_ivas->hIsmRendererData->interpolator[i] = (float)i / ((float)interpolator_length - 1); } } } @@ -1400,6 +1610,7 @@ void ivas_ism_dec_digest_tc( { ivas_jbm_dec_get_adapted_linear_interpolator( (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ), st_ivas->hTcBuffer->n_samples_available, st_ivas->hIsmRendererData->interpolator ); } +#endif /* also get the gains here */ num_objects = st_ivas->nchan_transport; @@ -1437,7 +1648,17 @@ void ivas_ism_dec_digest_tc( if ( st_ivas->hEFAPdata != NULL ) { - efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); +#ifdef IVAS_FLOAT_FIXED + Word32 azimuth_fx = L_shr(L_add(st_ivas->hIsmMetaData[i]->azimuth_fx, 2097152), Q22); + Word32 elevation_fx = L_shr(L_add(st_ivas->hIsmMetaData[i]->elevation_fx, 2097152), Q22); + efap_determine_gains_fixed(st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azimuth_fx, elevation_fx, EFAP_MODE_EFAP); + FOR(Word32 j = 0; j < MAX_OUTPUT_CHANNELS; j++) + { + st_ivas->hIsmRendererData->gains[i][j] = ((float)st_ivas->hIsmRendererData->gains_fx[i][j]) / L_shl(1, Q30); + } +#else + efap_determine_gains(st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP); +#endif } } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || @@ -1445,7 +1666,16 @@ void ivas_ism_dec_digest_tc( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { /*get HOA gets for direction (ACN/SN3D)*/ - ivas_dirac_dec_get_response( azimuth, elevation, st_ivas->hIsmRendererData->gains[i], st_ivas->hIntSetup.ambisonics_order ); +#ifdef IVAS_FLOAT_FIXED + Word16 azi = shr(extract_h(st_ivas->hIsmMetaData[i]->azimuth_fx), 22 - 16); + Word16 ele = shr(extract_h(st_ivas->hIsmMetaData[i]->elevation_fx), 22 - 16); + ivas_dirac_dec_get_response_fx(azi, ele, st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIntSetup.ambisonics_order); + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->gains_fx[i][j], Q30); + } +#else + ivas_dirac_dec_get_response(azimuth, elevation, st_ivas->hIsmRendererData->gains[i], st_ivas->hIntSetup.ambisonics_order); +#endif } } } @@ -1454,7 +1684,6 @@ void ivas_ism_dec_digest_tc( return; } - /*-------------------------------------------------------------------------* * ivas_param_ism_dec_digest_tc() * @@ -1523,8 +1752,35 @@ void ivas_param_ism_dec_digest_tc( /* De-quantization */ if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) { +#ifdef IVAS_FLOAT_FIXED + ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism ); + fixedToFloat_arrL( hParamIsmDec->azimuth_values_fx, hParamIsmDec->azimuth_values, 22, st_ivas->nchan_ism ); + fixedToFloat_arrL( hParamIsmDec->elevation_values_fx, hParamIsmDec->elevation_values, 22, st_ivas->nchan_ism ); + for ( int i = 0; i < 11; i++ ) + { + for ( int j = 0; j < 1; j++ ) + { + for ( int k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios_fx[i][j][k] = (Word16) floatToFixed( hParamIsmDec->power_ratios[i][j][k], 15 ); + } + } + } + ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec ); + for ( int i = 0; i < 11; i++ ) + { + for ( int j = 0; j < 1; j++ ) + { + for ( int k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios[i][j][k] = fixedToFloat( hParamIsmDec->power_ratios_fx[i][j][k], 15 ); + } + } + } +#else ivas_param_ism_dec_dequant_DOA( hParamIsmDec, st_ivas->nchan_ism ); ivas_param_ism_dec_dequant_powrat( hParamIsmDec ); +#endif // IVAS_FLOAT_FIXED st_ivas->hISMDTX.dtx_flag = 0; } else @@ -2328,6 +2584,156 @@ void ivas_param_ism_dec_render( * * *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_ism_params_to_masa_param_mapping_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + Word16 nBins; + Word16 band_idx, bin_idx, sf_idx; + Word16 brange[2]; + Word16 azimuth[2]; + Word16 elevation[2]; + Word16 power_ratio_fx[2]; + Word32 ivas_total_brate; + + hParamIsmDec = st_ivas->hParamIsmDec; + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + nBins = hSpatParamRendCom->num_freq_bands; + + move16(); + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + move32(); + + IF ( !( EQ_32(ivas_total_brate , IVAS_SID_5k2) || EQ_32(ivas_total_brate , FRAME_NO_DATA) ) ) + { + ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec ); + st_ivas->hISMDTX.dtx_flag = 0; + move16(); + } + ELSE + { + st_ivas->hISMDTX.dtx_flag = 1; + move16(); + } + + IF ( GT_16(st_ivas->nchan_ism , 1) ) + { + IF ( st_ivas->hISMDTX.dtx_flag ) + { + Word16 energy_ratio_fx; + energy_ratio_fx = mult( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx );/*Q15*/ + + hSpatParamRendCom->numSimultaneousDirections = 1; + move16(); + azimuth[0] = (Word16) L_shr(( hParamIsmDec->azimuth_values_fx[0] +(1<<21)),22); + elevation[0] = (Word16) L_shr(( hParamIsmDec->elevation_values_fx[0] + (1 << 21)),22); + + FOR ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + FOR ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; + hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; + + hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = energy_ratio_fx; + + hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0; + hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0; + move16(); + move16(); + move32(); + move16(); + move16(); + } + } + } + ELSE + { + hSpatParamRendCom->numSimultaneousDirections = 2; + move16(); + FOR ( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ ) + { + brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + + move16(); + move16(); + azimuth[0] = (Word16) L_shr( hParamIsmDec->azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] + (1 << 21),22); + elevation[0] = (Word16)L_shr(hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]] + (1 << 21),22); + + power_ratio_fx[0] = hParamIsmDec->power_ratios_fx[band_idx][0][0]; + move16(); + azimuth[1] = (Word16)L_shr(hParamIsmDec->azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]] + (1 << 21),22); + elevation[1] = (Word16)L_shr(hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]]+ (1 << 21),22 ); + power_ratio_fx[1] = hParamIsmDec->power_ratios_fx[band_idx][0][1]; + + move16(); + + FOR ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + FOR ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) + { + hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; + hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; + hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = power_ratio_fx[0]; + hSpatParamRendCom->azimuth2[sf_idx][bin_idx] = azimuth[1]; + hSpatParamRendCom->elevation2[sf_idx][bin_idx] = elevation[1]; + hSpatParamRendCom->energy_ratio2_fx[sf_idx][bin_idx] = power_ratio_fx[1]; + move16(); + move16(); + move16(); + move16(); + move32(); + move32(); + } + } + } + + FOR ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + FOR ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0; + hSpatParamRendCom->spreadCoherence2_fx[sf_idx][bin_idx] = 0; + hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0; + move16(); + move16(); + move16(); + } + } + } + } + ELSE + { + hSpatParamRendCom->numSimultaneousDirections = 1; + move16(); + azimuth[0] = (Word16) L_shr((hParamIsmDec->azimuth_values_fx[0] + (1 << 21)),22); + elevation[0] = (Word16)L_shr( hParamIsmDec->elevation_values_fx[0] + (1 << 21),22); + + FOR ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + FOR ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0]; + hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0]; + hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = 32767; + hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0; + hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0; + move16(); + move16(); + move32(); + move16(); + move16(); + } + } + } + return; +} +#endif // IVAS_FLOAT_FIXED void ivas_param_ism_params_to_masa_param_mapping( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 3d4d4c9d9ccc2ea8f4898cedb65fc6568ab17f9b..f473b9849cc620a763e9dab230e55cce7156d594 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3332,10 +3332,67 @@ void ivas_jbm_dec_feed_tc_to_renderer( { #ifdef IVAS_FLOAT_FIXED ivas_dirac_dec_set_md_map_fx( st_ivas, n_render_timeslots ); +#if 1/*Float to fix */ + PARAM_ISM_DEC_HANDLE hParamIsmDec; + hParamIsmDec = st_ivas->hParamIsmDec; + floatToFixed_arrL( hParamIsmDec->azimuth_values, hParamIsmDec->azimuth_values_fx, 22, st_ivas->nchan_ism ); + floatToFixed_arrL( hParamIsmDec->elevation_values, hParamIsmDec->elevation_values_fx, 22, st_ivas->nchan_ism ); + FOR( Word16 i = 0; i < 11; i++ ) + { + FOR( Word16 j = 0; j < 1; j++ ) + { + FOR( Word16 k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios_fx[i][j][k] = (Word16) floatToFixed( hParamIsmDec->power_ratios[i][j][k], 15 ); + } + } + } + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = float_to_fix16( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt, 15 ); + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + Word16 nBins = hSpatParamRendCom->num_freq_bands; + for ( Word16 sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( Word16 bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = float_to_fix16( hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = float_to_fix16( hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = float_to_fix16( hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->spreadCoherence2_fx[sf_idx][bin_idx] = float_to_fix16( hSpatParamRendCom->spreadCoherence2[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->energy_ratio2_fx[sf_idx][bin_idx] = float_to_fix16( hSpatParamRendCom->energy_ratio2[sf_idx][bin_idx], 15 ); + } + } +#endif // IVAS_FLOAT_FIXED + ivas_param_ism_params_to_masa_param_mapping_fx( st_ivas ); +#if 1 /*Fix to float*/ + fixedToFloat_arrL( hParamIsmDec->azimuth_values_fx, hParamIsmDec->azimuth_values, 22, st_ivas->nchan_ism ); + fixedToFloat_arrL( hParamIsmDec->elevation_values_fx, hParamIsmDec->elevation_values, 22, st_ivas->nchan_ism ); + FOR( Word16 i = 0; i < 11; i++ ) + { + FOR( Word16 j = 0; j < 1; j++ ) + { + FOR( Word16 k = 0; k < 2; k++ ) + { + hParamIsmDec->power_ratios[i][j][k] = fixedToFloat( hParamIsmDec->power_ratios_fx[i][j][k], 15 ); + } + } + } + for ( Word16 sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( Word16 bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = fixedToFloat( hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = fixedToFloat( hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = fixedToFloat( hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->spreadCoherence2[sf_idx][bin_idx] = fixedToFloat( hSpatParamRendCom->spreadCoherence2_fx[sf_idx][bin_idx], 15 ); + hSpatParamRendCom->energy_ratio2[sf_idx][bin_idx] = fixedToFloat( hSpatParamRendCom->energy_ratio2_fx[sf_idx][bin_idx], 15 ); + } + } +#endif #else ivas_dirac_dec_set_md_map( st_ivas, n_render_timeslots ); -#endif ivas_param_ism_params_to_masa_param_mapping( st_ivas ); +#endif } else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { @@ -3344,7 +3401,70 @@ void ivas_jbm_dec_feed_tc_to_renderer( } else /* ISM_MODE_DISC */ { - ivas_ism_dec_digest_tc( st_ivas ); + +#ifdef IVAS_FLOAT_FIXED + Word16 len = (int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC); + Word16 num_objects = st_ivas->nchan_transport; + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator_fx[idx] = floatToFixed(st_ivas->hIsmRendererData->interpolator[idx], Q15); + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->gains[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->prev_gains[i][j], Q30); + } + } + } + } + + ivas_ism_dec_digest_tc_fx(st_ivas); + + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator[idx] = fixedToFloat(st_ivas->hIsmRendererData->interpolator_fx[idx], Q15); + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->prev_gains_fx[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->gains_fx[i][j], Q30); + } + } + } + } +#else + ivas_ism_dec_digest_tc(st_ivas); +#endif } } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) @@ -3356,7 +3476,69 @@ void ivas_jbm_dec_feed_tc_to_renderer( if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - ivas_ism_dec_digest_tc( st_ivas ); +#ifdef IVAS_FLOAT_FIXED + Word16 len = (int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC); + Word16 num_objects = st_ivas->nchan_transport; + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator_fx[idx] = floatToFixed(st_ivas->hIsmRendererData->interpolator[idx], Q15); + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->gains[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->prev_gains[i][j], Q30); + } + } + } + } + + ivas_ism_dec_digest_tc_fx( st_ivas ); + + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator[idx] = fixedToFloat(st_ivas->hIsmRendererData->interpolator_fx[idx], Q15); + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->prev_gains_fx[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->gains_fx[i][j], Q30); + } + } + } + } +#else + ivas_ism_dec_digest_tc(st_ivas); +#endif /* delay the objects here for all renderers where it is needed */ if ( @@ -3400,7 +3582,69 @@ void ivas_jbm_dec_feed_tc_to_renderer( if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - ivas_ism_dec_digest_tc( st_ivas ); +#ifdef IVAS_FLOAT_FIXED + Word16 len = (int16_t)(st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC); + Word16 num_objects = st_ivas->nchan_transport; + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator_fx[idx] = floatToFixed(st_ivas->hIsmRendererData->interpolator[idx], Q15); + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->gains[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains_fx[i][j] = floatToFixed(st_ivas->hIsmRendererData->prev_gains[i][j], Q30); + } + } + } + } + + ivas_ism_dec_digest_tc_fx(st_ivas); + + IF(st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->renderer_type == RENDERER_OSBA_STEREO || + (st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0)) + { + if (st_ivas->hIsmRendererData != NULL) { + FOR(int idx = 0; idx < len; idx++) + { + st_ivas->hIsmRendererData->interpolator[idx] = fixedToFloat(st_ivas->hIsmRendererData->interpolator_fx[idx], Q15); + } + for (int i = 0; i < num_objects; i++) + { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->prev_gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->prev_gains_fx[i][j], Q30); + } + } + for (int i = 0; i < num_objects; i++) { + for (int j = 0; j < MAX_OUTPUT_CHANNELS; j++) { + st_ivas->hIsmRendererData->gains[i][j] = fixedToFloat(st_ivas->hIsmRendererData->gains_fx[i][j], Q30); + } + } + } + } +#else + ivas_ism_dec_digest_tc(st_ivas); +#endif } } else if ( st_ivas->ivas_format == MC_FORMAT ) diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 1b83441f936e9cd4a545226b990fc3dcc68c430f..427f11513f35100c69783a7ad553e2208c1ed18b 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -2181,6 +2181,251 @@ void ivas_mdct_core_reconstruct( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_mdct_core_reconstruct_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *x_fx[][NB_DIV], /* i/o: synthesis @internal_FS */ // Q(q_x) + Word16 signal_outFB_fx[CPE_CHANNELS][L_FRAME_PLUS], /* o : synthesis @output_FS */ // e_sig + Word16 fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + Word16 q_x, + Word16 e_sig +) +{ + Word16 ch, k, bfi; + Decoder_State **sts, *st; + /* Framing */ + Word16 L_frame[CPE_CHANNELS], L_frameTCX[CPE_CHANNELS], nSubframes[CPE_CHANNELS]; + Word16 L_frame_global[CPE_CHANNELS], L_frame_globalTCX[CPE_CHANNELS]; + /* Synth */ + Word16 synth_buf_fx[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; + Word16 *synth_fx; + Word16 synth_bufFB_fx[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; + Word16 *synthFB_fx; + Word16 q_syn = 0; + Word16 q_win = -2; + /* TCX */ + Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 tcx_offset[CPE_CHANNELS]; + Word16 tcx_offsetFB[CPE_CHANNELS]; + Word16 left_rect[CPE_CHANNELS]; + Word16 L_spec[CPE_CHANNELS]; + + Word16 pitch[CPE_CHANNELS][NB_SUBFR16k]; + Word16 pit_gain_fx[CPE_CHANNELS][NB_SUBFR16k]; + Word16 skip_decoding; + + set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); + + /* Initializations */ + sts = hCPE->hCoreCoder; + bfi = sts[0]->bfi; + + /* TNS, ITF, IMDCT and updates */ + FOR ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + + skip_decoding = 0; + IF ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + { + skip_decoding = 1; + } + + nSubframes[ch] = ( st->core == TCX_20_CORE ) ? 1 : NB_DIV; + synth_fx = synth_buf_fx + st->hTcxDec->old_synth_len; + synthFB_fx = synth_bufFB_fx + st->hTcxDec->old_synth_lenFB; + + Copy_Scale_sig( st->hTcxDec->old_synth, synth_buf_fx, st->hTcxDec->old_synth_len, sub(q_syn, st->Q_syn) ); + Copy_Scale_sig( st->hTcxDec->old_synthFB_fx, synth_bufFB_fx, st->hTcxDec->old_synth_lenFB, sub(q_syn, st->Q_syn) ); + set16_fx( synth_fx, 0, L_FRAME_PLUS + M ); + set16_fx( synthFB_fx, 0, L_FRAME_PLUS + M ); + IF ( NE_16(st->core, ACELP_CORE) ) + { + Scale_sig(st->hTcxDec->syn_Overl_TDACFB, shr(L_FRAME_MAX, 1), sub(q_win, -1 - st->Q_syn)); + Scale_sig(st->hTcxDec->syn_Overl_TDAC, shr(L_FRAME32k, 1), sub(q_win, -1 - st->Q_syn)); + Scale_sig(st->hTcxDec->old_syn_Overl, shr(L_FRAME32k, 1), sub(q_win, -1 - st->Q_syn)); + Scale_sig(st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub(q_win, st->Q_syn)); + Scale_sig(st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub(q_win, st->Q_syn)); + Scale_sig(st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub(q_win, st->Q_syn)); + Scale_sig(st->hHQ_core->old_out_fx, L_FRAME48k, sub(q_win, st->Q_syn)); + Scale_sig(synth_buf_fx, 3136, sub(-2, q_syn)); + Scale_sig(synth_bufFB_fx, 3136, sub(-2, q_syn)); + FOR( k = 0; k < nSubframes[ch]; k++ ) + { + L_spec[ch] = st->hTcxCfg->tcx_coded_lines / nSubframes[ch]; + L_frame_global[ch] = st->L_frame / nSubframes[ch]; + L_frame_globalTCX[ch] = st->hTcxDec->L_frameTCX / nSubframes[ch]; + + init_tcx_info_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], k, bfi, &tcx_offset[ch], + &tcx_offsetFB[ch], &L_frame[ch], &L_frameTCX[ch], &left_rect[ch], &L_spec[ch] ); + + IF ( !skip_decoding ) + { + decoder_tcx_imdct_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], L_spec[ch], tcx_offset[ch], tcx_offsetFB[ch], L_frame[ch], L_frameTCX[ch], left_rect[ch], x_fx[ch][k], q_x, xn_buf_fx, q_win, + ( ( hCPE->nchan_out == 1 && st->hTcxDec->kernel_type[k] == MDST_IV ) || st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ? MDCT_IV : st->hTcxDec->kernel_type[k], + fUseTns[ch][k], &synth_fx[k * L_frame[ch]], &synthFB_fx[k * L_frameTCX[ch]], bfi, k, 0 ); + + } + ELSE + { + set16_fx( &synth_fx[k * L_frame[ch]], 0, L_frame[ch] ); + set16_fx( &synthFB_fx[k * L_frame[ch]], 0, L_frameTCX[ch] ); + } + } + + IF ( EQ_16(bfi, 0) && st->hTonalMDCTConc != NULL ) + { + TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB_fx, L_frameTCX[ch] ); + } + decoder_tcx_post_ivas_fx( st, synth_fx, synthFB_fx, NULL, bfi, MCT_flag ); + + Scale_sig(st->hTcxDec->syn_Overl_TDACFB, shr(L_FRAME_MAX, 1), sub(-1 - st->Q_syn, q_win)); + Scale_sig(st->hTcxDec->syn_Overl_TDAC, shr(L_FRAME32k, 1), sub(-1 - st->Q_syn, q_win)); + Scale_sig(st->hTcxDec->old_syn_Overl, shr(L_FRAME32k, 1), sub(-1 - st->Q_syn, q_win)); + Scale_sig(synth_buf_fx, 3136, sub(q_syn, -2)); + Scale_sig(synth_bufFB_fx, 3136, sub(q_syn, -2)); + Scale_sig(st->syn, M + 1, st->Q_syn + 1); + Scale_sig(st->hTcxDec->syn_OverlFB, shr(L_FRAME_MAX, 1), sub(st->Q_syn, q_win)); + Scale_sig(st->hTcxDec->syn_Overl, shr(L_FRAME32k, 1), sub(st->Q_syn, q_win)); + Scale_sig(st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub(st->Q_syn, q_win)); + Scale_sig(st->hHQ_core->old_out_fx, L_FRAME48k, sub(st->Q_syn, q_win)); + } + ELSE /*ACELP core for ACELP-PLC */ + { + assert( EQ_16(st->bfi, 1) ); + /* PLC: [TCX: TD PLC] */ + IF ( NE_16(MCT_flag , 0) ) + { + con_tcx( st, &synthFB_fx[0] /*, -1.f, NULL, 0, NULL */ ); + } + ELSE + { + con_tcx_ivas_fx( st, &synthFB_fx[0], hCPE->hStereoMdct->lastCoh_fx, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); + } + + Scale_sig(synthFB_fx, st->hTcxDec->L_frameTCX, q_syn); + IF( ( EQ_16( st->nbLostCmpt, 1 ) ) || NE_16(st->hTcxDec->tcxConceal_recalc_exc, 0) ) + { + Scale_sig(synthFB_fx - (st->hTcxDec->L_frameTCX / 2 + st->hTcxDec->pit_max_TCX + 2 * M), sub(q_syn, st->Q_exc - 1), st->hTcxDec->L_frameTCX / 2 + st->hTcxDec->pit_max_TCX + 2 * M); + } + ELSE + { + Scale_sig(synthFB_fx - st->hTcxDec->L_frameTCX, sub(q_syn, st->Q_exc - 1), st->hTcxDec->L_frameTCX); + + } + + lerp( synthFB_fx, synth_fx, st->L_frame, st->hTcxDec->L_frameTCX ); + st->con_tcx = 1; + set16_fx( &st->mem_pitch_gain[2], st->lp_gainp_fx, st->nb_subfr ); + + /* PLC: [TCX: Tonal Concealment] */ + /* Signal that this frame is not TCX */ + IF ( st->hTonalMDCTConc != NULL ) + { + TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, 0, 0, 0, 0 ); + } + Scale_sig(st->mem_syn2_fx, M, st->Q_syn); + Scale_sig(st->mem_syn_r, M, st->Q_syn); + } + + /*--------------------------------------------------------------------------------* + * Updates + *--------------------------------------------------------------------------------*/ + + st = sts[ch]; + + IF ( NE_16(bfi, 0) && NE_16(st->last_core, ACELP_CORE) && EQ_16(st->core, ACELP_CORE) ) + { + /* Update FEC_scale_syn parameters */ + IF ( EQ_16(st->hTcxLtpDec->tcxltp_gain, 0) ) + { + frame_ener_fx( st->L_frame, UNVOICED, synth_fx, shr(st->L_frame, 1), &st->enr_old_fx, st->L_frame, 0, 0, 0 ); + } + ELSE + { + frame_ener_fx( st->L_frame, st->clas_dec, synth_fx, extract_l( L_shr(st->old_fpitch, 16)), &st->enr_old_fx, st->L_frame, 0, 0, 0 ); + } + } + + /* Update */ + mvs2s( synth_buf_fx + st->L_frame, st->hTcxDec->old_synth, st->hTcxDec->old_synth_len ); + mvs2s( st->hTcxDec->old_synthFB_fx + st->hTcxDec->L_frameTCX - NS2SA( st->output_Fs, PH_ECU_MEM_NS ), st->hTcxDec->synth_history_fx, NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ); + mvs2s( synth_bufFB_fx + st->hTcxDec->L_frameTCX, st->hTcxDec->old_synthFB_fx, st->hTcxDec->old_synth_lenFB ); + Scale_sig(st->hTcxDec->old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub(st->Q_syn, q_syn)); + IF ( st->hHQ_core != NULL ) + { + mvs2s( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + st->hTcxDec->old_synth_lenFB, NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + + mvs2s( st->lsp_q_cng, st->old_lsp_q_cng, M ); + mvs2s( st->lsf_q_cng, st->old_lsf_q_cng, M ); + st->last_is_cng = 0; + + /* Postfiltering */ + Word16 x_fx_16[1200]; + Copy_Scale_sig_32_16(x_fx[ch][0], x_fx_16, 1200, sub(0, q_x)); + + post_decoder_ivas_fx( st, synth_buf_fx, pit_gain_fx[ch], pitch[ch], x_fx_16, st->p_bpf_noise_buf ); + + IF ( signal_outFB_fx[ch] != NULL ) + { + Copy_Scale_sig( synthFB_fx, signal_outFB_fx[ch], st->hTcxDec->L_frameTCX, sub(sub(15, e_sig), q_syn) ); + //Scale_sig(signal_outFB_fx[ch], st->hTcxDec->L_frameTCX, sub(sub(15, e_sig), q_syn)); + } + + /* updates */ + st->last_voice_factor_fx = 0; + st->last_coder_type = st->coder_type; + + Copy_Scale_sig_16_32( x_fx_16, x_fx[ch][0], st->L_frame, sub(q_x, 0) ); + + } + + /* calculate coherence of signal needed when next frame is lost */ + IF ( EQ_16(bfi, 0) && EQ_16(MCT_flag, 0) && EQ_16(hCPE->element_mode, IVAS_CPE_MDCT) ) + { + Word16 i; + Word64 nrgL_fx, nrgR_fx, xcorr_fx; + Word16 e_nrgL, e_nrgR, e_xcorr, tmp, e_tmp; + Word32 L_tmp; + + nrgL_fx = EPSILON_FX; + + nrgR_fx = EPSILON_FX; + xcorr_fx = EPSILON_FX; + move32(); move32(); move32(); + + FOR ( i = 0; i < sts[0]->hTcxDec->L_frameTCX; i++ ) + { + nrgL_fx = W_add(nrgL_fx, L_mult0(signal_outFB_fx[0][i], signal_outFB_fx[0][i])); + nrgR_fx = W_add(nrgR_fx, L_mult0(signal_outFB_fx[1][i], signal_outFB_fx[1][i])); + xcorr_fx = W_add(xcorr_fx, L_mult0(signal_outFB_fx[0][i], signal_outFB_fx[1][i])); + } + e_nrgL = add(33, shl(e_sig, 1)); + e_nrgR = e_nrgL; + move16(); + e_xcorr = e_nrgL; + move16(); + tmp = W_norm(nrgL_fx); + nrgL_fx = W_shl(nrgL_fx, tmp); + e_nrgL = sub(e_nrgL, tmp); + tmp = W_norm(nrgR_fx); + nrgR_fx = W_shl(nrgR_fx, tmp); + e_nrgR = sub(e_nrgR, tmp); + tmp = W_norm(xcorr_fx); + xcorr_fx = W_shl(xcorr_fx, tmp); + e_xcorr = sub(e_xcorr, tmp); + L_tmp = Mpy_32_32(W_extract_h(nrgL_fx), W_extract_h(nrgR_fx)); + e_tmp = add(e_nrgL, e_nrgR); + L_tmp = ISqrt32(L_tmp, &e_tmp); + hCPE->hStereoMdct->lastCoh_fx = extract_l(L_shr(Mpy_32_32(L_abs(W_extract_h(xcorr_fx)), L_tmp), sub(17, add(e_xcorr, e_tmp)))); + hCPE->hStereoMdct->lastCoh_fx = s_min( hCPE->hStereoMdct->lastCoh_fx, 16384 ); + } + + return; +} +#endif /*-----------------------------------------------------------------* * ivas_mdct_core_tns_ns() diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index f48a262c352a72911069d0ea6d7c2b06e0f9562a..f52e7a9d9c9b9c7699a53f0eb17e2dafb11e94dc 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -538,9 +538,9 @@ ivas_error ivas_td_binaural_renderer_sf_fx( /* Update the listener's location/orientation */ #ifdef FIXED_CODE_WIP - IVAS_QUATERNION_FX *tmp_Quaternion_fx; + IVAS_QUATERNION *tmp_Quaternion_fx; IVAS_QUATERNION *tmp_Quaternion; - IVAS_VECTOR3_FX *tmp_vector_fx; + IVAS_VECTOR3 *tmp_vector_fx; IVAS_VECTOR3 *tmp_vector; Word16 enableCombinedOrientation = 0; /////////////////////////////////////////// Float to fixed starts here /////////////////////////////////////////// diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ca22eedf27c49ba2d21faa0645aa1b5a560f16f5..b6713fb084c8e62e1285bc9da942a06d5e27cae9 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -457,6 +457,9 @@ typedef struct stereo_mdct_dec_data_structure #endif int16_t prev_ms_mask[NB_DIV][MAX_SFB]; +#ifdef IVAS_FLOAT_FIXED + Word16 lastCoh_fx; +#endif float lastCoh; int16_t noise_seeds_channels[CPE_CHANNELS]; int16_t noise_seed_common; @@ -643,6 +646,7 @@ typedef struct ivas_param_ism_dec_data_structure #ifdef IVAS_FLOAT_FIXED Word32 azimuth_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; Word32 elevation_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS]; + Word16 power_ratios_fx[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE]; #endif // IVAS_FLOAT_FIXED float power_ratios[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE]; diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 05ab00c23049174f45fe52dc93806187e26e7a2f..d24d6db9e71939cfb7442343c3fb99b377246a2d 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -784,8 +784,268 @@ void stereo_mdct_core_dec_fx( apply_dmx_weights( hCPE, x, sts[0]->transform_type, sts[1]->transform_type ); #endif } +#ifdef IVAS_FLOAT_FIXED + // + + Word16 signal_outFB_tmp_fx[2][1200]; + Word16 e_sig = 17; + + Word16 e_lsp = 0; + Word16 e_lsf = 0;; + Word32 *x_fx_[2][2]; + Word16 q_x = Q11; + Word16 x_e_; + FOR(i = 0; i < 2; i++) { + FOR(j = 0; j < 2; j++) { + x_fx_[i][j] = malloc(1200 * sizeof(Word32)); + } + } + Word16 L_frame_global[CPE_CHANNELS], L_frame_globalTCX[CPE_CHANNELS]; + x_e_ = 31 - q_x; + IF(signal_outFB_tmp[0]) floatToFixed_arr(signal_outFB_tmp[0], signal_outFB_tmp_fx[0], 15-e_sig, 960); + IF(signal_outFB_tmp[1]) floatToFixed_arr(signal_outFB_tmp[1], signal_outFB_tmp_fx[1], 15-e_sig, 960); + FOR( ch = 0; ch < 2; ch++) { + st = hCPE->hCoreCoder[ch]; + L_spec[0] = st->hTcxCfg->tcx_coded_lines / nSubframes[0]; + L_frame_global[0] = st->L_frame / nSubframes[0]; + L_frame_globalTCX[0] = st->hTcxDec->L_frameTCX / nSubframes[0]; + + FOR( i = 0; i < 1200; i++) { + x_fx_[ch][0][i] = (Word32)(x[ch][0][i] * (1 << q_x)); + } + FOR( i = 0; i < 600; i++) { + x_fx_[ch][1][i] = (Word32)(x[ch][1][i] * (1 << q_x)); + } + st->hIGFDec->virtualSpec_e = x_e_; + IF ( NE_16(st->igf, 0) && st->hIGFDec && st->hIGFDec->virtualSpec_fx ) + FOR( i = 0; i < s_min(st->hIGFDec->infoIGFStopLine - st->hIGFDec->infoIGFStartLine, 856); i++) { + st->hIGFDec->virtualSpec_fx[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] = (Word32)(st->hIGFDec->virtualSpec_float[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] * (1 << (31 - st->hIGFDec->virtualSpec_e))); + } + IF(st->hTcxDec)st->hTcxDec->tcxltp_last_gain_unmodified = float_to_fix16( st->hTcxDec->tcxltp_last_gain_unmodified_float, Q15 ); + + IF(st->hTcxDec) st->hTcxDec->conceal_eof_gain = (Word16)(st->hTcxDec->conceal_eof_gain_float * 16384.f); + st->last_concealed_gain_syn_deemph = (Word16)(st->last_concealed_gain_syn_deemph_float * 32767.f); + + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->syn_Overl_float, st->hTcxDec->syn_Overl, st->Q_syn, L_FRAME32k / 2); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->syn_OverlFB_float, st->hTcxDec->syn_OverlFB, st->Q_syn, L_FRAME_MAX / 2); + IF(st->hTcxDec) st->hTcxDec->gainHelper = float_to_fix16( st->hTcxDec->gainHelper_float, Q14 ); + IF(st->hTcxDec) st->hTcxDec->gainHelper_e = 1; + IF(st->hTcxDec) st->hTcxDec->stepCompensate = float_to_fix16( st->hTcxDec->stepCompensate_float, Q14 ); + IF(st->hTcxDec) st->hTcxDec->stepCompensate_e = 1; + st->preemph_fac = float_to_fix16( st->preemph_fac_float, Q15 ); + IF(st->hTcxDec) st->hTcxDec->damping = float_to_fix16( st->hTcxDec->damping_float, Q14 ); + st->bfi_pitch_fx = float_to_fix16( st->bfi_pitch, Q5 ); + st->old_fpitch = float_to_fix( st->old_fpitch_float, Q16 ); + + st->prev_Q_syn = st->Q_syn; + st->old_fpitchFB = (Word32) ( st->old_fpitchFB_float * ONE_IN_Q16 ); + st->stab_fac_fx = (Word16) ( st->stab_fac * MAX_16 ); + IF(hCPE->hStereoMdct) hCPE->hStereoMdct->lastCoh_fx = (Word16)(hCPE->hStereoMdct->lastCoh * (1<<14)); + st->lp_gainp_fx = float_to_fix16(st->lp_gainp, 14); + IF(st->hTonalMDCTConc) st->hTonalMDCTConc->lastPitchLag = float_to_fix(st->hTonalMDCTConc->lastPitchLag_float, Q16); + + st->enr_old_fx = (Word32)st->enr_old; + + IF(st->hHQ_core) floatToFixed_arr(st->hHQ_core->old_outLB, st->hHQ_core->old_out_LB_fx, st->Q_syn, L_FRAME32k); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->syn_Overl_TDACFB_float, st->hTcxDec->syn_Overl_TDACFB, -1 - st->Q_syn, L_FRAME_MAX / 2); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->syn_Overl_TDAC_float, st->hTcxDec->syn_Overl_TDAC, -1 - st->Q_syn, L_FRAME32k / 2); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->old_syn_Overl_float, st->hTcxDec->old_syn_Overl, -1 - st->Q_syn, L_FRAME32k / 2); + floatToFixed_arr( st->mem_syn2, st->mem_syn2_fx, st->Q_syn, M ); + floatToFixed_arr( st->mem_syn_r_float, st->mem_syn_r, st->Q_syn, L_SYN_MEM ); + floatToFixed_arr( st->syn_float, st->syn, -1, M + 1 ); + floatToFixed_arr( st->old_exc, st->old_exc_fx, st->Q_exc, L_EXC_MEM_DEC ); + + IF(st->hTcxDec) st->hTcxDec->tcxltp_third_last_pitch = float_to_fix(st->hTcxDec->tcxltp_third_last_pitch_float, 16); + IF(st->hTcxDec) st->hTcxDec->tcxltp_second_last_pitch = float_to_fix(st->hTcxDec->tcxltp_second_last_pitch_float, 16); + IF(st->hTcxDec) st->hTcxLtpDec->tcxltp_gain = (Word16)floatToFixed(st->hTcxLtpDec->tcxltp_gain_float, Q15); + + IF(st->hPFstat) floatToFixed_arr( st->hPFstat->mem_pf_in_flt, st->hPFstat->mem_pf_in, 0, L_SUBFR ); + IF(st->hPFstat) floatToFixed_arr( st->hPFstat->mem_stp_flt, st->hPFstat->mem_stp, 0, L_SUBFR ); + IF(st->hBPF) st->lp_error_ener= floatToFixed( st->hBPF->pst_lp_ener, Q16 ); + IF(st->hBPF) st->mem_error = floatToFixed( st->hBPF->pst_mem_deemp_err, Q16 ); + IF(st->hPFstat) st->hPFstat->gain_prec = (Word16)floatToFixed( st->hPFstat->gain_prec_flt, Q14 ); + st->last_voice_factor_fx = (Word16)floatToFixed(st->last_voice_factor, 6); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->old_excFB, st->hTcxDec->old_excFB_fx, st->Q_exc, st->L_frame); + + st->Mode2_lp_gainc = (Word32) (st->lp_gainc * ONE_IN_Q16); + st->Mode2_lp_gainp= (Word32) (st->lp_gainp * ONE_IN_Q29); + st->cummulative_damping = (Word16) (st->cummulative_damping_float * MAX_16); + st->old_enr_LP = (Word16) (st->old_enr_LP_float * ONE_IN_Q3); + + if ( !st->tcxonly ) + { + floatToFixed_arr( st->p_bpf_noise_buf_float, st->p_bpf_noise_buf, 0, L_FRAME_16k ); + } + IF(st->hBPF) floatToFixed_arr( st->hBPF->pst_old_syn, st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); + + f2me_buf_16(st->lsp_q_cng_float, st->lsp_q_cng, &e_lsp, 16); + f2me_buf_16(st->lsf_q_cng_float, st->lsf_q_cng, &e_lsf, 16); + floatToFixed_arr(st->old_lsp_q_cng_float, st->old_lsp_q_cng, 15-e_lsp, 16); + floatToFixed_arr(st->old_lsf_q_cng_float, st->old_lsf_q_cng, 15-e_lsf, 16); + + floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); + floatToFixed_arr( st->mem_Aq_float, st->mem_Aq, Q12, ( NB_SUBFR16k ) * ( M + 1 ) ); + IF(st->hPFstat) floatToFixed_arr( st->hPFstat->mem_pf_in_flt, st->hPFstat->mem_pf_in, 0, L_SUBFR ); + IF(st->hPFstat) floatToFixed_arr( st->hPFstat->mem_stp_flt, st->hPFstat->mem_stp, 0, L_SUBFR ); + st->lp_noise = floatToFixed( st->lp_noise_float, Q16 ); + IF(st->hBPF) st->lp_error_ener = floatToFixed( st->hBPF->pst_lp_ener, Q16 ); + IF(st->hBPF) st->mem_error = floatToFixed( st->hBPF->pst_mem_deemp_err, Q16 ); + IF(st->hPFstat) st->hPFstat->gain_prec = (Word16) floatToFixed( st->hPFstat->gain_prec_flt, Q14 ); + + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->old_synth_float, st->hTcxDec->old_synth, st->Q_syn, 1280); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->old_synthFB, st->hTcxDec->old_synthFB_fx, st->Q_syn, s_max(st->hTcxDec->L_frameTCX, st->hTcxDec->old_synth_lenFB + NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ))); + IF(st->hTcxDec) floatToFixed_arr(st->hTcxDec->synth_history, st->hTcxDec->synth_history_fx, st->Q_syn, NS2SA( st->output_Fs, PH_ECU_MEM_NS )); + + float maxim = 0; + IF(st->hFdCngDec && st->hFdCngDec->hFdCngCom) { + FOR(Word16 ind = 0; ind < 340; ind++) + { + maxim = fmaxf(maxim, fabsf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind])); + } + st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; + IF(L_abs((Word32)maxim)!=0) st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 31 - norm_l((Word32)maxim); + FOR(Word16 ind = 0; ind < 340; ind++) + { + st->hFdCngDec->hFdCngCom->cngNoiseLevel[ind] = (Word32)(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind] * (1LL<<(31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp))); + } + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = float_to_fix16(st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt, 15); + } + IF(st->hHQ_core) floatToFixed_arr(st->hHQ_core->old_out, st->hHQ_core->old_out_fx, st->Q_syn, 960); + IF(st->hTonalMDCTConc) floatToFixed_arr(st->hTonalMDCTConc->lastPcmOut_float, st->hTonalMDCTConc->lastPcmOut, -2, st->hTonalMDCTConc->nSamples); + IF(st->hTonalMDCTConc) floatToFixed_arr(st->hTonalMDCTConc->secondLastPcmOut_float, st->hTonalMDCTConc->secondLastPcmOut, -2, st->hTonalMDCTConc->nSamples / 2); + if ( st->hPlcInfo ) + { + st->hPlcInfo->step_concealgain_fx = float_to_fix16( st->hPlcInfo->step_concealgain, Q15 ); + st->hPlcInfo->recovery_gain_float = float_to_fix16( st->hPlcInfo->recovery_gain, Q14 ); + } + IF(st->hTcxDec) + st->hTcxDec->conceal_eof_gain = float_to_fix16( st->hTcxDec->conceal_eof_gain_float, Q14 ); + if ( st->hTcxDec && st->hTcxDec->conCngLevelBackgroundTrace_e < 0 ) + { + st->hTcxDec->conCngLevelBackgroundTrace_e = 0; + } + IF(st->hTcxDec) f2me_16(st->hTcxDec->CngLevelBackgroundTrace_bfi, &st->hTcxDec->conCngLevelBackgroundTrace, &st->hTcxDec->conCngLevelBackgroundTrace_e); + if ( st->hTcxDec && st->hTcxDec->conLastFrameLevel_e < 0 ) + { + st->hTcxDec->conLastFrameLevel_e = 0; + } + IF(st->hTcxDec) st->hTcxDec->conLastFrameLevel = (Word16) floatToFixed( st->hTcxDec->LastFrameLevel_bfi, 15 - st->hTcxDec->conLastFrameLevel_e ); + if ( st->hTcxDec && st->hTcxDec->conNoiseLevelMemory_e[0] < 0 ) + { + set16_fx( st->hTcxDec->conNoiseLevelMemory_e, 0, PLC_MIN_STAT_BUFF_SIZE ); + } + IF(st->hTcxDec) floatToFixed_arr( st->hTcxDec->NoiseLevelMemory_bfi, st->hTcxDec->conNoiseLevelMemory, Q15, PLC_MIN_STAT_BUFF_SIZE ); + IF(st->hTcxDec) st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; + IF(st->hTcxDec) st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; + floatToFixed_arr( st->mem_pitch_gain_float, st->mem_pitch_gain, Q14, 2 * NB_SUBFR16k + 2 ); + floatToFixed_arrL( st->old_pitch_buf, st->old_pitch_buf_fx, Q16, 2 * NB_SUBFR16k + 2 ); + IF(st->hTcxDec) for ( int p = 0; p < st->L_frame; p++ ) + { + st->hTcxDec->old_excFB_fx[p] = (Word16) ( st->hTcxDec->old_excFB[p] * ( 1u << st->Q_exc ) ); + } + IF(st->hFdCngDec && st->hFdCngDec->hFdCngCom) floatToFixed_arr(st->hFdCngDec->hFdCngCom->A_cng_flt, st->hFdCngDec->hFdCngCom->A_cng, 15, 17); + } + FOR( Word16 ind = 0; ind < M + 1; ind++ ) + { + hCPE->hCoreCoder[0]->old_Aq_12_8_fx[ind] = (Word16) ( hCPE->hCoreCoder[0]->old_Aq_12_8[ind] * 4096.f ); + hCPE->hCoreCoder[1]->old_Aq_12_8_fx[ind] = (Word16) ( hCPE->hCoreCoder[1]->old_Aq_12_8[ind] * 4096.f ); + hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32[ind] = (Word32)(hCPE->hCoreCoder[0]->old_Aq_12_8[ind] * (1<<28)); + hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32[ind] = (Word32)(hCPE->hCoreCoder[1]->old_Aq_12_8[ind] * (1<<28)); + } + // + ivas_mdct_core_reconstruct_fx( hCPE, x_fx_, signal_outFB_tmp_fx, fUseTns, 0, q_x, e_sig ); + // + IF(hCPE->hStereoMdct) hCPE->hStereoMdct->lastCoh = fix16_to_float(hCPE->hStereoMdct->lastCoh_fx, 14); + IF(signal_outFB_tmp[0]) fixedToFloat_arr(signal_outFB_tmp_fx[0], signal_outFB_tmp[0], 15 - e_sig, 960); + IF(signal_outFB_tmp[1]) fixedToFloat_arr(signal_outFB_tmp_fx[1], signal_outFB_tmp[1], 15 - e_sig, 960); + FOR( ch = 0; ch < 2; ch++) { + st = hCPE->hCoreCoder[ch]; + IF(st->igf) me2f_buf(x_fx_[ch][0], 31 - q_x, x[ch][0], s_min(1200, s_max(st->hIGFDec->infoIGFStopLine, s_max(L_frameTCX[ch], L_spec[ch]) ))); + IF(st->igf && nSubframes[ch] > 1) me2f_buf(x_fx_[ch][1], 31 - q_x, x[ch][1], s_min(s_max(st->hIGFDec->infoIGFStopLine, s_max(L_frameTCX[ch], L_spec[ch])), 600) ); + fixedToFloat_arr(st->hTcxDec->syn_OverlFB, st->hTcxDec->syn_OverlFB_float, st->Q_syn, L_FRAME_MAX / 2); + fixedToFloat_arr(st->hTcxDec->syn_Overl, st->hTcxDec->syn_Overl_float, st->Q_syn, L_FRAME32k / 2); + fixedToFloat_arr( st->mem_syn2_fx, st->mem_syn2, st->Q_syn, M ); + fixedToFloat_arr( st->mem_syn_r, st->mem_syn_r_float, st->Q_syn, L_SYN_MEM ); + fixedToFloat_arr( st->syn, st->syn_float, st->Q_syn, M + 1 ); + fixedToFloat_arr( st->old_exc_fx, st->old_exc, st->Q_exc, L_EXC_MEM_DEC ); + st->hTonalMDCTConc->lastPitchLag_float = fix_to_float(st->hTonalMDCTConc->lastPitchLag, Q16); + st->hTcxDec->tcxltp_third_last_pitch_float = fix_to_float(st->hTcxDec->tcxltp_third_last_pitch, 16); + st->hTcxDec->tcxltp_second_last_pitch_float = fix_to_float(st->hTcxDec->tcxltp_second_last_pitch, 16); + st->old_fpitch_float = fix_to_float(st->old_fpitch, 16); + st->bfi_pitch = fix16_to_float( st->bfi_pitch_fx, Q6 ); + st->old_fpitchFB_float = fix_to_float(st->old_fpitchFB, 16); + st->hTcxDec->tcxltp_last_gain_unmodified_float = fix16_to_float( st->hTcxDec->tcxltp_last_gain_unmodified, Q15 ); + st->hTcxLtpDec->tcxltp_gain_float = fix16_to_float( st->hTcxLtpDec->tcxltp_gain, Q15 ); + st->hTcxDec->conceal_eof_gain_float = fix16_to_float( st->hTcxDec->conceal_eof_gain, Q14 ); + FOR(Word16 ind = 0; ind < 17; ind++) { + st->old_Aq_12_8[ind] = (float)(st->old_Aq_12_8_fx[ind]) / (float)(1<<12); + } + IF(st->hPFstat) fixedToFloat_arr( st->hPFstat->mem_pf_in, st->hPFstat->mem_pf_in_flt, 0, L_SUBFR ); + IF(st->hPFstat) fixedToFloat_arr( st->hPFstat->mem_stp, st->hPFstat->mem_stp_flt, 0, L_SUBFR ); + IF(st->hBPF) st->hBPF->pst_lp_ener = fixedToFloat( st->lp_error_ener, Q16 ); + IF(st->hBPF) st->hBPF->pst_mem_deemp_err = fixedToFloat( st->mem_error, Q16 ); + IF(st->hPFstat) st->hPFstat->gain_prec_flt = fixedToFloat( st->hPFstat->gain_prec, Q14 ); + st->last_voice_factor = fix16_to_float(st->last_voice_factor_fx, 6); + for ( int p = 0; p < st->L_frame; p++ ) + { + st->hTcxDec->old_excFB[p] = (float) ( st->hTcxDec->old_excFB_fx[p] ) / ( 1u << st->Q_exc ); + } + st->preemph_fac_float = (float) st->preemph_fac / MAX_16; + st->lp_gainc = (float) st->Mode2_lp_gainc / ONE_IN_Q16; + st->lp_gainp = (float) st->Mode2_lp_gainp / ONE_IN_Q29; + st->cummulative_damping_float = (float) st->cummulative_damping / MAX_16; + st->old_enr_LP_float = (float) st->old_enr_LP / ONE_IN_Q3; + for ( int p = 0; p < st->L_frame / 2; p++ ) + { + st->hTcxDec->old_syn_Overl_float[p] = (float) st->hTcxDec->old_syn_Overl[p] * 2 * ( 1u << st->Q_syn ); + st->hTcxDec->syn_Overl_TDACFB_float[p] = (float) st->hTcxDec->syn_Overl_TDACFB[p] * 2 * pow( 2, st->Q_syn ); + st->hTcxDec->syn_Overl_TDAC_float[p] = (float) st->hTcxDec->syn_Overl_TDAC[p] * 2 * pow( 2, st->Q_syn ); + } + for ( int p = 0; p < 640; p++ ) + { + st->hHQ_core->old_outLB[p] = (float) st->hHQ_core->old_out_LB_fx[p] / ( 1u << st->Q_syn ); + } + + if ( !st->tcxonly ) + { + fixedToFloat_arr( st->p_bpf_noise_buf, st->p_bpf_noise_buf_float, 0, L_FRAME_16k ); + } + IF(st->hBPF && st->hBPF->pst_old_syn) fixedToFloat_arr( st->hBPF->pst_old_syn_fx, st->hBPF->pst_old_syn, 0, NBPSF_PIT_MAX ); + st->enr_old = (float)st->enr_old_fx; + me2f_buf_16(st->old_lsp_q_cng, e_lsp, st->old_lsp_q_cng_float, 16); + me2f_buf_16(st->old_lsf_q_cng, e_lsf, st->old_lsf_q_cng_float, 16); + + fixedToFloat_arr(st->hTcxDec->old_synth, st->hTcxDec->old_synth_float, st->Q_syn, 1280); + fixedToFloat_arr(st->hTcxDec->synth_history_fx, st->hTcxDec->synth_history, st->Q_syn, NS2SA( st->output_Fs, PH_ECU_MEM_NS )); + fixedToFloat_arr(st->hTcxDec->old_synthFB_fx, st->hTcxDec->old_synthFB, st->Q_syn, st->hTcxDec->old_synth_lenFB + NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS )); + + for ( int p = 0; p < 960; p++ ) + { + st->hHQ_core->old_out[p] = (float) st->hHQ_core->old_out_fx[p] / ( 1u << st->Q_syn ); + } + + if ( st->hPlcInfo ) + { + st->hPlcInfo->recovery_gain_float = fix16_to_float( st->hPlcInfo->recovery_gain, Q14 ); + st->hPlcInfo->step_concealgain = fix16_to_float( st->hPlcInfo->step_concealgain_fx, Q15 ); + } + fixedToFloat_arr( st->mem_pitch_gain, st->mem_pitch_gain_float, Q14, 2 * NB_SUBFR16k + 2 ); + fixedToFloat_arrL( st->old_pitch_buf_fx, st->old_pitch_buf, Q16, 2 * NB_SUBFR16k + 2 ); + IF(st->hTcxDec) st->hTcxDec->CngLevelBackgroundTrace_bfi = me2f_16(st->hTcxDec->conCngLevelBackgroundTrace, st->hTcxDec->conCngLevelBackgroundTrace_e); + //st->hTcxDec->CngLevelBackgroundTrace_bfi = fix16_to_float( st->hTcxDec->conCngLevelBackgroundTrace, 15 - st->hTcxDec->conCngLevelBackgroundTrace_e ); + st->hTcxDec->LastFrameLevel_bfi = me2f_16( st->hTcxDec->conLastFrameLevel, st->hTcxDec->conLastFrameLevel_e ); + for ( int p = 0; p < PLC_MIN_STAT_BUFF_SIZE; p++ ) + { + st->hTcxDec->NoiseLevelMemory_bfi[p] = me2f_16( st->hTcxDec->conNoiseLevelMemory[p], 0 ); + } + IF(st->hTonalMDCTConc && st->hTonalMDCTConc->lastPcmOut_float) fixedToFloat_arr(st->hTonalMDCTConc->lastPcmOut, st->hTonalMDCTConc->lastPcmOut_float, -2, st->hTonalMDCTConc->nSamples); + IF( bfi == 0 && !st->hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive ) fixedToFloat_arr(st->hTonalMDCTConc->secondLastPcmOut, st->hTonalMDCTConc->secondLastPcmOut_float, -2, st->hTonalMDCTConc->nSamples / 2); + } + // +#else ivas_mdct_core_reconstruct( hCPE, x, signal_outFB_tmp, fUseTns, 0 ); +#endif mvr2r( signal_out_tmp[0], signal_out[0], L_FRAME48k ); mvr2r( signal_out_tmp[1], signal_out[1], L_FRAME48k ); diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index 8a626e2eddb047d03ff735d89b5de99ba30586d5..961cb27441ae61ca7207cfceae369e16d9db24e5 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -1519,8 +1519,7 @@ ivas_error IVAS_DEC_FeedRefVectorData( hIvasDec->updateOrientation = true; #ifdef IVAS_FLOAT_FIXED - ivas_orient_trk_state_t_fx *pOTR_fx = malloc(sizeof(ivas_orient_trk_state_t_fx)); - IVAS_VECTOR3_FX listenerPos_fx, refPos_fx; + IVAS_VECTOR3 listenerPos_fx, refPos_fx; listenerPos_fx.x_qfact = listenerPos_fx.y_qfact = listenerPos_fx.z_qfact = Q27; refPos_fx.x_qfact = refPos_fx.y_qfact = refPos_fx.z_qfact = Q27; listenerPos_fx.x_fx = float_to_fix( listenerPos.x, listenerPos_fx.x_qfact ); @@ -1529,13 +1528,11 @@ ivas_error IVAS_DEC_FeedRefVectorData( refPos_fx.x_fx = float_to_fix( refPos.x, refPos_fx.x_qfact ); refPos_fx.y_fx = float_to_fix( refPos.y, refPos_fx.y_qfact ); refPos_fx.z_fx = float_to_fix( refPos.z, refPos_fx.z_qfact ); - pOTR_fx->orientation_tracking_fx = pOtr->orientation_tracking; - ivas_error error_fx = ivas_orient_trk_SetReferenceVector_fx( pOTR_fx, listenerPos_fx, refPos_fx ); - pOtr->refRot.w = me2f( pOTR_fx->refRot_fx.w_fx, 31- pOTR_fx->refRot_fx.w_qfact ); - pOtr->refRot.x = me2f( pOTR_fx->refRot_fx.x_fx, 31 -pOTR_fx->refRot_fx.x_qfact ); - pOtr->refRot.y = me2f( pOTR_fx->refRot_fx.y_fx, 31- pOTR_fx->refRot_fx.y_qfact ); - pOtr->refRot.z = me2f( pOTR_fx->refRot_fx.z_fx, 31 -pOTR_fx->refRot_fx.z_qfact ); - free(pOTR_fx); + ivas_error error_fx = ivas_orient_trk_SetReferenceVector_fx(pOtr, listenerPos_fx, refPos_fx ); + pOtr->refRot.w = me2f(pOtr->refRot.w_fx, 31- pOtr->refRot.w_qfact ); + pOtr->refRot.x = me2f(pOtr->refRot.x_fx, 31 - pOtr->refRot.x_qfact ); + pOtr->refRot.y = me2f(pOtr->refRot.y_fx, 31- pOtr->refRot.y_qfact ); + pOtr->refRot.z = me2f(pOtr->refRot.z_fx, 31 - pOtr->refRot.z_qfact ); return error_fx; #else return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); @@ -1574,7 +1571,7 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( } #ifdef IVAS_FLOAT_FIXED - IVAS_QUATERNION_FX orientation_fx = { 0 }; + IVAS_QUATERNION orientation_fx = { 0 }; orientation_fx.w_qfact = orientation_fx.x_qfact = orientation_fx.y_qfact = orientation_fx.z_qfact = Q29; orientation_fx.w_fx = float_to_fix(orientation.w, orientation_fx.w_qfact); orientation_fx.x_fx = float_to_fix(orientation.x, orientation_fx.x_qfact); diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c index 03ea35e08020d0cc88568baf9a8d7f289eff9788..92b3ce1a4b4e72593932c45fbb26a98e0c46987a 100644 --- a/lib_dec/post_dec_fx.c +++ b/lib_dec/post_dec_fx.c @@ -181,6 +181,171 @@ void post_decoder( return; } +#ifdef IVAS_FLOAT_FIXED +void post_decoder_ivas_fx( + Decoder_State *st, + Word16 synth_buf[], + Word16 pit_gain[], + Word16 pitch[], + Word16 signal_out[], + Word16 *bpf_noise_buf +) +{ + Word16 L_frame, nb_subfr; + Word16 *synth, *synth2; + Word16 pfstat_on_previous; + Word16 pitch_gain_adjust[NB_SUBFR16k]; + Word16 tmp, tmp_noise; + Word16 synth2_pe[L_FRAME_MAX]; + Word16 synth_buf2[PIT_MAX_16k+1+L_FRAME_MAX+M]; + Word32 bitrate; + Word8 tmp8; + BPF_DEC_HANDLE hBPF; + Word16 coder_type = st->coder_type; + + move16(); + hBPF = st->hBPF; + L_frame = st->L_frame; + move16(); + nb_subfr = st->nb_subfr; + move16(); + pfstat_on_previous = 0; + move16(); + + IF(st->hPFstat != NULL) + { + pfstat_on_previous = st->hPFstat->on; + move16(); + st->hPFstat->on = 0; + move16(); + } + + bitrate = L_add(st->total_brate, 0); + IF(LE_32(st->core_brate, SID_2k40)) + { + bitrate = L_add(st->last_active_brate, 0); + } + + + /*Adapt Bpf: copy old and current adapt bpf parameters*/ + set16_fx(pitch_gain_adjust, st->bpf_gain_param, nb_subfr); + + synth = synth_buf + st->hTcxDec->old_synth_len; + synth2 = synth_buf2 + NBPSF_PIT_MAX; + + IF(st->hBPF != NULL) + { + Copy(hBPF->pst_old_syn_fx, synth_buf2, NBPSF_PIT_MAX); + } + + IF ( st->tcxonly != 0 ) + { + Copy( synth, synth2, L_frame ); + IF ( pfstat_on_previous ) + { + Copy( st->hPFstat->mem_pf_in+L_SYN_MEM-M, synth-M, M ); + Word16 L_subfr = st->L_frame / st->nb_subfr; + Residu3_fx ( st->old_Aq_12_8_fx, synth, synth_buf, L_subfr, 1 ); + E_UTIL_synthesis ( 1, st->old_Aq_12_8_fx, synth_buf, synth2, L_subfr, st->hPFstat->mem_stp+L_SYN_MEM-M, 0, M ); + scale_st ( synth, synth2, &st->hPFstat->gain_prec, L_subfr ); + blend_subfr2(synth2+L_subfr/2, synth+L_subfr/2, synth2+L_subfr/2); + } + } + ELSE + { + /*Formant enhancement*/ + IF ( EQ_16(st->last_bwidth,NB)) + { + Copy( synth, synth2_pe, L_frame ); + tmp = synth[-1]; + move16(); + + preemph_copy_fx( synth2_pe, synth2_pe, st->preemph_fac, L_frame, &tmp); + + tmp = 0; + move16(); + test(); + test(); + if ((GT_32(st->lp_noise, LP_NOISE_THRESH))|| + (st->core != ACELP_CORE) || + (EQ_16(coder_type, UNVOICED))) + { + tmp = 1; + move16(); + } + + IF(EQ_16(pfstat_on_previous, 0)) + { + st->hPFstat->reset = 1; + move16(); + } + IF ( EQ_16(st->bwidth,NB)) + { + st->hPFstat->on = 1; + move16(); + tmp_noise = 0; + nb_post_filt( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, GENERIC, st->BER_detect, tmp ); + } + ELSE + { + st->hPFstat->on = 0; + move16(); + tmp_noise = 0; + nb_post_filt( L_frame, st->hPFstat, &tmp_noise, 0, synth2_pe, st->mem_Aq, pitch, AUDIO, st->BER_detect, tmp ); + } + Copy(synth2_pe, synth2, L_frame); + + tmp = synth2[-1]; + move16(); + deemph_fx( synth2, st->preemph_fac, L_frame, &tmp ); + } + ELSE + { + IF(EQ_16(pfstat_on_previous, 0)) + { + st->hPFstat->reset = 1; + move16(); + } + IF ( GE_16(st->last_bwidth,WB)) + { + st->hPFstat->on = 1; + move16(); + formant_post_filt( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 0 ); + } + ELSE + { + st->hPFstat->on = 0; + move16(); + formant_post_filt( st->hPFstat, synth, st->mem_Aq, synth2, L_frame, st->lp_noise, bitrate, 1 ); + } + } + + /*Bass Post-filter */ + tmp8 = 0; + move16(); + test(); + if( GT_32(st->lp_noise,LP_NOISE_THRESH)&&st->narrowBand) + { + tmp8 = 1; + move16(); + } + bass_pf_1sf_delay( synth2, pitch, pit_gain, L_frame, L_SUBFR, bpf_noise_buf, pitch_gain_adjust, + tmp8, &(st->lp_error_ener), &(st->mem_error) ); + } + + /* Output */ + Copy( synth2, signal_out, L_frame ); + + /* Update synth2 memory */ + IF(st->hBPF != NULL) + { + Copy(synth_buf2 + L_frame, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX); + } + + + return; +} +#endif /*---------------------------------------------------------------------* * bass_pf_1sf_delay() diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index b4f4d6b246044551ed41cc713e2aa5d7c23bae61..304bf623565267a14c8e7945995747df3836cc1f 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -603,7 +603,7 @@ typedef struct tcx_dec_structure float synth_history[L_PROT48k + L_FRAME_MAX]; /* unified synthesis memory */ Word16 synth_history_fx[L_PROT48k + L_FRAME_MAX]; /*TCX unified synthesis memory */ - + Word16 q_synth_history_fx; float *old_synthFB; Word16* old_synthFB_fx; @@ -2348,6 +2348,7 @@ typedef struct Decoder_State #ifdef IVAS_FLOAT_FIXED Word16 prev_synth_buffer_fx[NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS)];/*Updated IVAS size is 96*/ + Word16 q_prev_synth_buffer_fx; #else Word16 prev_synth_buffer_fx[NS2SA(48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)]; /*Old EVS size is 51*/ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index df2709b45924de1922dac02eedfed35ee1a8d43d..e6a656414429a27df59fbc1682d2993497b3c906 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -2261,18 +2261,18 @@ static ivas_error ivas_shoebox_config_init_params( hShoeboxConfig->room_L_fx = 0; hShoeboxConfig->room_W_fx = 0; hShoeboxConfig->room_H_fx = 0; - move16(); - move16(); - move16(); + move32(); + move32(); + move32(); FOR ( i = 0; i < IVAS_ROOM_ABS_COEFF; i++ ) { hShoeboxConfig->abs_coeff_fx[i] = 0; - move16(); + move32(); } FOR( i = 0; i < 3; i++ ) { hShoeboxConfig->list_orig_fx[i] = 0; - move16(); + move32(); } #if 1/*To be removed later :floating point initializations*/ hShoeboxConfig->room_L = 0.0f; @@ -2355,17 +2355,17 @@ static ivas_error ivas_shoebox_obj_init( FOR ( i = 0; i < 75; i++ ) { hShoeboxObj->src_pos_fx[i] = 0; - move16(); + move32(); } FOR ( i = 0; i < 25; i++ ) { hShoeboxObj->src_dist_fx[i] = 0; - move16(); + move32(); } FOR( i = 0; i < 3; i++ ) { hShoeboxObj->list_pos_fx[i] = 0; - move16(); + move32(); } hShoeboxObj->nSrc = 0; @@ -2373,11 +2373,11 @@ static ivas_error ivas_shoebox_obj_init( hShoeboxObj->min_wall_dist_fx = 0; hShoeboxObj->soundspeed_fx = 0; hShoeboxObj->air_coeff_fx = 0; - move16(); - move16(); - move16(); - move16(); - move16(); + move32(); + move32(); + move32(); + move32(); + move32(); IF ( ( error = ivas_shoebox_config_init_params( &hShoeboxObj->cal ) ) != IVAS_ERR_OK ) { @@ -2522,7 +2522,7 @@ static ivas_error ivas_er_init_handle( } FOR ( i = 0; i < 3; i++ ) { - reflections->user_origin[i] = fixedToFloat( reflections->user_origin_fx[i], 14 ); + reflections->user_origin[i] = fixedToFloat( reflections->user_origin_fx[i], Q22 ); } #endif return IVAS_ERR_OK; @@ -2916,6 +2916,23 @@ ivas_error ivas_rend_openCrend( /* Set sample rate and frame size */ hCrend->reflections->output_Fs = (float) output_Fs; hCrend->reflections->max_frame_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ); +#ifdef IVAS_FLOAT_FIXED + hRendCfg->roomAcoustics.dimensions.x_fx = hRendCfg->roomAcoustics.dimensions.x * 4194304; // Q10.22, min value:1, max :999.0 + hRendCfg->roomAcoustics.dimensions.y_fx = hRendCfg->roomAcoustics.dimensions.y * 4194304; // Q10.22 + hRendCfg->roomAcoustics.dimensions.z_fx = hRendCfg->roomAcoustics.dimensions.z * 4194304; // Q10.22 + + + for ( int i = 0; i < 6; i++ ) + { + hRendCfg->roomAcoustics.AbsCoeff_fx[i] = hRendCfg->roomAcoustics.AbsCoeff[i] * 1073741824; // Q2.30 min :0 max 1 + } + + hRendCfg->roomAcoustics.ListenerOrigin.x_fx = hRendCfg->roomAcoustics.ListenerOrigin.x * 4194304; //( 2147483648 >> 2 ); + hRendCfg->roomAcoustics.ListenerOrigin.y_fx = hRendCfg->roomAcoustics.ListenerOrigin.y * ( 4194304 ); + hRendCfg->roomAcoustics.ListenerOrigin.z_fx = hRendCfg->roomAcoustics.ListenerOrigin.z * ( 4194304 ); + + +#endif /* Init Shoebox */ ivas_shoebox_config_init( &hCrend->reflections->shoebox_lib.cal, hRendCfg ); diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index dbca8eaf72eaef34653476668ab4f87fb49daabf..3b8fd7d6a6d150c8937fcb0759c80b48c0524781 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -1101,8 +1101,8 @@ ivas_error TDREND_Update_listener_orientation( ivas_error TDREND_Update_listener_orientation_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ const Word16 headRotEnabled, /* i : Headrotation flag */ - const IVAS_QUATERNION_FX *headPosition_fx, /* i : Listener orientation Qx */ - const IVAS_VECTOR3_FX *Pos_fx /* i : Listener Position */ + const IVAS_QUATERNION *headPosition_fx, /* i : Listener orientation Qx */ + const IVAS_VECTOR3 *Pos_fx /* i : Listener Position */ ) { Word32 FrontVec_fx[3]; diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index 8c2290ba7c3b5daee03cd81739c91c148bc4b672..af242aa45fa1237e6fea5188ade8a39616a3636b 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -73,10 +73,10 @@ static IVAS_QUATERNION IdentityQuaternion( } #ifdef IVAS_FLOAT_FIXED -static IVAS_QUATERNION_FX IdentityQuaternion_fx( +static IVAS_QUATERNION IdentityQuaternion_fx( void ) { - IVAS_QUATERNION_FX q; + IVAS_QUATERNION q; q.w_fx = ONE_IN_Q31; q.x_fx = q.y_fx = q.z_fx = 0; @@ -110,11 +110,11 @@ void QuaternionProduct( #ifdef IVAS_FLOAT_FIXED void QuaternionProduct_fx( - const IVAS_QUATERNION_FX q1, - const IVAS_QUATERNION_FX q2, - IVAS_QUATERNION_FX *const r ) + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, + IVAS_QUATERNION *const r ) { - IVAS_QUATERNION_FX tmp; + IVAS_QUATERNION tmp; Word64 mul[4] = { 0 }; Word16 q_min, q_fact[4] = { 0 }; mul[0] = W_mult0_32_32( q1.w_fx, q2.w_fx ); @@ -218,8 +218,8 @@ static float QuaternionDotProduct( #ifdef IVAS_FLOAT_FIXED static Word32 QuaternionDotProduct_fx( - const IVAS_QUATERNION_FX q1, - const IVAS_QUATERNION_FX q2, + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, Word16 *q_fact ) { Word32 a[4], b[4] = { 0 }; @@ -293,9 +293,9 @@ static void QuaternionDivision( #ifdef IVAS_FLOAT_FIXED static void QuaternionDivision_fx( - const IVAS_QUATERNION_FX q, + const IVAS_QUATERNION q, const Word32 d, - IVAS_QUATERNION_FX *const r, + IVAS_QUATERNION *const r, Word16 den_e ) { float den = me2f( d, den_e ); @@ -335,8 +335,8 @@ static void QuaternionNormalize( #ifdef IVAS_FLOAT_FIXED static void QuaternionNormalize_fx( - const IVAS_QUATERNION_FX q_fx, - IVAS_QUATERNION_FX *const r_fx ) + const IVAS_QUATERNION q_fx, + IVAS_QUATERNION *const r_fx ) { Word16 q_dot, sqrt_e = 0; Word32 sqrt_fx; @@ -389,15 +389,14 @@ void QuaternionSlerp( #ifdef IVAS_FLOAT_FIXED void QuaternionSlerp_fx( - const IVAS_QUATERNION_FX q1_fx, - const IVAS_QUATERNION_FX q2_fx, + const IVAS_QUATERNION q1_fx, + const IVAS_QUATERNION q2_fx, const Word32 t_fx, - IVAS_QUATERNION_FX *const r_fx ) + IVAS_QUATERNION *const r_fx ) { float angle, denom, s, s2; float t = me2f( t_fx, 1 ); IVAS_QUATERNION q1, q2; - IVAS_QUATERNION *r = malloc( sizeof( IVAS_QUATERNION ) ); Word16 q_dot = 0; Word32 s_fx = QuaternionDotProduct_fx( q1_fx, q2_fx, &q_dot ); s = me2f( s_fx, 31 - q_dot ); @@ -422,18 +421,17 @@ void QuaternionSlerp_fx( q2.x = me2f( q2_fx.x_fx, 31 - q2_fx.x_qfact ); q2.y = me2f( q2_fx.y_fx, 31 - q2_fx.y_qfact ); q2.z = me2f( q2_fx.z_fx, 31 - q2_fx.z_qfact ); - r->x = ( q1.x * s + q2.x * s2 ) / denom; - r->y = ( q1.y * s + q2.y * s2 ) / denom; - r->z = ( q1.z * s + q2.z * s2 ) / denom; - r->w = ( q1.w * s + q2.w * s2 ) / denom; - - r_fx->w_fx = float_to_fix( r->w, Q29 ); - r_fx->x_fx = float_to_fix( r->x, Q29 ); - r_fx->y_fx = float_to_fix( r->y, Q29 ); - r_fx->z_fx = float_to_fix( r->z, Q29 ); + r_fx->x = ( q1.x * s + q2.x * s2 ) / denom; + r_fx->y = ( q1.y * s + q2.y * s2 ) / denom; + r_fx->z = ( q1.z * s + q2.z * s2 ) / denom; + r_fx->w = ( q1.w * s + q2.w * s2 ) / denom; + + r_fx->w_fx = float_to_fix(r_fx->w, Q29 ); + r_fx->x_fx = float_to_fix(r_fx->x, Q29 ); + r_fx->y_fx = float_to_fix(r_fx->y, Q29 ); + r_fx->z_fx = float_to_fix(r_fx->z, Q29 ); r_fx->w_qfact = r_fx->x_qfact = r_fx->y_qfact = r_fx->z_qfact = Q29; QuaternionNormalize_fx( *r_fx, r_fx ); - free(r); return; } @@ -459,8 +457,8 @@ static void QuaternionConjugate( #ifdef IVAS_FLOAT_FIXED static void QuaternionConjugate_fx( - const IVAS_QUATERNION_FX q, - IVAS_QUATERNION_FX *const r ) + const IVAS_QUATERNION q, + IVAS_QUATERNION *const r ) { r->w_fx = q.w_fx; r->x_fx = L_negate( q.x_fx ); @@ -496,10 +494,10 @@ static float QuaternionAngle( #ifdef IVAS_FLOAT_FIXED static Word32 QuaternionAngle_fx( - const IVAS_QUATERNION_FX q1, - const IVAS_QUATERNION_FX q2 ) + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2 ) { - IVAS_QUATERNION_FX q12; + IVAS_QUATERNION q12; Word32 angle = 0; QuaternionConjugate_fx( q1, &q12 ); @@ -579,8 +577,8 @@ void QuaternionInverse( #ifdef IVAS_FLOAT_FIXED void QuaternionInverse_fx( - const IVAS_QUATERNION_FX q, - IVAS_QUATERNION_FX *const r ) + const IVAS_QUATERNION q, + IVAS_QUATERNION *const r ) { Word32 dot_product; Word16 dot_q = 0; @@ -613,11 +611,11 @@ static IVAS_VECTOR3 VectorSubtract( } #ifdef IVAS_FLOAT_FIXED -static IVAS_VECTOR3_FX VectorSubtract_fx( - const IVAS_VECTOR3_FX p1, - const IVAS_VECTOR3_FX p2 ) +static IVAS_VECTOR3 VectorSubtract_fx( + const IVAS_VECTOR3 p1, + const IVAS_VECTOR3 p2 ) { - IVAS_VECTOR3_FX result; + IVAS_VECTOR3 result; Word16 e_result = 0; result.x_fx = BASOP_Util_Add_Mant32Exp( p1.x_fx, ( 31 - p1.x_qfact ), ( L_negate( p2.x_fx ) ), ( 31 - p2.x_qfact ), &e_result ); result.x_qfact = 31 - e_result; @@ -652,11 +650,11 @@ static IVAS_VECTOR3 VectorCrossProduct( } #ifdef IVAS_FLOAT_FIXED -static IVAS_VECTOR3_FX VectorCrossProduct_fx( - const IVAS_VECTOR3_FX p1, - const IVAS_VECTOR3_FX p2 ) +static IVAS_VECTOR3 VectorCrossProduct_fx( + const IVAS_VECTOR3 p1, + const IVAS_VECTOR3 p2 ) { - IVAS_VECTOR3_FX result_fx; + IVAS_VECTOR3 result_fx; Word32 mul1, mul2; Word16 e_result = 0, q_mul1, q_mul2; mul1 = Mpy_32_32( p1.y_fx, p2.z_fx ); @@ -701,8 +699,8 @@ static float VectorDotProduct( #ifdef IVAS_FLOAT_FIXED static Word32 VectorDotProduct_fx( - const IVAS_VECTOR3_FX p1, - const IVAS_VECTOR3_FX p2, + const IVAS_VECTOR3 p1, + const IVAS_VECTOR3 p2, Word16 *q_fact ) { Word32 mul[3] = { 0 }; @@ -743,7 +741,7 @@ static float VectorLength( #ifdef IVAS_FLOAT_FIXED static Word32 VectorLength_fx( - IVAS_VECTOR3_FX p, + IVAS_VECTOR3 p, Word16 *q_fact ) { Word32 mul[3] = { 0 }; @@ -786,10 +784,10 @@ static IVAS_VECTOR3 VectorNormalize( } #ifdef IVAS_FLOAT_FIXED -static IVAS_VECTOR3_FX VectorNormalize_fx( - const IVAS_VECTOR3_FX p ) +static IVAS_VECTOR3 VectorNormalize_fx( + const IVAS_VECTOR3 p ) { - IVAS_VECTOR3_FX result_fx; + IVAS_VECTOR3 result_fx; Word32 length_fx; Word16 q_len, scale = 0; length_fx = VectorLength_fx( p, &q_len ); @@ -852,11 +850,11 @@ static void VectorRotationToQuaternion( #ifdef IVAS_FLOAT_FIXED static void VectorRotationToQuaternion_fx( - const IVAS_VECTOR3_FX p1, - const IVAS_VECTOR3_FX p2, - IVAS_QUATERNION_FX *const r ) + const IVAS_VECTOR3 p1, + const IVAS_VECTOR3 p2, + IVAS_QUATERNION *const r ) { - IVAS_VECTOR3_FX cross_product_fx, p1_normalized_fx = { 0 }, p2_normalized_fx = { 0 }; + IVAS_VECTOR3 cross_product_fx, p1_normalized_fx = { 0 }, p2_normalized_fx = { 0 }; Word32 dot_product_fx; Word16 q_dot; @@ -944,8 +942,7 @@ ivas_error ivas_orient_trk_Init( ivas_error ivas_orient_trk_Init_fx( ivas_orient_trk_state_t *pOTR ) /* i/o : orientation tracker handle */ { - IVAS_QUATERNION_FX identity_fx; - ivas_orient_trk_state_t_fx *pOTR_fx = malloc( sizeof( ivas_orient_trk_state_t_fx ) ); + IVAS_QUATERNION identity_fx; //===================Remove float code once caller function is converted to fixed=================// IF ( pOTR == NULL ) @@ -959,27 +956,26 @@ ivas_error ivas_orient_trk_Init_fx( identity_fx.x_qfact = identity_fx.y_qfact = identity_fx.z_qfact = Q31; /* configuration parameters */ - pOTR_fx->centerAdaptationRate_fx = C_ADP_RATE_Q31; - pOTR_fx->offCenterAdaptationRate_fx = OFF_C_ADP_RATE_Q31; - pOTR_fx->adaptationAngle_fx = PI_OVER_4_Q29; /* Excursion angle relative to center at which maximum adaptation rate shall be applied */ + pOTR->centerAdaptationRate_fx = C_ADP_RATE_Q31; + pOTR->offCenterAdaptationRate_fx = OFF_C_ADP_RATE_Q31; + pOTR->adaptationAngle_fx = PI_OVER_4_Q29; /* Excursion angle relative to center at which maximum adaptation rate shall be applied */ /* initial adaptivity filter coefficient, will be auto-adapted */ // pOTR->alpha = sinf( PI2 * pOTR->offCenterAdaptationRate / OTR_UPDATE_RATE ); /* start adaptation at off-center rate = fastest rate */ - pOTR_fx->alpha_fx = 33731208; // Q31 - pOTR_fx->trkRot_fx = identity_fx; - pOTR_fx->absAvgRot_fx = identity_fx; + pOTR->alpha_fx = 33731208; // Q31 + pOTR->trkRot = identity_fx; + pOTR->absAvgRot = identity_fx; /* Use frontal and horiontal orientation as reference orientation, unless/until overridden */ - pOTR_fx->refRot_fx = identity_fx; + pOTR->refRot = identity_fx; // this part still float// /* set safe default tracking mode */ pOTR->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; - pOTR->alpha = me2f( pOTR_fx->alpha_fx, 0 ); - pOTR->refRot.w = pOTR->absAvgRot.w = pOTR->trkRot.w = fix_to_float( pOTR_fx->trkRot_fx.w_fx, pOTR_fx->trkRot_fx.w_qfact ); - pOTR->refRot.x = pOTR->absAvgRot.x = pOTR->trkRot.x = fix_to_float( pOTR_fx->trkRot_fx.x_fx, pOTR_fx->trkRot_fx.x_qfact ); - pOTR->refRot.y = pOTR->absAvgRot.y = pOTR->trkRot.y = fix_to_float( pOTR_fx->trkRot_fx.y_fx, pOTR_fx->trkRot_fx.y_qfact ); - pOTR->refRot.z = pOTR->absAvgRot.z = pOTR->trkRot.z = fix_to_float( pOTR_fx->trkRot_fx.z_fx, pOTR_fx->trkRot_fx.z_qfact ); - free(pOTR_fx); + pOTR->alpha = me2f(pOTR->alpha_fx, 0 ); + pOTR->refRot.w = pOTR->absAvgRot.w = pOTR->trkRot.w = fix_to_float(pOTR->trkRot.w_fx, pOTR->trkRot.w_qfact ); + pOTR->refRot.x = pOTR->absAvgRot.x = pOTR->trkRot.x = fix_to_float(pOTR->trkRot.x_fx, pOTR->trkRot.x_qfact ); + pOTR->refRot.y = pOTR->absAvgRot.y = pOTR->trkRot.y = fix_to_float(pOTR->trkRot.y_fx, pOTR->trkRot.y_qfact ); + pOTR->refRot.z = pOTR->absAvgRot.z = pOTR->trkRot.z = fix_to_float(pOTR->trkRot.z_fx, pOTR->trkRot.z_qfact ); return IVAS_ERR_OK; } @@ -1008,7 +1004,7 @@ ivas_error ivas_orient_trk_SetTrackingType( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_SetTrackingType_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ ) { @@ -1017,7 +1013,7 @@ ivas_error ivas_orient_trk_SetTrackingType_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - pOTR->orientation_tracking_fx = orientation_tracking; + pOTR->orientation_tracking = orientation_tracking; return IVAS_ERR_OK; } @@ -1031,8 +1027,8 @@ ivas_error ivas_orient_trk_SetTrackingType_fx( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_SetReferenceRotation_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - const IVAS_QUATERNION_FX refRot /* i : reference rotation */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + const IVAS_QUATERNION refRot /* i : reference rotation */ ) { IF ( pOTR == NULL ) @@ -1046,7 +1042,7 @@ ivas_error ivas_orient_trk_SetReferenceRotation_fx( { Euler2Quat( deg2rad( refRot.x ), deg2rad( refRot.y ), deg2rad( refRot.z ), &pOTR->refRot ); }*/ - pOTR->refRot_fx = refRot; + pOTR->refRot = refRot; return IVAS_ERR_OK; } @@ -1112,8 +1108,8 @@ ivas_error ivas_orient_trk_GetMainOrientation( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_GetMainOrientation_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION_FX *pOrientation /* i/o: average/reference orientation */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + IVAS_QUATERNION *pOrientation /* i/o: average/reference orientation */ ) { IF ( pOTR == NULL || pOrientation == NULL ) @@ -1121,7 +1117,7 @@ ivas_error ivas_orient_trk_GetMainOrientation_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - SWITCH ( pOTR->orientation_tracking_fx ) + SWITCH ( pOTR->orientation_tracking ) { case IVAS_HEAD_ORIENT_TRK_NONE: *pOrientation = IdentityQuaternion_fx(); @@ -1129,10 +1125,10 @@ ivas_error ivas_orient_trk_GetMainOrientation_fx( case IVAS_HEAD_ORIENT_TRK_REF_VEC: case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: case IVAS_HEAD_ORIENT_TRK_REF: - *pOrientation = pOTR->refRot_fx; + *pOrientation = pOTR->refRot; BREAK; case IVAS_HEAD_ORIENT_TRK_AVG: - *pOrientation = pOTR->absAvgRot_fx; + *pOrientation = pOTR->absAvgRot; BREAK; } @@ -1163,8 +1159,8 @@ ivas_error ivas_orient_trk_GetTrackedRotation( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_GetTrackedRotation_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION_FX *pRotation /* i/o: processed rotation */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + IVAS_QUATERNION *pRotation /* i/o: processed rotation */ ) { IF ( pOTR == NULL || pRotation == NULL ) @@ -1172,7 +1168,7 @@ ivas_error ivas_orient_trk_GetTrackedRotation_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *pRotation = pOTR->trkRot_fx; + *pRotation = pOTR->trkRot; return IVAS_ERR_OK; } @@ -1238,13 +1234,13 @@ ivas_error ivas_orient_trk_SetReferenceVector( #ifdef IVAS_FLOAT_FIXED ivas_error ivas_orient_trk_SetReferenceVector_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - const IVAS_VECTOR3_FX listenerPos, /* i : Listener position */ - const IVAS_VECTOR3_FX refPos /* i : Reference position */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + const IVAS_VECTOR3 listenerPos, /* i : Listener position */ + const IVAS_VECTOR3 refPos /* i : Reference position */ ) { - IVAS_VECTOR3_FX acousticFrontVector, ivasForwardVector; - IVAS_VECTOR3_FX listenerPosLevel, refPosLevel; + IVAS_VECTOR3 acousticFrontVector, ivasForwardVector; + IVAS_VECTOR3 listenerPosLevel, refPosLevel; Word32 acousticFrontVectorLength; Word16 acousticFrontVector_q; @@ -1253,7 +1249,7 @@ ivas_error ivas_orient_trk_SetReferenceVector_fx( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - SWITCH ( pOTR->orientation_tracking_fx ) + SWITCH ( pOTR->orientation_tracking ) { case IVAS_HEAD_ORIENT_TRK_NONE: case IVAS_HEAD_ORIENT_TRK_REF: @@ -1290,7 +1286,7 @@ ivas_error ivas_orient_trk_SetReferenceVector_fx( ivasForwardVector.y_fx = 0; ivasForwardVector.z_fx = 0; ivasForwardVector.x_qfact = ivasForwardVector.y_qfact = ivasForwardVector.z_qfact = Q31; - VectorRotationToQuaternion_fx( ivasForwardVector, acousticFrontVector, &pOTR->refRot_fx ); + VectorRotationToQuaternion_fx( ivasForwardVector, acousticFrontVector, &pOTR->refRot ); return IVAS_ERR_OK; } @@ -1404,29 +1400,28 @@ ivas_error ivas_orient_trk_Process_fx( //===================Remove float code once caller function is converted to fixed=================// float alpha = pOTR->alpha; ivas_error result; - IVAS_QUATERNION_FX absRot_fx = { 0 }; + IVAS_QUATERNION absRot_fx = { 0 }; Word32 updateRate_fx; Word32 rateRange_fx; Word32 cutoffFrequency_fx, cutoff_prod; Word16 q_cutoff_prod = 0; Word32 alpha_fx = float_to_fix( alpha, Q30 ); - ivas_orient_trk_state_t_fx *pOTR_fx = malloc( sizeof( ivas_orient_trk_state_t_fx ) ); - pOTR_fx->refRot_fx.w_qfact = pOTR_fx->refRot_fx.x_qfact = pOTR_fx->refRot_fx.y_qfact = pOTR_fx->refRot_fx.z_qfact = Q29; + pOTR->refRot.w_qfact = pOTR->refRot.x_qfact = pOTR->refRot.y_qfact = pOTR->refRot.z_qfact = Q29; absRot_fx.w_qfact = absRot_fx.x_qfact = absRot_fx.y_qfact = absRot_fx.z_qfact = Q29; - pOTR_fx->absAvgRot_fx.w_qfact = pOTR_fx->absAvgRot_fx.x_qfact = pOTR_fx->absAvgRot_fx.y_qfact = pOTR_fx->absAvgRot_fx.z_qfact = Q29; + pOTR->absAvgRot.w_qfact = pOTR->absAvgRot.x_qfact = pOTR->absAvgRot.y_qfact = pOTR->absAvgRot.z_qfact = Q29; updateRate_fx = float_to_fix( updateRate, Q23 ); // value is 200// absRot_fx.w_fx = float_to_fix( absRot.w, absRot_fx.w_qfact ); absRot_fx.x_fx = float_to_fix( absRot.x, absRot_fx.x_qfact ); absRot_fx.y_fx = float_to_fix( absRot.y, absRot_fx.y_qfact ); absRot_fx.z_fx = float_to_fix( absRot.z, absRot_fx.z_qfact ); - pOTR_fx->refRot_fx.w_fx = float_to_fix( pOTR->refRot.w, pOTR_fx->refRot_fx.w_qfact ); - pOTR_fx->refRot_fx.x_fx = float_to_fix( pOTR->refRot.x, pOTR_fx->refRot_fx.x_qfact ); - pOTR_fx->refRot_fx.y_fx = float_to_fix( pOTR->refRot.y, pOTR_fx->refRot_fx.y_qfact ); - pOTR_fx->refRot_fx.z_fx = float_to_fix( pOTR->refRot.z, pOTR_fx->refRot_fx.z_qfact ); - pOTR_fx->absAvgRot_fx.w_fx = float_to_fix( pOTR->absAvgRot.w, pOTR_fx->absAvgRot_fx.w_qfact ); - pOTR_fx->absAvgRot_fx.x_fx = float_to_fix( pOTR->absAvgRot.x, pOTR_fx->absAvgRot_fx.x_qfact ); - pOTR_fx->absAvgRot_fx.y_fx = float_to_fix( pOTR->absAvgRot.y, pOTR_fx->absAvgRot_fx.y_qfact ); - pOTR_fx->absAvgRot_fx.z_fx = float_to_fix( pOTR->absAvgRot.z, pOTR_fx->absAvgRot_fx.z_qfact ); + pOTR->refRot.w_fx = float_to_fix( pOTR->refRot.w, pOTR->refRot.w_qfact ); + pOTR->refRot.x_fx = float_to_fix( pOTR->refRot.x, pOTR->refRot.x_qfact ); + pOTR->refRot.y_fx = float_to_fix( pOTR->refRot.y, pOTR->refRot.y_qfact ); + pOTR->refRot.z_fx = float_to_fix( pOTR->refRot.z, pOTR->refRot.z_qfact ); + pOTR->absAvgRot.w_fx = float_to_fix( pOTR->absAvgRot.w, pOTR->absAvgRot.w_qfact ); + pOTR->absAvgRot.x_fx = float_to_fix( pOTR->absAvgRot.x, pOTR->absAvgRot.x_qfact ); + pOTR->absAvgRot.y_fx = float_to_fix( pOTR->absAvgRot.y, pOTR->absAvgRot.y_qfact ); + pOTR->absAvgRot.z_fx = float_to_fix( pOTR->absAvgRot.z, pOTR->absAvgRot.z_qfact ); IF ( pOTR == NULL || pTrkRot == NULL ) { @@ -1438,13 +1433,13 @@ ivas_error ivas_orient_trk_Process_fx( SWITCH ( pOTR->orientation_tracking ) { case IVAS_HEAD_ORIENT_TRK_NONE: - pOTR_fx->trkRot_fx = absRot_fx; + pOTR->trkRot = absRot_fx; BREAK; case IVAS_HEAD_ORIENT_TRK_REF: case IVAS_HEAD_ORIENT_TRK_REF_VEC: case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: /* Reset average orientation */ - pOTR_fx->absAvgRot_fx = absRot_fx; + pOTR->absAvgRot = absRot_fx; Word16 scale_e; Word32 div; @@ -1452,22 +1447,22 @@ ivas_error ivas_orient_trk_Process_fx( scale_e = scale_e - 8; // e+e1-e2// // here div value is less so we can use sandwitch rule of sine// - pOTR_fx->alpha_fx = div; + pOTR->alpha_fx = div; /* Compute relative orientation = (absolute orientation) - (reference orientation) */ - QuaternionInverse_fx( pOTR_fx->refRot_fx, &pOTR_fx->trkRot_fx ); - QuaternionProduct_fx( pOTR_fx->trkRot_fx, absRot_fx, &pOTR_fx->trkRot_fx ); + QuaternionInverse_fx( pOTR->refRot, &pOTR->trkRot ); + QuaternionProduct_fx( pOTR->trkRot, absRot, &pOTR->trkRot ); ; BREAK; case IVAS_HEAD_ORIENT_TRK_AVG: /* Compute average (low-pass filtered) absolute orientation */ - QuaternionSlerp_fx( pOTR_fx->absAvgRot_fx, absRot_fx, alpha_fx, &pOTR_fx->absAvgRot_fx ); + QuaternionSlerp_fx( pOTR->absAvgRot, absRot_fx, alpha_fx, &pOTR->absAvgRot ); /* Compute relative orientation = (absolute orientation) - (average absolute orientation) */ - QuaternionInverse_fx( pOTR_fx->absAvgRot_fx, &pOTR_fx->trkRot_fx ); + QuaternionInverse_fx( pOTR->absAvgRot, &pOTR->trkRot ); Word32 angle_fx, relativeOrientationRate_fx = 0; - QuaternionProduct_fx( pOTR_fx->trkRot_fx, absRot_fx, &pOTR_fx->trkRot_fx ); - angle_fx = QuaternionAngle_fx( absRot_fx, pOTR_fx->trkRot_fx ); // Q29 + QuaternionProduct_fx( pOTR->trkRot, absRot_fx, &pOTR->trkRot ); + angle_fx = QuaternionAngle_fx( absRot_fx, pOTR->trkRot ); // Q29 Word16 result_e = 0; Word16 temp_result = BASOP_Util_Divide3232_Scale( angle_fx, PI_OVER_4_Q29, &result_e ); relativeOrientationRate_fx = L_deposit_h( temp_result ); @@ -1506,8 +1501,8 @@ ivas_error ivas_orient_trk_Process_fx( q_cutoff_prod = 31 + 28 - 31; temp_result = BASOP_Util_Divide3232_Scale( cutoff_prod, updateRate_fx, &result_e ); result_e = result_e + ( 23 - q_cutoff_prod ); - pOTR_fx->alpha_fx = L_deposit_h( temp_result ); - pOTR->alpha = me2f( pOTR_fx->alpha_fx, result_e ); // Remove this floating code// + pOTR->alpha_fx = L_deposit_h( temp_result ); + pOTR->alpha = me2f( pOTR->alpha_fx, result_e ); // Remove this floating code// BREAK; default: result = IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Non-supported orientation tracking adaptation type" ); @@ -1516,16 +1511,15 @@ ivas_error ivas_orient_trk_Process_fx( IF ( result == IVAS_ERR_OK ) { - pOTR->trkRot.w = me2f( pOTR_fx->trkRot_fx.w_fx, 31 - pOTR_fx->trkRot_fx.w_qfact ); - pOTR->trkRot.x = me2f( pOTR_fx->trkRot_fx.x_fx, 31 - pOTR_fx->trkRot_fx.x_qfact ); - pOTR->trkRot.y = me2f( pOTR_fx->trkRot_fx.y_fx, 31 - pOTR_fx->trkRot_fx.y_qfact ); - pOTR->trkRot.z = me2f( pOTR_fx->trkRot_fx.z_fx, 31 - pOTR_fx->trkRot_fx.z_qfact ); - pOTR->absAvgRot.w = me2f( pOTR_fx->absAvgRot_fx.w_fx, 31 - pOTR_fx->absAvgRot_fx.w_qfact ); - pOTR->absAvgRot.x = me2f( pOTR_fx->absAvgRot_fx.x_fx, 31 - pOTR_fx->absAvgRot_fx.x_qfact ); - pOTR->absAvgRot.y = me2f( pOTR_fx->absAvgRot_fx.y_fx, 31 - pOTR_fx->absAvgRot_fx.y_qfact ); - pOTR->absAvgRot.z = me2f( pOTR_fx->absAvgRot_fx.z_fx, 31 - pOTR_fx->absAvgRot_fx.z_qfact ); + pOTR->trkRot.w = me2f( pOTR->trkRot.w_fx, 31 - pOTR->trkRot.w_qfact ); + pOTR->trkRot.x = me2f( pOTR->trkRot.x_fx, 31 - pOTR->trkRot.x_qfact ); + pOTR->trkRot.y = me2f( pOTR->trkRot.y_fx, 31 - pOTR->trkRot.y_qfact ); + pOTR->trkRot.z = me2f( pOTR->trkRot.z_fx, 31 - pOTR->trkRot.z_qfact ); + pOTR->absAvgRot.w = me2f( pOTR->absAvgRot.w_fx, 31 - pOTR->absAvgRot.w_qfact ); + pOTR->absAvgRot.x = me2f( pOTR->absAvgRot.x_fx, 31 - pOTR->absAvgRot.x_qfact ); + pOTR->absAvgRot.y = me2f( pOTR->absAvgRot.y_fx, 31 - pOTR->absAvgRot.y_qfact ); + pOTR->absAvgRot.z = me2f( pOTR->absAvgRot.z_fx, 31 - pOTR->absAvgRot.z_qfact ); *pTrkRot = pOTR->trkRot; - free(pOTR_fx); } return result; diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 37d26ae1f4665e5c0ca56882baf3fdf30e6959cc..e97e15d29c69b24e5868844a4285900cb7c9425c 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1767,6 +1767,7 @@ void ivas_shoebox_init( shoebox_config_t *cal ); +#ifndef IVAS_FLOAT_FIXED void ivas_shoebox_set_scene ( shoebox_obj_t *obj, shoebox_output_t *ER_PARAMS, @@ -1775,6 +1776,17 @@ void ivas_shoebox_set_scene ( const uint16_t isCartesian, const uint16_t isRelative ); +#else + +void ivas_shoebox_set_scene ( + shoebox_obj_t *obj, + shoebox_output_t *ER_PARAMS, + const Word32 list_pos[3], + const Word32 src_pos_data[], + const uint16_t isCartesian, + const uint16_t isRelative +); +#endif /*---------------------------------------------------------------------------------* * Early reflections prototypes @@ -1841,6 +1853,9 @@ float deg2rad( float rad2deg( float radians ); +Word32 rad2deg_fx( + Word32 radians +); void QuatToRotMat( const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ @@ -2053,9 +2068,9 @@ void QuaternionProduct( #ifdef IVAS_FLOAT_FIXED void QuaternionProduct_fx( - const IVAS_QUATERNION_FX q1, - const IVAS_QUATERNION_FX q2, - IVAS_QUATERNION_FX *const r); + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, + IVAS_QUATERNION *const r); #endif void QuaternionInverse( @@ -2072,15 +2087,15 @@ void QuaternionSlerp( #ifdef IVAS_FLOAT_FIXED void QuaternionInverse_fx( - const IVAS_QUATERNION_FX q, - IVAS_QUATERNION_FX *const r + const IVAS_QUATERNION q, + IVAS_QUATERNION *const r ); void QuaternionSlerp_fx( - const IVAS_QUATERNION_FX q1, - const IVAS_QUATERNION_FX q2, + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, const Word32 t, - IVAS_QUATERNION_FX *const r + IVAS_QUATERNION *const r ); #endif @@ -2132,29 +2147,29 @@ ivas_error ivas_orient_trk_Init_fx( ); ivas_error ivas_orient_trk_SetReferenceRotation_fx( - ivas_orient_trk_state_t_fx *pOTR_fx, /* i/o: orientatoin trakcer handle */ - const IVAS_QUATERNION_FX refRot /* i : reference rotation */ + ivas_orient_trk_state_t *pOTR_fx, /* i/o: orientatoin trakcer handle */ + const IVAS_QUATERNION refRot /* i : reference rotation */ ); ivas_error ivas_orient_trk_SetReferenceVector_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - const IVAS_VECTOR3_FX listenerPos, /* i : Listener position */ - const IVAS_VECTOR3_FX refPos /* i : Reference position */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + const IVAS_VECTOR3 listenerPos, /* i : Listener position */ + const IVAS_VECTOR3 refPos /* i : Reference position */ ); ivas_error ivas_orient_trk_SetTrackingType_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ const IVAS_HEAD_ORIENT_TRK_T orientation_tracking /* i : orientation tracking type */ ); ivas_error ivas_orient_trk_GetMainOrientation_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION_FX *pOrientation /* i/o: average/reference orientation */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + IVAS_QUATERNION *pOrientation /* i/o: average/reference orientation */ ); ivas_error ivas_orient_trk_GetTrackedRotation_fx( - ivas_orient_trk_state_t_fx *pOTR, /* i/o: orientation tracker handle */ - IVAS_QUATERNION_FX *pRotation /* i/o: processed rotation */ + ivas_orient_trk_state_t *pOTR, /* i/o: orientation tracker handle */ + IVAS_QUATERNION *pRotation /* i/o: processed rotation */ ); ivas_error ivas_orient_trk_Process_fx( diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index 84004475a59504e93193a296de79b46ef3c8710b..12e1c19599fb7641eda5025b3b5a1a50778fa941 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -71,7 +71,7 @@ static uint16_t LC_mixing_7_1_4[11] = { 0, 1, 2, 3, 4, 3, 4, 0, 1, 2, 3 }; * * Initializes the reflections data structure according to the requested input config. *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED ivas_error ivas_er_init( er_struct_t *reflections, const AUDIO_CONFIG inConfig ) @@ -132,6 +132,89 @@ ivas_error ivas_er_init( return error; } +#else +ivas_error ivas_er_init( + er_struct_t *reflections, + const AUDIO_CONFIG inConfig ) +{ + ivas_error error; + uint8_t i; + + /* Set to defaults for shoebox */ + reflections->is_ready = 0; + reflections->audio_config = IVAS_AUDIO_CONFIG_INVALID; + reflections->is_cartesian = 0; + reflections->is_relative = 1; + reflections->shoebox_data.n_ref = ER_NUM_REF; + move16(); + move16(); + move16(); + move16(); + move32(); + + +#if 0 +// Commenting this code as the values are initialized in below loop. +// This initialization is redundant. + reflections->user_origin[0] = 0.0f; + reflections->user_origin[1] = 0.0f; + reflections->user_origin[2] = ER_LIST_HEIGHT; +#endif + + /* Store scene origin if present */ + + FOR( i = 0; i < 3; i++ ) + { + reflections->user_origin_fx[i] = reflections->shoebox_lib.cal.list_orig_fx[i]; // Q.22 + move32(); + } + + /* Init Shoebox */ + ivas_shoebox_init( &reflections->shoebox_lib, &reflections->shoebox_lib.cal ); + + /* Set mode */ + IF( ( error = ivas_er_set_reflections_mode( reflections, inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < reflections->shoebox_data.n_sources; i++ ) + { + reflections->source_positions[i * 3 + 0] = (float) reflections->source_positions_fx[i * 3 + 0]; + reflections->source_positions[i * 3 + 1] = (float) reflections->source_positions_fx[i * 3 + 1]; + reflections->source_positions[i * 3 + 2] = (float) reflections->source_positions_fx[i * 3 + 2] / ONE_IN_Q30; // table i + } +#endif + + /* Compute the static reflections (first frame) */ + IF( ( error = ivas_er_compute_reflections( reflections ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( ( reflections->closest_ch_idx = (uint16_t *) malloc( reflections->n_total_reflections * sizeof( uint16_t ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + set_s( (int16_t *) reflections->closest_ch_idx, 0, reflections->n_total_reflections ); + + IF( ( error = getAudioConfigNumChannels( reflections->audio_config, &( reflections->nchan_out ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize Encoder */ + IF( ( error = ivas_er_encoder_init( reflections ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Update flag to indicate that reflection module is ready to process */ + reflections->is_ready = 1; + + return error; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -162,9 +245,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->shoebox_data.n_sources = 1; reflections->n_LC_sources = 1; reflections->LC_mixing = LC_mixing_5_1; +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[0] = 0; reflections->source_positions[1] = 0; reflections->source_positions[2] = ER_RADIUS; +#else + reflections->source_positions[0] = 0; + reflections->source_positions[1] = 0; + reflections->source_positions[2] = ER_RADIUS_FX; +#endif break; case IVAS_AUDIO_CONFIG_STEREO: reflections->shoebox_data.n_sources = 2; @@ -172,9 +261,17 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_5_1; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP2[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP2[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; + +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP2_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP2_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; + +#endif } break; case IVAS_AUDIO_CONFIG_5_1: @@ -183,9 +280,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_5_1; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP6[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP6[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP6_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP6_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; +#endif } break; case IVAS_AUDIO_CONFIG_7_1: @@ -194,9 +297,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_7_1; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP12[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP12[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP12_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP12_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; +#endif } break; case IVAS_AUDIO_CONFIG_5_1_2: @@ -205,9 +314,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_5_1_2; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP14[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP14[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP14_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP14_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; +#endif } break; case IVAS_AUDIO_CONFIG_5_1_4: @@ -216,9 +331,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_5_1_4; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP16[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP16[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP16_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP16_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; +#endif } break; case IVAS_AUDIO_CONFIG_7_1_4: @@ -227,9 +348,15 @@ ivas_error ivas_er_set_reflections_mode( reflections->LC_mixing = LC_mixing_7_1_4; for ( ch = 0; ch < reflections->shoebox_data.n_sources; ch++ ) { +#ifndef IVAS_FLOAT_FIXED reflections->source_positions[3 * ch] = deg2rad( ls_azimuth_CICP19[ch] ); reflections->source_positions[1 + ( 3 * ch )] = deg2rad( ls_elevation_CICP19[ch] ); reflections->source_positions[2 + ( 3 * ch )] = ER_RADIUS; +#else + reflections->source_positions_fx[3 * ch] = ls_azimuth_CICP19_idx[ch]; + reflections->source_positions_fx[1 + ( 3 * ch )] = ls_elevation_CICP19_idx[ch]; + reflections->source_positions_fx[2 + ( 3 * ch )] = ER_RADIUS_FX; +#endif } break; case IVAS_AUDIO_CONFIG_HOA3: @@ -290,10 +417,16 @@ ivas_error ivas_er_encoder_init( { src_idx = ( j > LFE_CHANNEL ) ? j - 1 : j; +#ifndef IVAS_FLOAT_FIXED p_x_src = reflections->source_positions[src_idx * 3 + 2] * ( cosf( reflections->source_positions[src_idx * 3 + 1] ) * cosf( reflections->source_positions[src_idx * 3] ) ); p_y_src = reflections->source_positions[src_idx * 3 + 2] * ( cosf( reflections->source_positions[src_idx * 3 + 1] ) * sinf( reflections->source_positions[src_idx * 3] ) ); p_z_src = reflections->source_positions[src_idx * 3 + 2] * sinf( reflections->source_positions[src_idx * 3 + 1] ); +#else + p_x_src = reflections->source_positions[src_idx * 3 + 2] * ( shoebox_sin_cos_tbl[(int32_t) ( reflections->source_positions[src_idx * 3 + 1] )][1] * shoebox_sin_cos_tbl[(int32_t) ( reflections->source_positions[src_idx * 3] )][1] ); + p_y_src = reflections->source_positions[src_idx * 3 + 2] * ( shoebox_sin_cos_tbl[(int32_t) ( reflections->source_positions[src_idx * 3 + 1] )][1] * shoebox_sin_cos_tbl[(int32_t) ( reflections->source_positions[src_idx * 3] )][0] ); + p_z_src = reflections->source_positions[src_idx * 3 + 2] * shoebox_sin_cos_tbl[(int32_t) ( reflections->source_positions[src_idx * 3 + 1] )][0]; +#endif tmp = ( p_x_src - p_x ) * ( p_x_src - p_x ); tmp += ( p_y_src - p_y ) * ( p_y_src - p_y ); tmp += ( p_z_src - p_z ) * ( p_z_src - p_z ); @@ -347,8 +480,13 @@ ivas_error ivas_er_compute_reflections( } /* Run shoebox with current reflection parameters */ +#ifndef IVAS_FLOAT_FIXED ivas_shoebox_set_scene( &( reflections->shoebox_lib ), &( reflections->shoebox_data ), reflections->shoebox_lib.cal.list_orig, reflections->source_positions, reflections->is_cartesian, reflections->is_relative ); +#else + ivas_shoebox_set_scene( &( reflections->shoebox_lib ), &( reflections->shoebox_data ), reflections->shoebox_lib.cal.list_orig_fx, + reflections->source_positions_fx, reflections->is_cartesian, reflections->is_relative ); +#endif /* Convert reflection times in seconds to samples and keep track of max */ circ_len = 0; @@ -373,7 +511,7 @@ ivas_error ivas_er_compute_reflections( #ifdef IVAS_FLOAT_FIXED for ( i = 0; i < 150; i++ ) { - reflections->shoebox_data.gains.data_fx[i] = (Word32)( reflections->shoebox_data.gains.data[i]*ONE_IN_Q31); + reflections->shoebox_data.gains.data_fx[i] = L_shl( reflections->shoebox_data.gains.data_fx[i], 9 ); } if ( reflections->circ_buffers ) { @@ -405,7 +543,7 @@ ivas_error ivas_er_compute_reflections( set32_fx( reflections->circ_buffers, 0, reflections->shoebox_data.n_sources * reflections->circ_len ); } #else - if ( reflections->circ_buffers ) + if ( reflections->circ_buffers ) { if ( reflections->circ_len == circ_len ) { @@ -424,7 +562,7 @@ ivas_error ivas_er_compute_reflections( set_f( reflections->circ_buffers, 0.0f, reflections->shoebox_data.n_sources * reflections->circ_len ); } } - else + else { /* circ buffers do not exist */ reflections->circ_len = circ_len; @@ -475,7 +613,7 @@ ivas_error ivas_er_process( Word32 ref_gain; Word32 *buffer_ch; Word32 temp; - + if ( !reflections ) { return IVAS_ERR_INIT_ERROR; @@ -533,7 +671,7 @@ ivas_error ivas_er_process( { for ( j = 0; j < subframe_size; j++ ) { - buffer_ch[samp_idx] = L_add( io[in_ch_idx][j + subframe_offset] , buffer_ch[samp_idx] ) ; + buffer_ch[samp_idx] = L_add( io[in_ch_idx][j + subframe_offset], buffer_ch[samp_idx] ); samp_idx++; samp_idx = samp_idx % reflections->circ_len; } @@ -577,7 +715,7 @@ ivas_error ivas_er_process( } } } - + /* Increment circular buffer start index */ reflections->circ_insert = ( reflections->circ_insert + subframe_size ) % reflections->circ_len; return error; diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 2af418973548c471c52f6fbae220959cd7897e16..befd2f30ebdc22411e8ebd54569872fa1708cecf 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -132,14 +132,10 @@ ivas_error ivas_headTrack_open( } #ifdef IVAS_FLOAT_FIXED - if (((*hHeadTrackData)->OrientationTracker_fx = (ivas_orient_trk_state_t_fx *)malloc(sizeof(ivas_orient_trk_state_t_fx))) == NULL) - { - return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Orientation tracking"); - } - if ((error = ivas_orient_trk_Init_fx((*hHeadTrackData)->OrientationTracker)) != IVAS_ERR_OK) + if ( ( error = ivas_orient_trk_Init_fx( ( *hHeadTrackData )->OrientationTracker ) ) != IVAS_ERR_OK ) { - return error; + return error; } #else @@ -187,14 +183,6 @@ void ivas_headTrack_close( ( *hHeadTrackData )->OrientationTracker = NULL; } -#ifdef IVAS_FLOAT_FIXED - if ((*hHeadTrackData)->OrientationTracker_fx != NULL) - { - free((*hHeadTrackData)->OrientationTracker_fx); - (*hHeadTrackData)->OrientationTracker_fx = NULL; - } -#endif - free( ( *hHeadTrackData ) ); *hHeadTrackData = NULL; @@ -210,8 +198,8 @@ void ivas_headTrack_close( #ifdef IVAS_FLOAT_FIXED void QuatToRotMat_fx( - const IVAS_QUATERNION_FX quat, /* i : quaternion describing the rotation Qx */ - Word32 Rmat[3][3] /* o : real-space rotation matrix for this rotation 2*Qx-32 */ + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation Qx */ + Word32 Rmat[3][3] /* o : real-space rotation matrix for this rotation 2*Qx-32 */ ) { Word32 w = quat.w_fx; @@ -225,7 +213,7 @@ void QuatToRotMat_fx( // Adding a guard bit to squared terms since 2*x is not being done in those // statements (R[0][0], R[1][1], R[2][2]). This is done to avoid L_shl. - Word32 ww = L_shr( Mpy_32_32( w, w ), 1 ); // 2 * Qx - 31 - 1 = 2*Qx-32 + Word32 ww = L_shr( Mpy_32_32( w, w ), 1 ); // 2 * Qx - 31 - 1 = 2*Qx-32 move32(); Word32 xx = L_shr( Mpy_32_32( x, x ), 1 ); move32(); @@ -347,7 +335,7 @@ float deg2rad( * * Converts normalized radians to degrees *------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED float rad2deg( float radians ) { @@ -362,7 +350,23 @@ float rad2deg( return _180_OVER_PI * radians; } +#else +Word32 rad2deg_fx( + Word32 radians ) +{ + while ( radians >= EVS_PI_FX ) + { + radians = radians - EVS_PI_FX; + } + while ( radians <= -EVS_PI_FX ) + { + radians = radians + EVS_PI_FX; + } + + return ( radians * _180_OVER_PI_FX ); +} +#endif #ifdef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * rotateAziEle() @@ -487,7 +491,7 @@ void rotateAziEle_fixed( const Word16 isPlanar /* i : is rotation planar and elevation meaningless? */ ) { - Word16 n,radian,temp_16; + Word16 n, radian, temp_16; Word32 dv_fx[3], dv_r_fx[3]; Word32 w_fx; Word32 temp; @@ -517,13 +521,13 @@ void rotateAziEle_fixed( /*Conversion cartesian to spherical coordinates*/ y = dv_r_fx[1]; x = dv_r_fx[0]; - radian = BASOP_util_atan2( y , x, 0 );//Q13 - - angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1);//Q22 + radian = BASOP_util_atan2( y, x, 0 ); // Q13 + angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 - *azi = (Word32) ( max( L_shl(-180,22), min( L_shl(180,22), angle ) ) );//Q22 - if ( abs(*azi)<=ONE_IN_Q22 ) + + *azi = (Word32) ( max( L_shl( -180, 22 ), min( L_shl( 180, 22 ), angle ) ) ); // Q22 + if ( abs( *azi ) <= ONE_IN_Q22 ) { *azi = 0; } @@ -532,9 +536,9 @@ void rotateAziEle_fixed( sqrt_fx = L_Frac_sqrtQ31( L_add( Mpy_32_32( dv_r_fx[0], dv_r_fx[0] ), Mpy_32_32( dv_r_fx[1], dv_r_fx[1] ) ) ); y = dv_r_fx[2]; x = sqrt_fx; - radian = BASOP_util_atan2( y , x ,0); - - angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 );//Q22 + radian = BASOP_util_atan2( y, x, 0 ); + + angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 *ele = (Word32) ( max( L_shl( -90, 22 ), min( L_shl( 90, 22 ), angle ) ) ); // Q22 @@ -581,7 +585,7 @@ void rotateAziEle( { dv_r[n] = Rmat[n][0] * dv[0] + Rmat[n][1] * dv[1] + Rmat[n][2] * dv[2]; } - float inter,inter1,inter2; + float inter, inter1, inter2; inter = atan2f( dv_r[1], dv_r[0] ); inter1 = min( 180.0f, atan2f( dv_r[1], dv_r[0] ) * _180_OVER_PI ); inter2 = max( -180.0f, min( 180.0f, atan2f( dv_r[1], dv_r[0] ) * _180_OVER_PI ) ); @@ -626,7 +630,7 @@ void rotateFrame_shd( Word32 cross_fade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; shd_rot_max_order = hTransSetup.ambisonics_order; - SWITCH( subframe_len ) + SWITCH( subframe_len ) { case L_SUBFRAME_48k: tmp = Q31_BY_SUB_FRAME_240; @@ -649,10 +653,10 @@ void rotateFrame_shd( cross_fade[i] = UL_Mpy_32_32( i, tmp ); } /* initialize rotation matrices with zeros */ - FOR ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) + FOR( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { - set_val_Word16( SHrotmat_prev[i],0, HEADROT_SHMAT_DIM ); - set_val_Word16( SHrotmat[i],0, HEADROT_SHMAT_DIM ); + set_val_Word16( SHrotmat_prev[i], 0, HEADROT_SHMAT_DIM ); + set_val_Word16( SHrotmat[i], 0, HEADROT_SHMAT_DIM ); } /* calculate ambisonics rotation matrices for the previous and current frames */ @@ -660,7 +664,7 @@ void rotateFrame_shd( SHrotmatgen_fx( SHrotmat, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); - FOR ( i = 0; i < subframe_len; i++ ) + FOR( i = 0; i < subframe_len; i++ ) { /*As the rotation matrix becomes block diagonal in a SH basis, we can apply each angular-momentum block individually to save complexity. */ @@ -668,23 +672,23 @@ void rotateFrame_shd( /* loop over l blocks */ m1 = 1; m2 = 4; - FOR ( l = 1; l <= shd_rot_max_order; l++ ) + FOR( l = 1; l <= shd_rot_max_order; l++ ) { /* compute mtx-vector product for this l */ - FOR ( n = m1; n < m2; n++ ) + FOR( n = m1; n < m2; n++ ) { tmpRot[n - m1] = 0; - FOR ( m = m1; m < m2; m++ ) + FOR( m = m1; m < m2; m++ ) { /* crossfade with previous rotation gains */ - tmp = L_add(Mpy_32_32(Mpy_32_16_r(cross_fade[i] , SHrotmat[n][m]) , output[m][subframe_idx * subframe_len + i]) ,Mpy_32_32( Mpy_32_16_r(L_sub( ONE_IN_Q31 , cross_fade[i] ) , SHrotmat_prev[n][m] ), output[m][subframe_idx * subframe_len + i])); + tmp = L_add( Mpy_32_32( Mpy_32_16_r( cross_fade[i], SHrotmat[n][m] ), output[m][subframe_idx * subframe_len + i] ), Mpy_32_32( Mpy_32_16_r( L_sub( ONE_IN_Q31, cross_fade[i] ), SHrotmat_prev[n][m] ), output[m][subframe_idx * subframe_len + i] ) ); tmpRot[n - m1] = L_add( L_shl( tmp, 1 ), tmpRot[n - m1] ); } } /* write back the result */ - FOR ( n = m1; n < m2; n++ ) + FOR( n = m1; n < m2; n++ ) { output[n][subframe_idx * subframe_len + i] = (Word32) tmpRot[n - m1]; } @@ -710,7 +714,7 @@ void rotateFrame_shd( } /* move Rmat to Rmat_prev */ - FOR ( i = 0; i < 3; i++ ) + FOR( i = 0; i < 3; i++ ) { mvr2r_Word32( hCombinedOrientationData->Rmat_fx[subframe_idx][i], @@ -920,7 +924,7 @@ void rotateFrame_sd( /* output channel index without LFE */ ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; - gains_prev_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 + gains_prev_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 } } @@ -945,7 +949,7 @@ void rotateFrame_sd( /* output channel index without LFE */ ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; - gains_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 + gains_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 } } } @@ -961,7 +965,7 @@ void rotateFrame_sd( out_temp = output[ch_in][i]; Word32 temp = Mpy_32_32( Mpy_32_32( ( cross_fade_fx[j] ), gains_fx[ch_in][ch_out] ), out_temp ); Word32 temp1 = Mpy_32_32( Mpy_32_32( ( ONE_IN_Q31 - cross_fade_fx[j] ), gains_prev_fx[ch_in][ch_out] ), out_temp ); - output_tmp_fx[ch_out][i] = L_add( L_shl(L_add( temp, temp1 ),1), output_tmp_fx[ch_out][i] ); + output_tmp_fx[ch_out][i] = L_add( L_shl( L_add( temp, temp1 ), 1 ), output_tmp_fx[ch_out][i] ); } } } @@ -1430,13 +1434,13 @@ void rotateFrame_sd_cldfb( *------------------------------------------------------------------------*/ void rotateFrame_sd_cldfb_fixed( - Word32 Rmat_fx[3][3], /* i : real-space rotation matrix (Q30) */ + Word32 Rmat_fx[3][3], /* i : real-space rotation matrix (Q30) */ Word32 Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ Word32 Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ - const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ - const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - const int16_t nb_band /* i : number of CLDFB bands to process */ + const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const int16_t numTimeSlots, /* i : number of time slots to process */ + const int16_t nb_band /* i : number of CLDFB bands to process */ ) { int16_t iBlock, iBand, m, n; @@ -1465,11 +1469,11 @@ void rotateFrame_sd_cldfb_fixed( /* rotation of Euler angles */ FOR( n = 0; n < nInChannels; n++ ) { - //rotateAziEle( hOutputSetup->ls_azimuth[n], hOutputSetup->ls_elevation[n], &azimuth, &elevation, Rmat, isPlanar ); + // rotateAziEle( hOutputSetup->ls_azimuth[n], hOutputSetup->ls_elevation[n], &azimuth, &elevation, Rmat, isPlanar ); rotateAziEle_fx( (Word16) hOutputSetup->ls_azimuth[n], (Word16) hOutputSetup->ls_elevation[n], &azimuth, &elevation, Rmat_fx, isPlanar ); IF( hEFAPdata != NULL && ( hOutputSetup->ls_azimuth[n] != azimuth || hOutputSetup->ls_elevation[n] != elevation ) ) { - //efap_determine_gains( hEFAPdata, gains[n], azimuth, elevation, EFAP_MODE_EFAP ); + // efap_determine_gains( hEFAPdata, gains[n], azimuth, elevation, EFAP_MODE_EFAP ); efap_determine_gains_fixed( hEFAPdata, gains_fx[n], L_shl( azimuth, Q22 ), L_shl( elevation, Q22 ), EFAP_MODE_EFAP ); } ELSE @@ -2655,13 +2659,13 @@ void ivas_combined_orientation_update_index( #else void ivas_combined_orientation_update_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - const Word16 samples_rendered /* i : samples rendered since the last call */ + const Word16 samples_rendered /* i : samples rendered since the last call */ ) { Word16 exp, div_result; - IF ( hCombinedOrientationData != NULL ) + IF( hCombinedOrientationData != NULL ) { - IF ( EQ_16(hCombinedOrientationData->num_subframes, 1) ) + IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) ) { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; @@ -2669,9 +2673,9 @@ void ivas_combined_orientation_update_index( } ELSE { - hCombinedOrientationData->cur_subframe_samples_rendered = add(hCombinedOrientationData->cur_subframe_samples_rendered, samples_rendered); - div_result = BASOP_Util_Divide3216_Scale(hCombinedOrientationData->cur_subframe_samples_rendered, hCombinedOrientationData->subframe_size, &exp); - hCombinedOrientationData->subframe_idx = add(hCombinedOrientationData->subframe_idx, shl(div_result, exp + 1)); + hCombinedOrientationData->cur_subframe_samples_rendered = add( hCombinedOrientationData->cur_subframe_samples_rendered, samples_rendered ); + div_result = BASOP_Util_Divide3216_Scale( hCombinedOrientationData->cur_subframe_samples_rendered, hCombinedOrientationData->subframe_size, &exp ); + hCombinedOrientationData->subframe_idx = add( hCombinedOrientationData->subframe_idx, shl( div_result, exp + 1 ) ); hCombinedOrientationData->cur_subframe_samples_rendered = hCombinedOrientationData->cur_subframe_samples_rendered % hCombinedOrientationData->subframe_size; move16(); hCombinedOrientationData->subframe_idx = s_min( hCombinedOrientationData->subframe_idx, hCombinedOrientationData->num_subframes - 1 ); diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index e984eed05443521beb01938b83c0f48afe918d02..197364befc47a573cc51b096978a00b7ef295d17 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -38,6 +38,7 @@ #include "ivas_cnst.h" #include "prot.h" #include "wmc_auto.h" +#include "ivas_rom_com.h" /*------------------------------------------------------------------------- @@ -50,6 +51,13 @@ #define ER_SOUND_SPEED ( 343.0f ) #define ER_MIN_WALL_DIST ( 0.1f ) #define ER_EUCLIDEAN_SCALE ( 1.29246971E-26f ) +#ifdef IVAS_FLOAT_FIXED +#define ER_AIR_COEFF_FX ( Word32 )( 0.00137 * ONE_IN_Q31 ) // Q.31 +#define ER_SOUND_SPEED_FX ( Word32 )( 1 / 343.0 * ONE_IN_Q31 ) // 1/343.0f in Q1.31 +#define ER_MIN_WALL_DIST_FX ( Word32 )( 0.1 * ONE_IN_Q22 ) // Q.22 +#define ER_EUCLIDEAN_SCALE_FX ( 0x1 ) ////Q.22 +#define ER_RECIPROCAL_EUCLIDEAN_SCALE_FX ( 0x1 ) // Q.22 +#endif /*-----------------------------------------------------------------------------------------* @@ -58,7 +66,7 @@ * Function transfer the parameters from the reverb config handle to the shoebox * calibration data structure. *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void ivas_shoebox_config_init( shoebox_config_t *cal, RENDER_CONFIG_HANDLE hRenderConfig /* i : Renderer configuration handle */ @@ -84,6 +92,42 @@ void ivas_shoebox_config_init( return; } +#else + +void ivas_shoebox_config_init( + shoebox_config_t *cal, + RENDER_CONFIG_HANDLE hRenderConfig /* i : Renderer configuration handle */ +) +{ + UWord16 wall_idx; + + + cal->room_L_fx = hRenderConfig->roomAcoustics.dimensions.x_fx; // Q.22 + cal->room_W_fx = hRenderConfig->roomAcoustics.dimensions.y_fx; // Q.22 + cal->room_H_fx = hRenderConfig->roomAcoustics.dimensions.z_fx; // Q.22 + move32(); + move32(); + move32(); + + /* Absorption Coefficients */ + /* Convention: [Front wall, Back wall, Left wall, Right wall, Ceiling, Floor] */ + FOR( wall_idx = 0; wall_idx < 6; wall_idx++ ) + { + cal->abs_coeff_fx[wall_idx] = hRenderConfig->roomAcoustics.AbsCoeff_fx[wall_idx]; // Q2.30 + move32(); + } + + /* Listener position (only X and Y can be pos. or neg. ) */ + cal->list_orig_fx[0] = hRenderConfig->roomAcoustics.ListenerOrigin.x_fx; // Q.22 + cal->list_orig_fx[1] = hRenderConfig->roomAcoustics.ListenerOrigin.y_fx; // Q.22 + cal->list_orig_fx[2] = hRenderConfig->roomAcoustics.ListenerOrigin.z_fx; // Q.22 + move32(); + move32(); + move32(); + + return; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -92,7 +136,7 @@ void ivas_shoebox_config_init( * Function initializes the shoebox operating parameters by setting limits and defaults, * also contains the calibration structure. *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void ivas_shoebox_init( shoebox_obj_t *obj, shoebox_config_t *cal ) @@ -132,6 +176,63 @@ void ivas_shoebox_init( return; } +#else +void ivas_shoebox_init( + shoebox_obj_t *obj, + shoebox_config_t *cal ) +{ + uint16_t i; + + /* Add cal to obj struct */ + obj->cal = *cal; + move32(); + /* Add defaults */ + obj->max_bands = 1; + obj->MAX_SOURCES = ER_MAX_SOURCES; + obj->REF_ORDER = ER_REF_ORDER; + move16(); + move16(); + move16(); + move16(); + + /* Positions */ + + set_l( &obj->src_pos_fx[0], 0, 75U ); + set_l( &obj->src_dist_fx[0], 0, 25U ); + + FOR( i = 0; i < 3; i++ ) + { + obj->list_pos_fx[i] = cal->list_orig_fx[i]; // Q.22 + move32(); + } + + /* Pointer */ + obj->nSrc = 0; + move16(); + + /* Flags */ + obj->isCartesian = 1; + obj->isRelative = 1; + obj->isZHeight = 1; + obj->isRadians = 1; + move16(); + move16(); + move16(); + move16(); + + /* Params */ + obj->radius_fx = ER_RADIUS_FX; + obj->min_wall_dist_fx = ER_MIN_WALL_DIST_FX; + obj->soundspeed_fx = ER_SOUND_SPEED_FX; + obj->air_coeff_fx = ER_AIR_COEFF_FX; + move32(); + move32(); + move32(); + move32(); + + return; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -142,7 +243,7 @@ void ivas_shoebox_init( * by the surface parameters. If object is out of bounds, then new cartesian * coordinates are established to collapse the object position. *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void shoebox_bound( shoebox_obj_t *obj, float *out_pos ) @@ -197,6 +298,77 @@ static void shoebox_bound( return; } +#else +static void shoebox_bound_fx( + shoebox_obj_t *obj, + Word32 *out_pos ) +{ + Word32 out_tmp, out_tmp1; + Word32 i; + // assert( 0 ); + + out_tmp = L_sub( L_shr( obj->cal.room_L_fx, 1 ), obj->min_wall_dist_fx ); // Q.22 + out_tmp1 = L_add( L_shr( L_negate( obj->cal.room_L_fx ), 1 ), obj->min_wall_dist_fx ); // Q.22 + test(); + IF( GT_32( out_pos[0], out_tmp ) || LT_32( out_pos[0], out_tmp1 ) ) + { + test(); + IF( LT_32( out_pos[0], 0 ) ) + { + i = -1; + move32(); + } + ELSE + { + i = ( out_pos[0] > 0 ) ? ( (Word32) 1 ) : ( (Word32) 0 ); + test(); + move32(); + } + + out_pos[0] = ( out_tmp * ( i ) ); + } + + out_tmp = L_sub( L_shr( obj->cal.room_W_fx, 1 ), obj->min_wall_dist_fx ); // Q.22 + out_tmp1 = L_add( L_shr( L_negate( obj->cal.room_W_fx ), 1 ), obj->min_wall_dist_fx ); // Q.22 + + IF( GT_32( out_pos[1], out_tmp ) || LT_32( out_pos[1], out_tmp1 ) ) + { + IF( LT_32( out_pos[1], 0 ) ) + { + i = -1; + move32(); + } + ELSE + { + i = ( out_pos[1] > 0 ) ? ( (Word32) 1 ) : ( (Word32) 0 ); + test(); + move32(); + } + out_pos[1] = out_tmp * ( i ); + } + + out_tmp = L_sub( L_shr( obj->cal.room_H_fx, 1 ), obj->min_wall_dist_fx ); // Q.22 + out_tmp1 = L_add( L_shr( L_negate( obj->cal.room_H_fx ), 1 ), obj->min_wall_dist_fx ); // Q.22 + + IF( GT_32( out_pos[2], out_tmp ) || LT_32( out_pos[2], out_tmp1 ) ) + { + IF( LT_32( out_pos[2], 0 ) ) + { + i = -1; + move32(); + } + ELSE + { + i = ( out_pos[2] > 0 ) ? ( (Word32) 1 ) : ( (Word32) 0 ); + test(); + move32(); + } + out_pos[2] = out_tmp * ( i ); + } + + return; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -204,7 +376,7 @@ static void shoebox_bound( * * Transform relative spherical coordinate to 3D cartesian point *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void shoebox_get_coord( shoebox_obj_t *obj, float *fcnOutput_data, @@ -280,6 +452,99 @@ static void shoebox_get_coord( return; } +#else + + +static void shoebox_get_coord_fx( + shoebox_obj_t *obj, + Word32 *fcnOutput_data, + const Word32 src_pos_data[], + Word32 *tmp_pos, + Word32 out_tmp, + Word32 coord, + Word32 loop_ub, + Word32 k, + UWord16 isRelative ) +{ + Word32 tmp_data[3]; + Word32 rcoselev; + Word32 tmp_size_idx_1; + Word32 n; + // assert( 0 ); + tmp_size_idx_1 = 3; + move32(); + IF( EQ_16( obj->isCartesian, 0 ) ) + { + /* Convert Spherical to Cartesian */ +#if 0 + IF ( obj->isRadians == 0 ) + { + FOR ( n = 0; n < loop_ub; n++ ) + { + fcnOutput_data[n] = deg2rad( src_pos_data[k + n] ); // not needed //Reshma + } + } +#endif + tmp_data[2] = Mpy_32_32( fcnOutput_data[2], shoebox_sin_cos_tbl_fx[fcnOutput_data[1]][0] ); //.29 = .30 * .30 + move32(); + rcoselev = Mpy_32_32( fcnOutput_data[2], shoebox_sin_cos_tbl_fx[fcnOutput_data[1]][1] ); //.29 = .30 * .30 + tmp_data[0] = Mpy_32_32( rcoselev, shoebox_sin_cos_tbl_fx[fcnOutput_data[0]][1] ); // .28 =.29*.30 + move32(); + tmp_data[1] = Mpy_32_32( rcoselev, shoebox_sin_cos_tbl_fx[fcnOutput_data[0]][0] ); // .28 = .29*.30 + move32(); + tmp_data[0] = L_shr( tmp_data[0], 6 ); + move32(); + tmp_data[1] = L_shr( tmp_data[1], 6 ); + move32(); + tmp_data[2] = L_shr( tmp_data[2], 7 ); + move32(); + } + ELSE + { + /* CARTESIAN CASE */ + tmp_size_idx_1 = loop_ub; + FOR( n = 0; n < loop_ub; n++ ) + { + tmp_data[n] = src_pos_data[k + n]; + move32(); + } + IF( NE_16( obj->isZHeight, 0 ) ) + { + /* FIX Z COORDINATE */ + tmp_data[2] = L_sub( src_pos_data[k + 2], L_shr( obj->cal.room_H_fx, 1 ) ); + } + } + + FOR( k = 0; k < tmp_size_idx_1; k++ ) + { + obj->src_pos_fx[( coord + k ) - 1] = tmp_data[k]; //.22 + move32(); + } + + /* CENTER TO LISTENER */ + + k = ( out_tmp + 1 ); + + + tmp_pos[0] = obj->src_pos_fx[k - 1]; //.22 + tmp_pos[1] = obj->src_pos_fx[k]; + tmp_pos[2] = obj->src_pos_fx[k + 1]; + move32(); + move32(); + move32(); + + IF( NE_16( isRelative, 0 ) ) + { + tmp_pos[0] = L_add( tmp_pos[0], obj->list_pos_fx[0] ); //.22 + tmp_pos[1] = L_add( tmp_pos[1], obj->list_pos_fx[1] ); + tmp_pos[2] = L_add( tmp_pos[2], obj->list_pos_fx[2] ); + } + + return; +} + + +#endif /*-----------------------------------------------------------------------------------------* @@ -287,7 +552,7 @@ static void shoebox_get_coord( * * Get 3D source distance from receiver *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static float shoebox_get_euclidian_distance_internal( shoebox_obj_t *obj, float *tmp_pos, @@ -338,6 +603,96 @@ static float shoebox_get_euclidian_distance_internal( return out_tmp; } +#else +static Word32 shoebox_get_euclidian_distance_internal_fx( + shoebox_obj_t *obj, + Word32 *tmp_pos, + Word32 *scale ) +{ + Word32 absxk, out_tmp, t; + Word16 q; + + // assert( 0 ); + + absxk = L_abs( L_sub( obj->list_pos_fx[0], tmp_pos[0] ) ); // Q.22-Q22 + + IF( GT_32( absxk, ER_EUCLIDEAN_SCALE_FX ) ) + { + out_tmp = ONE_IN_Q22; // 1 in Q22 + *scale = absxk; // Q22 + move32(); + move32(); + } + ELSE + { + t = absxk * ER_RECIPROCAL_EUCLIDEAN_SCALE_FX; // Q22 + out_tmp = Mpy_32_32( t, t ); // Q13 + out_tmp = L_shl( out_tmp, 9 ); // Q22 + } + + absxk = L_abs( L_sub( obj->list_pos_fx[1], tmp_pos[1] ) ); + + IF( GT_32( absxk, *scale ) ) + { + q = Q22; + move16(); + t = (Word32) BASOP_Util_Divide3232_Scale( *scale, absxk, &q ); + q = sub( Q22, sub( Q15, q ) ); + t = L_shl( t, q ); + + out_tmp = Mpy_32_32( out_tmp, t ); // Q13 + out_tmp = L_shl( out_tmp, 9 ); + out_tmp = Mpy_32_32( out_tmp, t ); // Q13 + out_tmp = L_add( L_shl( out_tmp, 9 ), ONE_IN_Q22 ); //.22 + *scale = absxk; // Q.22 + move32(); + } + ELSE + { + q = Q22; + move16(); + t = (Word32) BASOP_Util_Divide3232_Scale( absxk, *scale, &q ); + q = sub( Q22, sub( Q15, q ) ); + t = L_shl( t, q ); + t = Mpy_32_32( t, t ); // Q.13 + t = L_shl( t, 9 ); + out_tmp = L_add( out_tmp, t ); //.22 + move32(); + } + + absxk = L_abs( L_sub( obj->list_pos_fx[2], tmp_pos[2] ) ); + + IF( GE_32( absxk, *scale ) ) + { + q = Q22; + move16(); + t = (Word32) BASOP_Util_Divide3232_Scale( *scale, absxk, &q ); + q = sub( Q22, sub( Q15, q ) ); + t = L_shl( t, q ); + + out_tmp = Mpy_32_32( out_tmp, t ); // Q13 + out_tmp = L_shl( out_tmp, 9 ); + out_tmp = Mpy_32_32( out_tmp, t ); // Q13 + out_tmp = L_add( L_shl( out_tmp, 9 ), ONE_IN_Q22 ); //.22 + *scale = absxk; // Q.22 + move32(); + } + ELSE + { + q = Q22; + move16(); + t = (Word32) BASOP_Util_Divide3232_Scale( absxk, *scale, &q ); + q = sub( Q22, sub( Q15, q ) ); + t = L_shl( t, q ); // Q22 + t = Mpy_32_32( t, t ); // Q.13 + t = L_shl( t, 9 ); + out_tmp = L_add( out_tmp, t ); //.22 + } + + return out_tmp; +} + +#endif /*-----------------------------------------------------------------------------------------* @@ -345,6 +700,7 @@ static float shoebox_get_euclidian_distance_internal( * * Initial scene setup returning computed reflection (arrival times, DOA and gain). *-----------------------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void ivas_shoebox_set_scene( shoebox_obj_t *obj, @@ -489,3 +845,230 @@ void ivas_shoebox_set_scene( return; } +#else + +void ivas_shoebox_set_scene( + shoebox_obj_t *obj, + shoebox_output_t *ER_PARAMS, + const Word32 list_pos_fx[3], + const Word32 src_pos_data[], + const uint16_t isCartesian, + const uint16_t isRelative ) +{ + + Word32 tmp_pos_fx[3]; + Word32 out_tmp; + Word32 i, j, k, n; + Word32 loop_ub, out_tmp_fx; + Word16 q_format1, q_format; + + /* ------------- SET FLAGS ------------- */ + obj->isCartesian = isCartesian; + obj->isRelative = isRelative; + move16(); + move16(); + /* ------------- CHECK DIMENSIONS ------------- */ + if ( GE_16(ER_PARAMS->n_sources , obj->MAX_SOURCES) ) + { + obj->nSrc = obj->MAX_SOURCES; + } + else + { + obj->nSrc = ER_PARAMS->n_sources; + } + move16(); + + set_l( &obj->src_pos_fx[0], 0, 75U ); + + obj->list_pos_fx[0] = list_pos_fx[0]; + obj->list_pos_fx[1] = list_pos_fx[1]; + obj->list_pos_fx[2] = list_pos_fx[2]; + move32(); + move32(); + move32(); + /* ---------- ADJUST LISTENER ------------- */ + IF( NE_16(obj->isZHeight , 0) ) + { + obj->list_pos_fx[2] = L_sub(list_pos_fx[2] , L_shr( obj->cal.room_H_fx , 1 )); // Q.22 + } + tmp_pos_fx[1] = obj->list_pos_fx[1]; + tmp_pos_fx[2] = obj->list_pos_fx[2]; + move32(); + move32(); + + shoebox_bound_fx( obj, obj->list_pos_fx ); + + + /* ---------- SOURCE LOOP ------------- */ + i = (Word32) obj->nSrc; + move32(); + FOR ( j = 0; j < i; j++ ) + { + Word32 fcnOutput_data_fx[3], scale_fx; + Word32 rcoselev; + Word32 coord; + + /* idx = single(i); */ + out_tmp = 3 * j; + /* GET COORDINATE IN CARTESIAN ABSOLUTE FORMAT */ + k = out_tmp; + move32(); + n = L_add(out_tmp, 3); + coord = L_add(out_tmp , 1); + + loop_ub =L_sub( n , k); + + FOR( n = 0; n < loop_ub; n++ ) + { + fcnOutput_data_fx[n] = src_pos_data[k + n]; + move32(); + } + + shoebox_get_coord_fx( obj, fcnOutput_data_fx, src_pos_data, tmp_pos_fx, out_tmp, coord, loop_ub, k, isRelative ); + shoebox_bound_fx( obj, tmp_pos_fx ); + + scale_fx = ER_EUCLIDEAN_SCALE_FX; + move32(); + out_tmp_fx = shoebox_get_euclidian_distance_internal_fx( obj, tmp_pos_fx, &scale_fx ); + q_format = sub(Q31, Q22); + out_tmp_fx = Sqrt32( out_tmp_fx, &q_format ); + out_tmp_fx = Mpy_32_32( scale_fx, out_tmp_fx ); + obj->src_dist_fx[j] = L_shl( out_tmp_fx, q_format ); // Q22 + move32(); + + + /* COMPUTE PATTERNS */ + + /* SHOEBOX_COMPUTE: fills an input structure (4 array fields of length NxR ) with the */ + /* Early reflection metadata (time of arrival, gain, az, el). */ + /* */ + /* Input: */ + /* 1. obj : Module data holder */ + /* 2. ER_struct : Early reflection structure */ + /* 3. src_num : Index of source to compute patterns for */ + /* ------ */ + out_tmp_fx = obj->src_dist_fx[j]; + move32(); + + FOR ( loop_ub = 0; loop_ub < 6; loop_ub++ ) + { + + Word32 im_pos_fx[3]; + Word32 path_dist_fx; + Word32 asin_val; + Word32 sub_im_nd_list_pos_1, sub_im_nd_list_pos_0, atan_pos, az_angle_d; + Word32 one_minus_abs_coeff, out_tmp_div_path_dist, product, pro_pd_air_coeff, result_gain; + Word32 sub_im_nd_list_div_path, one_minus_sub_im_nd_list_div_path_sq, sub_im_nd_list_div_path_sq, one_minus_sub_im_nd_list_div_path_sq_rt, asin_val_deg; + Word16 q_format_n; + + /* Retrieve coordinate and surface sign */ + coord = L_shr(loop_ub , 1); // tbl + rcoselev = L_add(L_add( loop_ub , 1 ) , ( ER_PARAMS->n_ref * j )); + + /* Initialize image position coordinates */ + im_pos_fx[0] = tmp_pos_fx[0]; // Q:22 + im_pos_fx[1] = tmp_pos_fx[1]; + im_pos_fx[2] = tmp_pos_fx[2]; + move32(); + move32(); + move32(); + + /* Calculate image projection coordinate based on current surface axis */ + IF( LT_32(L_add( loop_ub , 1 ) , 3) ) + { + scale_fx = obj->cal.room_L_fx; // Q:22 + move32(); + } + ELSE IF( LT_32(L_add( loop_ub , 1 ) , 5 )) + { + scale_fx = obj->cal.room_W_fx; // Q:22 + move32(); + } + ELSE + { + scale_fx = obj->cal.room_H_fx; // Q:22 + move32(); + } + + + im_pos_fx[coord] = + tmp_pos_fx[coord] + + ( ( ( ( ( -( 1 - ( ( ( loop_ub + 1 ) & 1 ) << 1 ) ) ) * scale_fx ) >> 1 ) - tmp_pos_fx[coord] ) << 1 ); // Q:22 + + /* 0. Get euclidean distance from IMAGE SOURCE [N,W] to LIST */ + scale_fx = ER_EUCLIDEAN_SCALE_FX; // Q:22 + move32(); + path_dist_fx = shoebox_get_euclidian_distance_internal_fx( obj, im_pos_fx, &scale_fx ); // Uutput :Q:22 + + q_format =sub(Q31, Q22); + path_dist_fx = Sqrt32( path_dist_fx, &q_format ); // Input: Q:22, Output : Q.30 + + path_dist_fx = Mpy_32_32( scale_fx, path_dist_fx ); // Q22 * Q = Q + path_dist_fx = L_shl( path_dist_fx, q_format ); + + + /* 1. Compute time-of arrival (TOA) */ + ER_PARAMS->times.data_fx[rcoselev - 1] = Mpy_32_32( path_dist_fx, obj->soundspeed_fx ); // Q.22 + + /* 2./3. DOA */ + sub_im_nd_list_pos_1 = L_sub(im_pos_fx[1] , obj->list_pos_fx[1]); // Q.22 + sub_im_nd_list_pos_0 = L_sub(im_pos_fx[0] , obj->list_pos_fx[0]); // Q.22 + q_format = sub(Q22, Q22); + atan_pos = BASOP_util_atan2( sub_im_nd_list_pos_1, sub_im_nd_list_pos_0, q_format ); // Q.13 + az_angle_d = rad2deg_fx( atan_pos ); // Q.23 + ER_PARAMS->az_angle.data_fx[rcoselev - 1] = az_angle_d; + move32(); + + + q_format = Q22; + move16(); + sub_im_nd_list_div_path = BASOP_Util_Divide3232_Scale( ( im_pos_fx[2] - obj->list_pos_fx[2] ), path_dist_fx, &q_format ); + sub_im_nd_list_div_path = L_shl( sub_im_nd_list_div_path, q_format ); + sub_im_nd_list_div_path = L_deposit_h( (Word16) sub_im_nd_list_div_path ); + sub_im_nd_list_div_path_sq = Mpy_32_32( sub_im_nd_list_div_path, sub_im_nd_list_div_path ); + sub_im_nd_list_div_path_sq = L_shr( sub_im_nd_list_div_path_sq, 1 ); + one_minus_sub_im_nd_list_div_path_sq = L_sub( L_shl( 1, Q30 ), sub_im_nd_list_div_path_sq ); + q_format1 = sub(Q31, Q30); + + one_minus_sub_im_nd_list_div_path_sq_rt = Sqrt32( one_minus_sub_im_nd_list_div_path_sq, &q_format1 ); + one_minus_sub_im_nd_list_div_path_sq_rt = L_shl( one_minus_sub_im_nd_list_div_path_sq_rt, q_format1 ); + + + q_format_n = sub(Q31, Q31); + asin_val = BASOP_util_atan2( sub_im_nd_list_div_path, one_minus_sub_im_nd_list_div_path_sq_rt, q_format_n ); // Q13 + + asin_val_deg = rad2deg_fx( asin_val ); // Q.23 + ER_PARAMS->el_angle.data_fx[rcoselev - 1] = asin_val_deg; + move32(); + + + /* 4. Compute gain taking into account air and surface absorption */ + /* and propagation loss */ + if ( LT_32(path_dist_fx , out_tmp_fx )) + { + path_dist_fx = out_tmp_fx; + move32(); + } + + one_minus_abs_coeff = L_sub( ( ONE_IN_Q30 ), obj->cal.abs_coeff_fx[loop_ub] ); // Q30=Q30-Q30 + q_format_n = Q22; + move16(); + out_tmp_div_path_dist = BASOP_Util_Divide3232_Scale( out_tmp_fx, path_dist_fx, &q_format_n ); // Q22/Q.22 + product = Mpy_32_32( one_minus_abs_coeff, out_tmp_div_path_dist ); // Q.30 *Q.15 + product = L_shl( product, q_format_n ); // Q14 + product = L_shl( product, Q8 ); // Q22 + + pro_pd_air_coeff = Mpy_32_32( path_dist_fx, obj->air_coeff_fx ); // Q.22 *Q.31 =Q.22 + result_gain =L_sub( product , pro_pd_air_coeff); + ER_PARAMS->gains.data_fx[rcoselev - 1] = result_gain; + + + ER_PARAMS->times.data[( (int32_t) rcoselev ) - 1] = (float) ER_PARAMS->times.data_fx[( (int32_t) rcoselev ) - 1] / 4194304.0; + ER_PARAMS->az_angle.data[( (int32_t) rcoselev ) - 1] = (float) ER_PARAMS->az_angle.data_fx[( (int32_t) rcoselev ) - 1] / 8388608.0; + ER_PARAMS->el_angle.data[( (int32_t) rcoselev ) - 1] = (float) ER_PARAMS->el_angle.data_fx[( (int32_t) rcoselev ) - 1] / 8388608.0; + // ER_PARAMS->gains.data[( (int32_t) rcoselev ) - 1] = (float) ER_PARAMS->gains.data_fx[( (int32_t) rcoselev ) - 1] / 4194304.0; + } + } + return; +} +#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 8d1c7808f314bed003fd91a6464edaadc83ccce3..2b97c75e66fb4b3a2d97a1cd4f1b5d4d541af8fb 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -906,26 +906,16 @@ typedef struct ivas_orient_trk_state_t IVAS_QUATERNION refRot; /* reference orientation */ IVAS_QUATERNION trkRot; /* tracked rotation */ -} ivas_orient_trk_state_t; - #ifdef IVAS_FLOAT_FIXED - -typedef struct ivas_orient_trk_state_t_fx -{ - IVAS_HEAD_ORIENT_TRK_T orientation_tracking_fx; Word32 centerAdaptationRate_fx; Word32 offCenterAdaptationRate_fx; Word32 adaptationAngle_fx; Word32 alpha_fx; - IVAS_QUATERNION_FX absAvgRot_fx; /* average absolute orientation */ - IVAS_QUATERNION_FX refRot_fx; /* reference orientation */ - IVAS_QUATERNION_FX trkRot_fx; /* tracked rotation */ - -} ivas_orient_trk_state_t_fx; - #endif +} ivas_orient_trk_state_t; + /*----------------------------------------------------------------------------------* * Head rotation data structure *----------------------------------------------------------------------------------*/ @@ -937,7 +927,6 @@ typedef struct IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; #ifdef IVAS_FLOAT_FIXED Word32 crossfade_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - ivas_orient_trk_state_t_fx *hOrientationTracker_fx; #endif float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; ivas_orient_trk_state_t *hOrientationTracker; @@ -970,9 +959,6 @@ typedef struct ivas_binaural_head_track_struct int16_t shd_rot_max_order; ivas_orient_trk_state_t *OrientationTracker; -#ifdef IVAS_FLOAT_FIXED - ivas_orient_trk_state_t_fx *OrientationTracker_fx; -#endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; @@ -988,7 +974,7 @@ typedef struct ivas_external_orientation_struct int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ #ifdef IVAS_FLOAT_FIXED - IVAS_QUATERNION_FX Quaternions_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ + IVAS_QUATERNION Quaternions_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ #endif int16_t num_subframes; @@ -1009,7 +995,7 @@ typedef struct ivas_combined_orientation_struct float lrSwitchInterpVal; bool isInterpolationOngoing; IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; - IVAS_QUATERNION_FX Quaternions_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION Quaternions_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternion_prev_extOrientation; IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; @@ -1021,7 +1007,7 @@ typedef struct ivas_combined_orientation_struct float procChEneIIR[2][MASA_FREQUENCY_BANDS]; Word16 shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; - IVAS_VECTOR3_FX listenerPos_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 listenerPos_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; Word8 isExtOrientationFrozen; @@ -1249,11 +1235,11 @@ typedef struct float abs_coeff[IVAS_ROOM_ABS_COEFF]; float list_orig[3]; - Word16 room_L_fx; - Word16 room_W_fx; - Word16 room_H_fx; - Word16 abs_coeff_fx[IVAS_ROOM_ABS_COEFF]; - Word16 list_orig_fx[3]; + Word32 room_L_fx; + Word32 room_W_fx; + Word32 room_H_fx; + Word32 abs_coeff_fx[IVAS_ROOM_ABS_COEFF]; + Word32 list_orig_fx[3]; } shoebox_config_t; /* Structure to hold the corrected( bounded ) source and listener positions */ @@ -1286,22 +1272,17 @@ typedef struct shoebox_config_t cal; } shoebox_obj_t; -#ifdef IVAS_FLOAT_FIXED + typedef struct shoebox_data_t { float data[150]; +#ifdef IVAS_FLOAT_FIXED Word32 data_fx[150]; +#endif Word32 size[1]; } shoebox_data_t; -#else -typedef struct shoebox_data_t -{ - float data[150]; - int32_t size[1]; -} shoebox_data_t; -#endif typedef struct { uint16_t n_sources; @@ -1336,8 +1317,8 @@ typedef struct er_struct_t UWord32 max_frame_size; #ifdef IVAS_FLOAT_FIXED Word32 output_Fs_fx; - Word16 source_positions_fx[75]; - Word16 user_origin_fx[3]; + Word32 source_positions_fx[75]; + Word32 user_origin_fx[3]; //is not needed #endif float output_Fs; float source_positions[75]; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6ceed8018cb855fd9344f31cc4b27fe0acf6cf54..568df256b9c65d26ca6682f391d32e65abaee7ef 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1770,11 +1770,6 @@ static ivas_error initHeadRotation( } #ifdef IVAS_FLOAT_FIXED - IF( ( hIvasRend->headRotData.hOrientationTracker_fx = (ivas_orient_trk_state_t_fx *) malloc( sizeof( ivas_orient_trk_state_t_fx ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Orientation tracking" ); - } - IF( ( error = ivas_orient_trk_Init_fx( hIvasRend->headRotData.hOrientationTracker ) ) != IVAS_ERR_OK ) { return error; @@ -1835,13 +1830,6 @@ static void closeHeadRotation( free( hIvasRend->headRotData.hOrientationTracker ); } -#ifdef IVAS_FLOAT_FIXED - if ( ( hIvasRend != NULL ) && ( hIvasRend->headRotData.hOrientationTracker_fx != NULL ) ) - { - free( hIvasRend->headRotData.hOrientationTracker_fx ); - } -#endif - return; } @@ -6127,8 +6115,7 @@ ivas_error IVAS_REND_SetOrientationTrackingMode( { #ifdef IVAS_FLOAT_FIXED ivas_error ret; - ret = ivas_orient_trk_SetTrackingType_fx( hIvasRend->headRotData.hOrientationTracker_fx, orientation_tracking ); - hIvasRend->headRotData.hOrientationTracker->orientation_tracking = hIvasRend->headRotData.hOrientationTracker_fx->orientation_tracking_fx; + ret = ivas_orient_trk_SetTrackingType_fx( hIvasRend->headRotData.hOrientationTracker, orientation_tracking ); return ret; #else return ivas_orient_trk_SetTrackingType( hIvasRend->headRotData.hOrientationTracker, orientation_tracking ); @@ -6157,17 +6144,17 @@ ivas_error IVAS_REND_SetReferenceRotation( #ifdef IVAS_FLOAT_FIXED - IVAS_QUATERNION_FX refRot_fx; + IVAS_QUATERNION refRot_fx; refRot_fx.w_qfact = refRot_fx.x_qfact = refRot_fx.y_qfact = refRot_fx.z_qfact = Q29; refRot_fx.w_fx = (Word32) float_to_fix( refRot.w, refRot_fx.w_qfact ); refRot_fx.x_fx = (Word32) float_to_fix( refRot.x, refRot_fx.x_qfact ); refRot_fx.y_fx = (Word32) float_to_fix( refRot.y, refRot_fx.y_qfact ); refRot_fx.z_fx = (Word32) float_to_fix( refRot.z, refRot_fx.z_qfact ); - error = ivas_orient_trk_SetReferenceRotation_fx( hIvasRend->headRotData.hOrientationTracker_fx, refRot_fx ); - hIvasRend->headRotData.hOrientationTracker->refRot.w = me2f( hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.w_fx, 31 - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.w_qfact ); - hIvasRend->headRotData.hOrientationTracker->refRot.x = me2f( hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.x_fx, 31 - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.x_qfact ); - hIvasRend->headRotData.hOrientationTracker->refRot.y = me2f( hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.y_fx, 31 - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.y_qfact ); - hIvasRend->headRotData.hOrientationTracker->refRot.z = me2f( hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.z_fx, 31 - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.z_qfact ); + error = ivas_orient_trk_SetReferenceRotation_fx( hIvasRend->headRotData.hOrientationTracker, refRot_fx ); + hIvasRend->headRotData.hOrientationTracker->refRot.w = me2f( hIvasRend->headRotData.hOrientationTracker->refRot.w_fx, 31 - hIvasRend->headRotData.hOrientationTracker->refRot.w_qfact ); + hIvasRend->headRotData.hOrientationTracker->refRot.x = me2f( hIvasRend->headRotData.hOrientationTracker->refRot.x_fx, 31 - hIvasRend->headRotData.hOrientationTracker->refRot.x_qfact ); + hIvasRend->headRotData.hOrientationTracker->refRot.y = me2f( hIvasRend->headRotData.hOrientationTracker->refRot.y_fx, 31 - hIvasRend->headRotData.hOrientationTracker->refRot.y_qfact ); + hIvasRend->headRotData.hOrientationTracker->refRot.z = me2f( hIvasRend->headRotData.hOrientationTracker->refRot.z_fx, 31 - hIvasRend->headRotData.hOrientationTracker->refRot.z_qfact ); if ( error != IVAS_ERR_OK ) { @@ -6204,28 +6191,26 @@ ivas_error IVAS_REND_GetMainOrientation( } #ifdef IVAS_FLOAT_FIXED - IVAS_QUATERNION_FX *pOrientation_fx = malloc( sizeof( IVAS_QUATERNION_FX ) ); - Word16 q_fact = hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.w_qfact = hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.x_qfact = - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.y_qfact = hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.z_qfact = Q29; - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.w, q_fact ); - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.x, q_fact ); - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.y, q_fact ); - hIvasRend->headRotData.hOrientationTracker_fx->refRot_fx.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.z, q_fact ); - - - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.w, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.x, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.y, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.z, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.w_qfact = hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.x_qfact = - hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.y_qfact = hIvasRend->headRotData.hOrientationTracker_fx->absAvgRot_fx.z_qfact = Q29; - - error = ivas_orient_trk_GetMainOrientation_fx( hIvasRend->headRotData.hOrientationTracker_fx, pOrientation_fx ); - pOrientation->w = fix_to_float( pOrientation_fx->w_fx, pOrientation_fx->w_qfact ); - pOrientation->x = fix_to_float( pOrientation_fx->x_fx, pOrientation_fx->x_qfact ); - pOrientation->y = fix_to_float( pOrientation_fx->y_fx, pOrientation_fx->y_qfact ); - pOrientation->z = fix_to_float( pOrientation_fx->z_fx, pOrientation_fx->z_qfact ); - free( pOrientation_fx ); + Word16 q_fact = hIvasRend->headRotData.hOrientationTracker->refRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->refRot.x_qfact = + hIvasRend->headRotData.hOrientationTracker->refRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->refRot.z_qfact = Q29; + hIvasRend->headRotData.hOrientationTracker->refRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.w, q_fact ); + hIvasRend->headRotData.hOrientationTracker->refRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.x, q_fact ); + hIvasRend->headRotData.hOrientationTracker->refRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.y, q_fact ); + hIvasRend->headRotData.hOrientationTracker->refRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->refRot.z, q_fact ); + + + hIvasRend->headRotData.hOrientationTracker->absAvgRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.w, Q29 ); + hIvasRend->headRotData.hOrientationTracker->absAvgRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.x, Q29 ); + hIvasRend->headRotData.hOrientationTracker->absAvgRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.y, Q29 ); + hIvasRend->headRotData.hOrientationTracker->absAvgRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->absAvgRot.z, Q29 ); + hIvasRend->headRotData.hOrientationTracker->absAvgRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->absAvgRot.x_qfact = + hIvasRend->headRotData.hOrientationTracker->absAvgRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->absAvgRot.z_qfact = Q29; + + error = ivas_orient_trk_GetMainOrientation_fx( hIvasRend->headRotData.hOrientationTracker, pOrientation ); + pOrientation->w = fix_to_float( pOrientation->w_fx, pOrientation->w_qfact ); + pOrientation->x = fix_to_float( pOrientation->x_fx, pOrientation->x_qfact ); + pOrientation->y = fix_to_float( pOrientation->y_fx, pOrientation->y_qfact ); + pOrientation->z = fix_to_float( pOrientation->z_fx, pOrientation->z_qfact ); IF( error != IVAS_ERR_OK ) { return error; @@ -6260,19 +6245,17 @@ ivas_error IVAS_REND_GetTrackedRotation( } #ifdef IVAS_FLOAT_FIXED - IVAS_QUATERNION_FX *pRotation_fx = malloc( sizeof( IVAS_QUATERNION_FX ) ); - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.w, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.x, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.y, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.z, Q29 ); - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.w_qfact = hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.x_qfact = - hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.y_qfact = hIvasRend->headRotData.hOrientationTracker_fx->trkRot_fx.z_qfact = Q29; - error = ivas_orient_trk_GetTrackedRotation_fx( hIvasRend->headRotData.hOrientationTracker_fx, pRotation_fx ); - pRotation->w = fix_to_float( pRotation_fx->w_fx, pRotation_fx->w_qfact ); - pRotation->x = fix_to_float( pRotation_fx->x_fx, pRotation_fx->x_qfact ); - pRotation->y = fix_to_float( pRotation_fx->y_fx, pRotation_fx->y_qfact ); - pRotation->z = fix_to_float( pRotation_fx->z_fx, pRotation_fx->z_qfact ); - free( pRotation_fx ); + hIvasRend->headRotData.hOrientationTracker->trkRot.w_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.w, Q29 ); + hIvasRend->headRotData.hOrientationTracker->trkRot.x_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.x, Q29 ); + hIvasRend->headRotData.hOrientationTracker->trkRot.y_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.y, Q29 ); + hIvasRend->headRotData.hOrientationTracker->trkRot.z_fx = (Word32) float_to_fix( hIvasRend->headRotData.hOrientationTracker->trkRot.z, Q29 ); + hIvasRend->headRotData.hOrientationTracker->trkRot.w_qfact = hIvasRend->headRotData.hOrientationTracker->trkRot.x_qfact = + hIvasRend->headRotData.hOrientationTracker->trkRot.y_qfact = hIvasRend->headRotData.hOrientationTracker->trkRot.z_qfact = Q29; + error = ivas_orient_trk_GetTrackedRotation_fx( hIvasRend->headRotData.hOrientationTracker, pRotation ); + pRotation->w = fix_to_float( pRotation->w_fx, pRotation->w_qfact ); + pRotation->x = fix_to_float( pRotation->x_fx, pRotation->x_qfact ); + pRotation->y = fix_to_float( pRotation->y_fx, pRotation->y_qfact ); + pRotation->z = fix_to_float( pRotation->z_fx, pRotation->z_qfact ); IF( error != IVAS_ERR_OK ) { return error; @@ -10643,6 +10626,22 @@ static ivas_error ivas_masa_ext_rend_dirac_rend_init( if ( hDirACRend->proto_signal_decorr_on ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_dirac_dec_decorr_open_fx( &( hDirACRend->h_freq_domain_decorr_ap_params ), + &( hDirACRend->h_freq_domain_decorr_ap_state ), + hSpatParamRendCom->num_freq_bands, + hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, + hDirACRend->synthesisConf, + hDirACRend->frequency_axis, + nchan_transport, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + +#else + if ( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, @@ -10655,6 +10654,7 @@ static ivas_error ivas_masa_ext_rend_dirac_rend_init( { return error; } +#endif } /* output synthesis */ @@ -10821,9 +10821,21 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { frequency_axis[i] = frequency_axis_fx[i]; } + if ( ( error = ivas_dirac_dec_decorr_open_fx( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis, + BINAURAL_CHANNELS, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } #else ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); -#endif + if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), &( hDiracDecBin->h_freq_domain_decorr_ap_state ), nBins, @@ -10836,6 +10848,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { return error; } +#endif /* External renderer uses constant regularization factor */ hDiracDecBin->reqularizationFactor = 0.4f;