diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index d6dca84cae8e246c33bd03b0920e1a3d5a3d2bb2..f51c45ee2c6a8e8a78acc0398424acdae26b664a 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -315,6 +315,7 @@ + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index fc5e0663853eaeb4805b1759cfd53f0bc7894275..b9dbd7fd5a6304a0d47586693a0d781946e88a35 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -285,6 +285,7 @@ + diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools.c index 386951df678b9bd7f818caa6e240f48a46b336a3..bcd24fe1ff031b4805dd20d6466795f8a89a5905 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools.c @@ -39,7 +39,9 @@ #include "ivas_rom_com.h" #include "wmc_auto.h" #include "prot.h" - +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx1.h" +#endif /*---------------------------------------------------------------------* * eye_matrix() @@ -65,7 +67,28 @@ void eye_matrix( return; } - +#ifdef IVAS_FLOAT_FIXED +void eye_matrix_fx( + Word16 *mat, + const Word16 n, + const Word16 d) +{ + Word16 i; + + FOR(i = 0; i < n * n; i++) + { + mat[i] = 0; + move16(); + } + FOR(i = 0; i < n; i++) + { + mat[i * n + i] = d; + move16(); + } + + return; +} +#endif /*---------------------------------------------------------------------* * cov() * @@ -537,7 +560,63 @@ void dquat2mat( return; } +#ifdef IVAS_FLOAT_FIXED +void dquat2mat_fx( + const Word16 *ql, + const Word16 *qr, + Word16 *m ) +{ + Word16 a, b, c, d; + Word16 w, x, y, z; + Word16 aw, ax, ay, az; + Word16 bw, bx, by, bz; + Word16 cw, cx, cy, cz; + Word16 dw, dx, dy, dz; + + a = ql[0];move16(); + b = ql[1];move16(); + c = ql[2];move16(); + d = ql[3];move16(); + w = qr[0];move16(); + x = qr[1];move16(); + y = qr[2];move16(); + z = qr[3];move16(); + aw = mult( a, w ); // Ql + Qr - 15 + ax = mult( a, x ); + ay = mult( a, y ); + az = mult( a, z ); + bw = mult( b, w ); + bx = mult( b, x ); + by = mult( b, y ); + bz = mult( b, z ); + cw = mult( c, w ); + cx = mult( c, x ); + cy = mult( c, y ); + cz = mult( c, z ); + dw = mult( d, w ); + dx = mult( d, x ); + dy = mult( d, y ); + dz = mult( d, z ); + m[0] = sub( sub( aw, bx ), add( cy, dz ) ); + m[1] = sub( sub( cz, dy ), add( ax, bw ) ); + m[2] = add( sub( sub( -ay, bz ), cw ), dx ); + m[3] = sub( sub( by, az ), add( cx, dw ) ); + m[4] = add( sub( add( bw, ax ), dy ), cz ); + m[5] = add( add( add( -bx, aw ), dz ), cy ); + m[6] = sub( sub( add( -by, az ), dw ), cx ); + m[7] = add( sub( sub( -bz, ay ), dx ), cw ); + m[8] = sub( add( add( cw, dx ), ay ), bz ); + m[9] = sub( sub( add( -cx, dw ), az ), by ); + m[10] = add( add( add( -cy, dz ), aw ), bx ); + m[11] = sub( add( sub( -cz, dy ), ax ), bw ); + m[12] = add( add( sub( dw, cx ), by ), az ); + m[13] = add( sub( sub( -dx, cw ), bz ), ay ); + m[14] = sub( add( sub( -dy, cz ), bw ), ax ); + m[15] = add( add( add( -dz, cy ), bx ), aw ); + return; +} +#endif /*---------------------------------------------------------------------* * quat_shortestpath() * @@ -594,7 +673,63 @@ void quat_shortestpath( return; } +#ifdef IVAS_FLOAT_FIXED +// Not tested +void quat_shortestpath_fx( + const Word16 *q00, + Word16 *q01, + const Word16 *q10, + Word16 *q11) +{ + Word32 d0, d1; + Word16 res, i; + Word16 exp1 = 0, exp2 = 0; + + d0 = dotp_fx(q00, q01, IVAS_PCA_INTERP, &exp1); + d1 = dotp_fx(q10, q11, IVAS_PCA_INTERP, &exp2); + + res = 0; + move16(); + IF(LT_32(d0, 0) && LT_32(d1, 0)) + { + res = 1; + move16(); + } + ELSE + { + IF(LT_32(d0, 0)) + { + IF(GT_32((-d0), d1)) + { + res = 1; + move16(); + } + } + ELSE + { + IF(LT_32(d1, 0)) + { + IF(GT_32((-d1), d0)) + { + res = 1; + move16(); + } + } + } + } + + IF(res) + { + FOR(i = 0; i < IVAS_PCA_INTERP; i++) + { + q01[i] = -q01[i];move16(); + q11[i] = -q11[i];move16(); + } + } + return; +} +#endif /*---------------------------------------------------------------------* * mat_det4() * @@ -652,6 +787,24 @@ static void norm_quat( return; } +#ifdef IVAS_FLOAT_FIXED +static void norm_quat_fx( + Word16 *q) +{ + Word32 norm_q; + Word16 i, exp1 = 0, exp; + norm_q = dotp_fx(q, q, IVAS_PCA_INTERP, &exp1); + exp1 = (31 - (exp1 + 2)); + norm_q = ISqrt32(norm_q, &exp1); /*q(15 - exp)*/ + + FOR(i = 0; i < IVAS_PCA_INTERP; i++) + { + q[i] = mult(q[i], (Word16)L_shr(norm_q, 15)); // todo : recheck + } + + return; +} +#endif static void quat_nlerp_preproc( const float *q0, @@ -671,6 +824,30 @@ static void quat_nlerp_preproc( return; } +#ifdef IVAS_FLOAT_FIXED +static void quat_nlerp_preproc_fx( + const Word16 *q0, + const Word16 *q1, + const Word16 alpha, + Word16 *q_slerp) +{ + Word16 i; + Word16 tmp1, tmp2; + + FOR(i = 0; i < IVAS_PCA_INTERP; i++) + { + tmp1 = mult((MAX_16 - alpha), q1[i]); + tmp2 = mult_r(alpha, q0[i]); + IF((alpha == q0[i]) && (alpha == 32767)) + tmp2 = 32767; + q_slerp[i] = add(tmp1, tmp2); + } + + norm_quat_fx(q_slerp); + + return; +} +#endif void pca_interp_preproc( const float *prev_ql, @@ -695,7 +872,39 @@ void pca_interp_preproc( return; } - +#ifdef IVAS_FLOAT_FIXED +void pca_interp_preproc_fx( + const Word16 *prev_ql, + const Word16 *prev_qr, + const Word16 *ql, + const Word16 *qr, + const Word16 len, + Word16 *ql_interp, + Word16 *qr_interp) +{ + Word16 alpha; + Word16 j; + Word16 tmp, tmp2, tmp3; + FOR(j = 0; j < len; j++) + { + tmp = sub(len, 1); + IF(EQ_16(j, 0)) { + alpha = 0; + move16(); + } + ELSE + alpha = idiv1616(j, tmp); // the increment can be updated by simple delta //q15 + tmp2 = mult(EVS_PI_FX, alpha); // q13 + tmp3 = getCosWord16(tmp2); // q14 + alpha = shr(sub(ONE_IN_Q14, tmp3), 1); // q15 + alpha = sub(MAX_16, alpha); + quat_nlerp_preproc_fx(prev_ql, ql, alpha, &ql_interp[j * IVAS_PCA_INTERP]); + quat_nlerp_preproc_fx(prev_qr, qr, alpha, &qr_interp[j * IVAS_PCA_INTERP]); + } + + return; +} +#endif static float acos_clip( float v ) @@ -728,7 +937,25 @@ static void sp2cart( return; } +#ifdef IVAS_FLOAT_FIXED +static void sp2cart_fx( + const Word16 ph1, + const Word16 ph2, + const Word16 ph3, + Word16 *q ) +{ + Word16 s1, s2, s1s2; + s1 = getSinWord16( ph1 ); // q15 + s2 = getSinWord16( ph2 ); // q15 + s1s2 = mult( s1, s2 ); // q15 + q[3] = mult( getSinWord16( ph3 ), s1s2 ); // q15 + q[2] = mult( getCosWord16( ph3 ), s1s2 ); // q15 + q[1] = mult( getCosWord16( ph2 ), s1 ); // q15 + q[0] = getCosWord16( ph1 ); // q14 + return; +} +#endif static int16_t calc_n2( const float ph1 ) { @@ -743,7 +970,22 @@ static int16_t calc_n2( return n2; } +#ifdef IVAS_FLOAT_FIXED +static Word16 calc_n2_fx( + const Word16 ph1 ) +{ + Word16 n2; + Word16 temp = mult( 23040, getSinWord16( ph1 ) ); // q8 + n2 = round_fx( temp ); + + IF( EQ_16( s_and( n2, 1 ), 0 ) ) + { + n2 = add( n2, ONE_IN_Q8 ); + } + return n2; +} +#endif static int16_t calc_n3( const float ph1, @@ -767,7 +1009,32 @@ static int16_t calc_n3( return n3; } +#ifdef IVAS_FLOAT_FIXED +static Word16 calc_n3_fx( + const Word16 ph1, + const Word16 ph2 ) +{ + Word16 n3; + Word16 temp1 = mult( 23040, getSinWord16( ph1 ) ); // q7 + q15 - q15 + n3 = round_fx( mult( temp1, getSinWord16( ph2 ) ) ); // q7 + q15 - q15 + + IF( EQ_16( n3, 0 ) ) + { + n3 = ONE_IN_Q7; + move16(); + } + ELSE + { + IF( ( s_and( n3, 1 ) ) == 1 ) + { + n3 = add( n3, ONE_IN_Q7 ); + } + } + + return n3; +} +#endif static void q_ang_2surv( const float a, @@ -923,7 +1190,25 @@ static int16_t get_pca_offset_n2( return index2; } +#ifdef IVAS_FLOAT_FIXED +static Word16 get_pca_offset_n2_fx( + const Word16 index1 ) +{ + Word16 index2; + IF( LE_16(index1, IVAS_PCA_N1_EQ )) + { + index2 = ivas_pca_offset_n2[index1]; + move16(); + } + ELSE + { + index2 = ivas_pca_offset_n2[IVAS_PCA_N1 - 1 - index1]; + move16(); + } + return index2; +} +#endif /*---------------------------------------------------------------------* * pca_enc_s3() @@ -1116,3 +1401,97 @@ void pca_dec_s3( return; } + +#ifdef IVAS_FLOAT_FIXED +// Not tested +void pca_dec_s3_fx( + const Word32 index, + Word16 *q_fx ) +{ + Word16 ph1_q_fx, ph2_q_fx, ph3_q_fx; + + Word32 j; + Word16 i; + Word16 n1, n2, n3; + + Word16 index1, index2, index3; + Word16 d_fx; + + j = index; + move16(); + index1 = -1; + move16(); + FOR( i = 0; i < IVAS_PCA_N1; i++ ) + { + IF( j < ivas_pca_offset_index1[i + 1] ) + { + index1 = i; + move16(); + break; + } + } + + assert( index1 > -1 ); + + n1 = IVAS_PCA_N1; + move16(); + Word16 num_fx = 12868; + + d_fx = idiv1616( num_fx, n1 ); // Q12 + ph1_q_fx = mult( index1, d_fx ); // Q12 + + n2 = calc_n2_fx( ph1_q_fx ); + + j = L_sub(j , ivas_pca_offset_index1[index1]); + index2 = -1; + move16(); + FOR( i = 0; i < n2; i++ ) + { + IF( j < ivas_pca_offset_index2[i + get_pca_offset_n2_fx( index1 ) + 1] ) + { + index2 = i; + move16(); + break; + } + } + + assert( index2 > -1 ); + + IF( EQ_16(n2, 1) ) + { + ph2_q_fx = 0; + move16(); + } + ELSE + { + + num_fx = 12868; + move16(); + d_fx = idiv1616( num_fx, n1 ); // Q12 + ph2_q_fx = mult( index2, d_fx ); // Q12 + } + + j = L_sub(j, ivas_pca_offset_index2[index2 + get_pca_offset_n2_fx( index1 )]); + + index3 = (Word16) j; + move16(); + n3 = calc_n3_fx( ph1_q_fx, ph2_q_fx ); + + IF( EQ_16(n3, 1 )) + { + ph3_q_fx = 0; + move16(); + } + ELSE + { + num_fx = 6434; + move16(); + d_fx = idiv1616( num_fx, n3 ); // Q11 + ph3_q_fx = mult( index3, d_fx ); // Q11 + } + sp2cart_fx( ph1_q_fx, ph2_q_fx, ph3_q_fx, q_fx ); + + return; +} + +#endif \ No newline at end of file diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 92f1515ab1fec5dc68055afc2a46afef51117c8c..c031e2efde6e28bf82def494f02c13675b21328f 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5065,9 +5065,15 @@ int16_t ivas_is_res_channel( void ivas_spar_dec_agc_pca( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ float *output[], /* i/o: input/output audio channels */ - const int16_t output_frame /* i : output frame length */ + const Word16 output_frame /* i : output frame length */ ); - +#ifdef IVAS_FLOAT_FIXED +void ivas_spar_dec_agc_pca_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Word32 *output[], /* i/o: input/output audio channels */ + const Word16 output_frame /* i : output frame length */ +); +#endif void ivas_spar_dec_set_render_map( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nCldfbTs /* i : number of CLDFB time slots */ @@ -5511,14 +5517,39 @@ void ivas_pca_dec( const int16_t bfi, /* i : bad frame indicator */ float *pcm_out[] /* o : output audio channels */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_pca_read_bits_fx( + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + PCA_DEC_STATE *hPCA /* i/o: PCA encoder structure */ +); + +void ivas_pca_dec_init_fx( + PCA_DEC_STATE *hPCA /* i/o: PCA decoder structure */ +); +void ivas_pca_dec_fx( + PCA_DEC_STATE *hPCA, /* i/o: PCA decoder structure */ + const Word16 output_frame, /* i : output frame length */ + const Word16 n_channels, /* i : number of channels */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate */ + const Word16 bfi, /* i : bad frame indicator */ + Word32 *pcm_out[] /* o : output audio channels */ +); +#endif /* PCA utilities */ void eye_matrix( float *mat, const int16_t n, const float d ); - +#ifdef IVAS_FLOAT_FIXED +void eye_matrix_fx( + Word16 *mat, + const Word16 n, + const Word16 d +); +#endif void cov_subfr( float **ptr_sig, float *r, @@ -5572,7 +5603,27 @@ void pca_interp_preproc( float *ql_interp, float *qr_interp ); - +#ifdef IVAS_FLOAT_FIXED +void dquat2mat_fx( + const Word16 *ql, + const Word16 *qr, + Word16 *m); + +void quat_shortestpath_fx( + const Word16 *q00, + Word16 *q01, + const Word16 *q10, + Word16 *q11); + +void pca_interp_preproc_fx( + const Word16 *prev_ql, + const Word16 *prev_qr, + const Word16 *ql, + const Word16 *qr, + const Word16 len, + Word16 *ql_interp, + Word16 *qr_interp); +#endif void pca_enc_s3( float *q, int32_t *index @@ -5582,7 +5633,11 @@ void pca_dec_s3( const int32_t index, float *q ); - +#ifdef IVAS_FLOAT_FIXED +void pca_dec_s3_fx( + const Word32 index, + Word16 *q); +#endif int16_t ivas_get_bits_to_encode( int32_t val ); diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 7a3a430a72d2109ede89f1aecfecc6fb95723395..65c86cfae94d0f048d6d9cd9125e62c48b69a704 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -155,6 +155,11 @@ ivas_error ivas_omasa_dec_config_fx( Word16 SrcInd[MAX_NUM_TDREND_CHANNELS], Word16 *data /* o : output synthesis signal */ ); +ivas_error ivas_td_binaural_renderer_sf_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ +); #endif void ivas_omasa_modify_masa_energy_ratios_fx( @@ -1901,10 +1906,59 @@ ivas_error ivas_qmetadata_allocate_memory( void ivas_qmetadata_close( IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */ ); -#endif ivas_error ivas_spar_dec_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ Word16 *nb_bits_read /* o : number of MD bits read */ ); + +ivas_error TDREND_Update_object_positions_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ + const Word16 num_src, /* i : number of sources to render */ + const IVAS_FORMAT in_format, /* i : Format of input sources */ + const ISM_METADATA_HANDLE *hIsmMetaData /* i : Input metadata for ISM objects */ +); + +ivas_error TDREND_MIX_LIST_SetOrient_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word32 *FrontVec_p_fx, /* i : Listener's orientation front vector */ + const Word32 *UpVec_p_fx, /* i : Listener's orientation up vector */ + const Word16 orient_q +); + +void TDREND_MIX_LIST_SetPos_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word32 *Pos_p /* i : Listener's position */ +); + +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 */ +); + +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 */ +); + +Word32 TDREND_SPATIAL_VecNorm_fx( + const Word32 *Vec_p, /* i : Vector for norm calculation */ + const Word16 in_exp, /* i : Input exp */ + Word16 *out_exp /* o : Output exp */ +); + +void TDREND_SPATIAL_VecMapToNewCoordSystem_fx( + const Word32 *Vec_p, /* i : Input vector */ + const Word32 *TranslVec_p, /* i : Translation vector */ + const Word32 *DirVec_p, /* i : Direction vector */ + const Word32 *UpVec_p, /* i : Up vector */ + const Word32 *RightVec_p, /* i : Right vector */ + Word32 *MappedVec_p, /* o : Transformed vector */ + Word32 *LisRelPosAbs /* o : Transformed vector ignoring orientation */ +); + +#endif // IVAS_FLOAT_FIXED + #endif diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index 4c103f70ea089bec0ddc130bc5964df339f3cc76..c901dd2d9aa4da47e65514a149fc42ddd6c39d98 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -323,12 +323,14 @@ Word16 ivas_sba_get_nchan_metadata( IF ( EQ_16(sba_order , SBA_FOA_ORDER) ) { nb_channels = FOA_CHANNELS; + move16(); } ELSE { IF ( GE_32(ivas_total_brate , IVAS_512k) ) { nb_channels = IVAS_SPAR_MAX_CH; + move16(); nb_channels = s_min( nb_channels, imult1616(add( sba_order , 1 ) , add( sba_order , 1 )) ); } ELSE diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 68d285dc7626cf3deab1b56a75453a1533f9c170..4c60f85c7591f1f2ddb6fade97328d640d19f87e 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -6854,6 +6854,12 @@ void GSC_dec_init_ivas_fx( const Word16 coder_type /* i : coder type */ ); + ivas_error acelp_core_switch_dec_bfi_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 synth_out[], /* o : synthesis Q_syn */ + const Word16 coder_type /* i : coder type */ + ); + //pred_lt4_fx.c void pred_lt4( const Word16 excI[], /* in : excitation buffer */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 5a954cf349eb5ebee5eceeef8df19aa5b7d310c6..66031abf6a86d0ae994176839d24388096a95090 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -1575,16 +1575,16 @@ ivas_error acelp_core_dec_fx( *----------------------------------------------------------------*/ /* check if the CLDFB works on the right sample rate */ - IF( (st_fx->cldfbAna_fx->usb * st_fx->cldfbAna_fx->no_col) != st_fx->L_frame ) + IF( (st_fx->cldfbAna->usb * st_fx->cldfbAna->no_col) != st_fx->L_frame ) { /* resample to ACELP internal sampling rate */ Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, FRAMES_PER_SEC)); - resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 0 ); - resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbAna, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 0 ); if( st_fx->ini_frame > 0 ) { - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels,st_fx->cldfbAna->no_channels); } } #ifdef ADD_LRTD @@ -1627,7 +1627,7 @@ ivas_error acelp_core_dec_fx( } #endif /* analysis of the synthesis at internal sampling rate */ - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX, workBuffer); + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX, workBuffer); scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); @@ -1640,19 +1640,19 @@ ivas_error acelp_core_dec_fx( i = CLDFB_NO_COL_MAX; move16(); } - addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), - i, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate(st_fx->Q_syn), + i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor ); /* set output mask for upsampling */ IF( EQ_16(st_fx->bwidth,NB)) { /* set NB mask for upsampling */ - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,10); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels,10); } - ELSE if( NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels))) + ELSE if( NE_16(st_fx->cldfbSyn->bandsToZero,sub(st_fx->cldfbSyn->no_channels,st_fx->cldfbAna->no_channels))) { /* in case of BW switching, re-init to default */ - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->cldfbAna_fx->no_channels); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels); } /*WB/SWB-FD_CNG*/ @@ -1664,17 +1664,17 @@ ivas_error acelp_core_dec_fx( test(); IF(!st_fx->cng_sba_flag || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) { - IF((EQ_32(st_fx->core_brate, FRAME_NO_DATA) || EQ_32(st_fx->core_brate, SID_2k40)) && (EQ_16(st_fx->cng_type, FD_CNG)) && (LT_16(st_fx->hFdCngDec->hFdCngCom->numCoreBands, st_fx->cldfbSyn_fx->no_channels))) + IF((EQ_32(st_fx->core_brate, FRAME_NO_DATA) || EQ_32(st_fx->core_brate, SID_2k40)) && (EQ_16(st_fx->cng_type, FD_CNG)) && (LT_16(st_fx->hFdCngDec->hFdCngCom->numCoreBands, st_fx->cldfbSyn->no_channels))) { generate_comfort_noise_dec_hf(realBuffer, imagBuffer, &scaleFactor.hb_scale, st_fx); - st_fx->cldfbSyn_fx->bandsToZero = 0; + st_fx->cldfbSyn->bandsToZero = 0; move16(); - if (LT_16(st_fx->hFdCngDec->hFdCngCom->regularStopBand, st_fx->cldfbSyn_fx->no_channels)) + if (LT_16(st_fx->hFdCngDec->hFdCngCom->regularStopBand, st_fx->cldfbSyn->no_channels)) { - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->hFdCngDec->hFdCngCom->regularStopBand); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels, st_fx->hFdCngDec->hFdCngCom->regularStopBand); } - st_fx->cldfbSyn_fx->lsb = st_fx->cldfbAna_fx->no_channels; + st_fx->cldfbSyn->lsb = st_fx->cldfbAna->no_channels; move16(); } } @@ -1716,7 +1716,7 @@ ivas_error acelp_core_dec_fx( else #endif { - cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer); + cldfbSynthesisFiltering(st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer); } /* Bring CLDFB output to Q0 */ Scale_sig(synth_out, output_frame, negate(st_fx->Q_syn2)); diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 04fa192e59a0f7b63970cdcccaf04dea6abbd555..dba2c46ffe7d50a13fdebdb5285b500efefa16bd 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -8,6 +8,7 @@ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx1.h" /* Function prototypes */ #include "prot_fx2.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ /*---------------------------------------------------------------------* * Local function prototypes @@ -194,20 +195,20 @@ ivas_error acelp_core_switch_dec_fx( st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal ); - if ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + if ((error = cldfb_save_memory( st_fx->cldfbAna)) != IVAS_ERR_OK) { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, synth_intFreq, + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, synth_intFreq, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH, workBuffer); - cldfb_restore_memory( st_fx->cldfbAna_fx ); + cldfb_restore_memory( st_fx->cldfbAna); /* CLDFB synthesis of the combined signal */ scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); /* CLDFB analysis and add the BPF error signal */ - if ((error = cldfb_save_memory( st_fx->cldfbBPF_fx )) != IVAS_ERR_OK) + if ((error = cldfb_save_memory( st_fx->cldfbBPF )) != IVAS_ERR_OK) { return error; } @@ -218,19 +219,19 @@ ivas_error acelp_core_switch_dec_fx( i = CLDFB_NO_COL_MAX_SWITCH; move16(); } - addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), - i, CLDFB_NO_COL_MAX_SWITCH, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); - cldfb_restore_memory( st_fx->cldfbBPF_fx ); + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate(st_fx->Q_syn), + i, CLDFB_NO_COL_MAX_SWITCH, st_fx->cldfbAna->no_channels, &scaleFactor ); + cldfb_restore_memory( st_fx->cldfbBPF ); /* CLDFB synthesis of the combined signal */ scaleFactor.hb_scale = scaleFactor.lb_scale; - if ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + if ((error = cldfb_save_memory( st_fx->cldfbSyn )) != IVAS_ERR_OK) { return error; } - cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_subfr_out, 0, CLDFB_NO_COL_MAX_SWITCH, workBuffer); - cldfb_restore_memory( st_fx->cldfbSyn_fx ); + cldfbSynthesisFiltering(st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_subfr_out, 0, CLDFB_NO_COL_MAX_SWITCH, workBuffer); + cldfb_restore_memory( st_fx->cldfbSyn ); *Q_syn = 0; move16(); @@ -558,33 +559,33 @@ ivas_error acelp_core_switch_dec_bfi_fx( * Resamping to the output sampling frequency *----------------------------------------------------------------*/ /* CLDFB analysis of the synthesis at internal sampling rate */ - if ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + if ((error = cldfb_save_memory( st_fx->cldfbAna)) != IVAS_ERR_OK) { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn, + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer); - cldfb_restore_memory( st_fx->cldfbAna_fx ); + cldfb_restore_memory( st_fx->cldfbAna); scaleFactor.hb_scale = scaleFactor.lb_scale; /* CLDFB synthesis of the combined signal */ - if ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + if ((error = cldfb_save_memory( st_fx->cldfbSyn )) != IVAS_ERR_OK) { return error; } - cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, + cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer ); /* output to Q0 */ Scale_sig(synth_out,L_FRAME48k, negate(st_fx->Q_syn)); - cldfb_restore_memory( st_fx->cldfbSyn_fx ); + cldfb_restore_memory( st_fx->cldfbSyn ); return error; } -#ifdef DISABLED +#ifdef IVAS_FLOAT_FIXED ivas_error acelp_core_switch_dec_bfi_ivas_fx( Decoder_State *st_fx, /* i/o: decoder state structure */ Word16 synth_out[], /* o : synthesis Q_syn */ @@ -618,6 +619,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( Word16 i; CLDFB_SCALE_FACTOR scaleFactor; Word32 workBuffer[128*3]; + Word32 synth32[L_FRAME48k]; MUSIC_POSTFILT_HANDLE hMusicPF; BPF_DEC_HANDLE hBPF; ivas_error error; @@ -641,7 +643,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); st_fx->bpf_off = 1; move16(); - st_fx->clas_dec = st_fx->last_good_fx; + st_fx->clas_dec = st_fx->last_good; move16(); tmp_noise = 0; move16(); @@ -673,7 +675,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( move16(); /* SC-VBR */ - if( EQ_16(st_fx->last_nelp_mode_dec_fx, 1)) + if( EQ_16(st_fx->last_nelp_mode_dec, 1)) { st_fx->nelp_mode_dec = 1; move16(); @@ -684,7 +686,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( /* LSF estimation and A(z) calculation */ lsf_dec_bfi(MODE1, lsf_new, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, - st_fx->stab_fac_fx, st_fx->last_coder_type_fx, st_fx->L_frame, st_fx->last_good_fx, + st_fx->stab_fac_fx, st_fx->last_coder_type, st_fx->L_frame, st_fx->last_good, st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx_fx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth); FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq, lsf_new, lsp_new); @@ -726,7 +728,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( /* calculation of excitation signal */ FEC_exc_estim_fx( st_fx, st_fx->L_frame, exc, exc2, syn /* dummy buffer */, pitch_buf, voice_factors, &FEC_pitch, bwe_exc, lsf_new, &Q_exc, &tmp_noise ); Rescale_exc( NULL, exc, bwe_exc, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, L_FRAME32k, (Word32)0, - &Q_exc, st_fx->Q_subfr, exc2, st_fx->L_frame, st_fx->last_coder_type_fx); + &Q_exc, st_fx->Q_subfr, exc2, st_fx->L_frame, st_fx->last_coder_type); st_fx->seed = tmp_float[5]; move16(); @@ -752,7 +754,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( syn_12k8_fx( st_fx->L_frame, Aq, exc2, syn, tmp_float, 1, Q_exc, st_fx->Q_syn ); tmp_float32 = st_fx->enr_old_fx; - frame_ener_fx( st_fx->L_frame, st_fx->last_good_fx, syn, shr(add(FEC_pitch,32),6), &tmp_float32, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); + frame_ener_fx( st_fx->L_frame, st_fx->last_good, syn, shr(add(FEC_pitch,32),6), &tmp_float32, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); /*------------------------------------------------------------------* * Perform fixed deemphasis through 1/(1 - g*z^-1) @@ -804,7 +806,7 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( { return error; } - /*cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn, + /*cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer);*/ cldfbAnalysis_ivas_fx(syn32, realBuffer, imagBuffer, st_fx->L_frame / 2, st_fx->cldfbAna); cldfb_restore_memory_ivas_fx( st_fx->cldfbAna ); @@ -816,11 +818,15 @@ ivas_error acelp_core_switch_dec_bfi_ivas_fx( { return error; } - /*cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, + /*cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer );*/ - Scale_sig32(st_fx->cldfbSyn->cldfb_state,st_fx->cldfbSyn->cldfb_state_length,1); - cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); - Scale_sig32(st_fx->cldfbSyn->cldfb_state, st_fx->cldfbSyn->cldfb_state_length, -1); + Scale_sig32(st_fx->cldfbSyn->cldfb_state_fx,st_fx->cldfbSyn->cldfb_state_length,1); + Copy_Scale_sig_16_32(synth_out, synth32, L_FRAME48k, 11 - 5 - 1); + + //cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); + cldfbSynthesis_ivas_fx( realBuffer, imagBuffer, synth32, extract_l( Mpy_32_16_1( st_fx->output_Fs, 328 ) ), st_fx->cldfbSyn ); + Scale_sig32(st_fx->cldfbSyn->cldfb_state_fx, st_fx->cldfbSyn->cldfb_state_length, -1); + Copy_Scale_sig_32_16(synth32, synth_out, L_FRAME48k, -5); /* output to Q0 */ Copy_Scale_sig32_16(syn32, synth_out, L_FRAME48k, -5); diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 6d062f3a93783903d69f1f7402ccd4a20a06a929..a1f4193696e0e5c60934644013170faa57f8f4bc 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -842,24 +842,24 @@ ivas_error amr_wb_dec_fx( *----------------------------------------------------------------*/ /* check if the CLDFB works on the right sample rate */ - IF( (st_fx->cldfbAna_fx->usb * st_fx->cldfbAna_fx->no_col) != L_FRAME ) + IF( (st_fx->cldfbAna->usb * st_fx->cldfbAna->no_col) != L_FRAME ) { /* resample to ACELP internal sampling rate */ Word16 newCldfbBands = CLDFB_getNumChannels(INT_FS_FX); - resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, L_FRAME, 0 ); - resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, L_FRAME, 0 ); + resampleCldfb( st_fx->cldfbAna, newCldfbBands, L_FRAME, 0 ); + resampleCldfb( st_fx->cldfbBPF, newCldfbBands, L_FRAME, 0 ); if( st_fx->ini_frame > 0 ) { - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels,st_fx->cldfbAna->no_channels); } } bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, L_FRAME, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx, &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal); - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn_fx, + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate(st_fx->Q_syn), CLDFB_NO_COL_MAX, workBuffer ); scaleFactor.hb_scale = scaleFactor.lb_scale; @@ -873,19 +873,19 @@ ivas_error amr_wb_dec_fx( i = CLDFB_NO_COL_MAX; move16(); } - addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, negate(st_fx->Q_syn), - i, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &scaleFactor ); + addBassPostFilterFx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate(st_fx->Q_syn), + i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor ); st_fx->Q_syn2 = st_fx->Q_syn; move16(); - if( NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,st_fx->cldfbAna_fx->no_channels))) + if( NE_16(st_fx->cldfbSyn->bandsToZero,sub(st_fx->cldfbSyn->no_channels,st_fx->cldfbAna->no_channels))) { /* in case of BW switching, re-init to default */ - st_fx->cldfbSyn_fx->bandsToZero = sub(st_fx->cldfbSyn_fx->no_channels, st_fx->cldfbAna_fx->no_channels); + st_fx->cldfbSyn->bandsToZero = sub(st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels); } cldfb_synth_set_bandsToZero( st_fx, realBuffer, imagBuffer, CLDFB_NO_COL_MAX, scaleFactor ); /* CLDFB synthesis of the combined signal */ - cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer ); + cldfbSynthesisFiltering( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate(st_fx->Q_syn2), CLDFB_NO_COL_MAX, workBuffer ); /* Bring CLDFB output to Q-1 */ Scale_sig( synth_out_fx, output_frame, negate(st_fx->Q_syn2) ); @@ -921,7 +921,7 @@ ivas_error amr_wb_dec_fx( test(); test(); - IF( GE_16(output_frame,L_FRAME16k)&&(NE_16(st_fx->cldfbSyn_fx->bandsToZero,sub(st_fx->cldfbSyn_fx->no_channels,10))||NE_16(st_fx->last_flag_filter_NB,1))) + IF( GE_16(output_frame,L_FRAME16k)&&(NE_16(st_fx->cldfbSyn->bandsToZero,sub(st_fx->cldfbSyn->no_channels,10))||NE_16(st_fx->last_flag_filter_NB,1))) { hf_synth_amr_wb_fx( st_fx->hAmrwb_IO, st_fx->hBWE_zero, st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, &amr_io_class, synth_out_fx, diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index b80fbef39f7c4c8a70d131cae9d262a7299a36ba..205e1df3de115683369ed8ea65508f11010ab328 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -511,9 +511,9 @@ void open_decoder_LPD( } move16(); /* reset CLDFB memories */ - cldfb_reset_memory( st->cldfbAna_fx ); - cldfb_reset_memory( st->cldfbBPF_fx ); - cldfb_reset_memory( st->cldfbSyn_fx ); + cldfb_reset_memory( st->cldfbAna ); + cldfb_reset_memory( st->cldfbBPF ); + cldfb_reset_memory( st->cldfbSyn ); #ifndef NEW_IVAS_OPEN_DEC #if 0 PMT("cldfbSynHB is missing ") diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 4dfafcd5dd041b9ca3a5e3eb8eb10e1c3d5f81b2..2825f54e5289213f4e63c6f18f83142256ffb5df 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -638,26 +638,26 @@ ivas_error core_switching_pre_dec_fx( move32(); } - no_col = s_min(st_fx->cldfbAna_fx->no_col, idiv1616(sub(add(delay_comp, st_fx->cldfbAna_fx->no_channels),1) , st_fx->cldfbAna_fx->no_channels)); + no_col = s_min(st_fx->cldfbAna->no_col, idiv1616(sub(add(delay_comp, st_fx->cldfbAna->no_channels),1) , st_fx->cldfbAna->no_channels)); /* CLDFB analysis of the synthesis at internal sampling rate */ - IF ((error = cldfb_save_memory( st_fx->cldfbAna_fx )) != IVAS_ERR_OK) + IF ((error = cldfb_save_memory( st_fx->cldfbAna )) != IVAS_ERR_OK) { return error; } - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, hTcxDec->syn_Overl, 0, no_col, workBuffer); - cldfb_restore_memory( st_fx->cldfbAna_fx ); + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, hTcxDec->syn_Overl, 0, no_col, workBuffer); + cldfb_restore_memory( st_fx->cldfbAna ); scaleFactor.hb_scale = scaleFactor.lb_scale; move16(); /* CLDFB synthesis of the combined signal */ - IF ((error = cldfb_save_memory( st_fx->cldfbSyn_fx )) != IVAS_ERR_OK) + IF ((error = cldfb_save_memory( st_fx->cldfbSyn )) != IVAS_ERR_OK) { return error; } - cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, hHQ_core->fer_samples_fx, 0, no_col, workBuffer); - cldfb_restore_memory( st_fx->cldfbSyn_fx ); + cldfbSynthesisFiltering(st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, hHQ_core->fer_samples_fx, 0, no_col, workBuffer); + cldfb_restore_memory( st_fx->cldfbSyn ); } IF( !st_fx->last_con_tcx && st_fx->last_core_bfi == ACELP_CORE && EQ_16(st_fx->core,HQ_CORE)) @@ -834,9 +834,9 @@ ivas_error core_switching_pre_dec_fx( move16(); /* reset CLDFB memories */ - cldfb_reset_memory( st_fx->cldfbAna_fx ); - cldfb_reset_memory( st_fx->cldfbBPF_fx ); - cldfb_reset_memory( st_fx->cldfbSyn_fx ); + cldfb_reset_memory( st_fx->cldfbAna ); + cldfb_reset_memory( st_fx->cldfbBPF ); + cldfb_reset_memory( st_fx->cldfbSyn ); /* reset TBE memories */ test(); @@ -1545,7 +1545,7 @@ ivas_error core_switching_post_dec_ivas_fx( IF( EQ_16( st_fx->core, ACELP_CORE ) && st_fx->bfi && hHQ_core != NULL && !st_fx->con_tcx ) { /*needed to be converted to fixed curretnly using evs implementation not in line*/ - if ( ( error = acelp_core_switch_dec_bfi_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type ) ) != IVAS_ERR_OK ) + if ( ( error = acelp_core_switch_dec_bfi_ivas_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type ) ) != IVAS_ERR_OK ) { return error; } /*the output at Q0*/ @@ -1730,7 +1730,7 @@ ivas_error core_switching_post_dec_ivas_fx( smoothTransitionDtxToTcx_fx( synth, output_frame, delay_comp ); } /* Reset memories of CLDFBs */ - IF( st_fx->cldfbAna_fx != NULL ) + IF( st_fx->cldfbAna != NULL ) { IF( NE_16( i_mult( st_fx->cldfbAna->no_channels, st_fx->cldfbAna->no_col ), st_fx->L_frame ) ) { @@ -1782,7 +1782,7 @@ ivas_error core_switching_post_dec_ivas_fx( cldfb_reset_memory_fx( st_fx->cldfbBPF ); } - IF( st_fx->cldfbSyn_fx != NULL ) + IF( st_fx->cldfbSyn != NULL ) { cldfb_reset_memory_fx( st_fx->cldfbSyn ); } diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 860cc7788c33549d95d0f3668527fa5f99a8a6c8..80176e309c9c136294284a351f2fe77a5475f917 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -210,23 +210,23 @@ void decode_frame_type(Decoder_State *st mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, frame_size_index ); #endif /* Reconf CLDFB */ - IF( NE_16 (i_mult(st->cldfbAna_fx->no_channels,st->cldfbAna_fx->no_col), st->L_frame) ) + IF( NE_16 (i_mult(st->cldfbAna->no_channels,st->cldfbAna->no_col), st->L_frame) ) { Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st->L_frame,50)); - resampleCldfb( st->cldfbAna_fx, newCldfbBands, st->L_frame, 0 ); + resampleCldfb( st->cldfbAna, newCldfbBands, st->L_frame, 0 ); IF ( LE_16(st->L_frame,L_FRAME16k) ) { - resampleCldfb( st->cldfbBPF_fx, newCldfbBands, st->L_frame, 0 ); + resampleCldfb( st->cldfbBPF, newCldfbBands, st->L_frame, 0 ); } } IF ( EQ_16(st->bwidth,NB)) { - st->cldfbSyn_fx->bandsToZero = sub (st->cldfbSyn_fx->no_channels,10); + st->cldfbSyn->bandsToZero = sub (st->cldfbSyn->no_channels,10); } ELSE { - st->cldfbSyn_fx->bandsToZero = 0; + st->cldfbSyn->bandsToZero = 0; } /* Reconf FD-CNG */ diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index 1eb8eb6c22178ab86ef404b027cfeb73fb2650c0..626bf03b0d331ef95de6162c3394f283dbee948f 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -960,14 +960,14 @@ ivas_error evs_dec_fx( /* -------------------------------------------------------------- */ { - nab = s_min( st_fx->cldfbAna_fx->no_channels, st_fx->cldfbSyn_fx->no_channels ); - st_fx->cldfbSyn_fx->lsb = s_min(st_fx->cldfbAna_fx->no_channels, st_fx->cldfbSyn_fx->no_channels); + nab = s_min( st_fx->cldfbAna->no_channels, st_fx->cldfbSyn->no_channels ); + st_fx->cldfbSyn->lsb = s_min(st_fx->cldfbAna->no_channels, st_fx->cldfbSyn->no_channels); move16(); - st_fx->cldfbSyn_fx->usb = st_fx->cldfbSyn_fx->no_channels; + st_fx->cldfbSyn->usb = st_fx->cldfbSyn->no_channels; move16(); - st_fx->cldfbAna_fx->lsb = st_fx->cldfbAna_fx->no_channels; + st_fx->cldfbAna->lsb = st_fx->cldfbAna->no_channels; move16(); - st_fx->cldfbAna_fx->usb = st_fx->cldfbAna_fx->no_channels; + st_fx->cldfbAna->usb = st_fx->cldfbAna->no_channels; move16(); test(); @@ -1032,7 +1032,7 @@ ivas_error evs_dec_fx( } Scale_sig( output_sp, st_fx->L_frame, timeIn_e ); timeIn_e = negate( timeIn_e ); - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); st_fx->scaleFactor.hb_scale = st_fx->scaleFactor.lb_scale; move16(); } @@ -1059,24 +1059,24 @@ ivas_error evs_dec_fx( } } /* check if the CLDFB works on the right sample rate */ - IF( NE_16((st_fx->cldfbAna_fx->no_channels * st_fx->cldfbAna_fx->no_col),st_fx->L_frame)) + IF( NE_16((st_fx->cldfbAna->no_channels * st_fx->cldfbAna->no_col),st_fx->L_frame)) { Word16 newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, 50)); - resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 0 ); - resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbAna, newCldfbBands, st_fx->L_frame, 0 ); + resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 0 ); } - st_fx->cldfbSyn_fx->bandsToZero = 0; + st_fx->cldfbSyn->bandsToZero = 0; move16(); test(); - IF ( EQ_16( st_fx->bwidth, NB )&>_16(st_fx->cldfbSyn_fx->no_channels,10)) + IF ( EQ_16( st_fx->bwidth, NB )&>_16(st_fx->cldfbSyn->no_channels,10)) { - st_fx->cldfbSyn_fx->bandsToZero = sub( st_fx->cldfbSyn_fx->no_channels, 10 ); + st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, 10 ); } - ELSE IF ( st_fx->hFdCngDec->hFdCngCom->regularStopBand < st_fx->cldfbSyn_fx->no_channels ) + ELSE IF ( st_fx->hFdCngDec->hFdCngCom->regularStopBand < st_fx->cldfbSyn->no_channels ) { - st_fx->cldfbSyn_fx->bandsToZero = st_fx->cldfbSyn_fx->no_channels - st_fx->hFdCngDec->hFdCngCom->regularStopBand; + st_fx->cldfbSyn->bandsToZero = st_fx->cldfbSyn->no_channels - st_fx->hFdCngDec->hFdCngCom->regularStopBand; } timeIn_e = 2; @@ -1088,7 +1088,7 @@ ivas_error evs_dec_fx( } timeIn_e = negate(timeIn_e); - cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, timeDomainBuffer, timeIn_e, CLDFB_NO_COL_MAX, workBuffer) ; + cldfbAnalysisFiltering( st_fx->cldfbAna, realBuffer, imagBuffer, &st_fx->scaleFactor, timeDomainBuffer, timeIn_e, CLDFB_NO_COL_MAX, workBuffer) ; } if( st_fx->flag_cna == 0 ) @@ -1106,8 +1106,8 @@ ivas_error evs_dec_fx( move16(); } - addBassPostFilterFx( st_fx->p_bpf_noise_buf, realBuffer, imagBuffer, st_fx->cldfbBPF_fx, workBuffer, - timeInBpf_e, CLDFB_NO_COL_MAX, st_fx->cldfbAna_fx->no_col, st_fx->cldfbAna_fx->no_channels, &st_fx->scaleFactor ); + addBassPostFilterFx( st_fx->p_bpf_noise_buf, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, + timeInBpf_e, CLDFB_NO_COL_MAX, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &st_fx->scaleFactor ); IF( NE_16(st_fx->m_frame_type,ACTIVE_FRAME)) { @@ -1122,8 +1122,8 @@ ivas_error evs_dec_fx( calcGainTemp_TBE_Fx( realBuffer, imagBuffer, st_fx->hTECDec->cldfbExp, st_fx->hTECDec->loBuffer, 0, /*startPos,*//*!< Start position of the current envelope. */ - st_fx->cldfbAna_fx->no_col, /*stopPos,*/ /*!< Stop position of the current envelope. */ - st_fx->cldfbAna_fx->no_channels, /*lowSubband*/ + st_fx->cldfbAna->no_col, /*stopPos,*/ /*!< Stop position of the current envelope. */ + st_fx->cldfbAna->no_channels, /*lowSubband*/ st_fx->hTECDec->pGainTemp_m, st_fx->hTECDec->pGainTemp_e, st_fx->tec_flag ); } @@ -1133,13 +1133,13 @@ ivas_error evs_dec_fx( { FOR( i = 0; i < 16; i++ ) { - set32_fx( &realBuffer[i][nab], 0, sub(st_fx->cldfbSyn_fx->no_channels,nab) ); - set32_fx( &imagBuffer[i][nab], 0, sub(st_fx->cldfbSyn_fx->no_channels,nab) ); + set32_fx( &realBuffer[i][nab], 0, sub(st_fx->cldfbSyn->no_channels,nab) ); + set32_fx( &imagBuffer[i][nab], 0, sub(st_fx->cldfbSyn->no_channels,nab) ); } } timeIn_e = s_min(0, add(timeIn_e, 2)); - cldfbSynthesisFiltering(st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); + cldfbSynthesisFiltering(st_fx->cldfbSyn, realBuffer, imagBuffer, &st_fx->scaleFactor, output_sp, timeIn_e, CLDFB_NO_COL_MAX, workBuffer ); /*CLDFB output always in timeIn_e*/ /* MODE1 MDCT to ACELP 2 transition */ diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index 1f548d9dd541929618a85438a35dff113c05451a..2668a1e4d0ce8dc442a3b8a07b49ab4a79de5618 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -658,18 +658,18 @@ ivas_error init_decoder_fx( * FD BPF & resampling tools parameters *-----------------------------------------------------------------*/ /* open analysis for max. SR 48kHz */ - if ((error = openCldfb(&st_fx->cldfbAna_fx, CLDFB_ANALYSIS, CLDFB_getNumChannels(48000), 320)) != IVAS_ERR_OK) + if ((error = openCldfb(&st_fx->cldfbAna, CLDFB_ANALYSIS, CLDFB_getNumChannels(48000), 320)) != IVAS_ERR_OK) { return error; } /* open analysis BPF for max. SR 16kHz */ - if ((error = openCldfb(&st_fx->cldfbBPF_fx, CLDFB_ANALYSIS, CLDFB_getNumChannels(16000), 320)) != IVAS_ERR_OK) + if ((error = openCldfb(&st_fx->cldfbBPF, CLDFB_ANALYSIS, CLDFB_getNumChannels(16000), 320)) != IVAS_ERR_OK) { return error; } /* open synthesis for output SR */ - if ((error = openCldfb(&st_fx->cldfbSyn_fx, CLDFB_SYNTHESIS, CLDFB_getNumChannels(st_fx->output_Fs), st_fx->output_frame_fx)) != IVAS_ERR_OK) + if ((error = openCldfb(&st_fx->cldfbSyn, CLDFB_SYNTHESIS, CLDFB_getNumChannels(st_fx->output_Fs), st_fx->output_frame_fx)) != IVAS_ERR_OK) { return error; } @@ -752,8 +752,8 @@ ivas_error init_decoder_fx( newCldfbBands = CLDFB_getNumChannels(L_mult0(st_fx->L_frame, 50)); - resampleCldfb( st_fx->cldfbAna_fx, newCldfbBands, st_fx->L_frame, 1 ); - resampleCldfb( st_fx->cldfbBPF_fx, newCldfbBands, st_fx->L_frame, 1 ); + resampleCldfb( st_fx->cldfbAna, newCldfbBands, st_fx->L_frame, 1 ); + resampleCldfb( st_fx->cldfbBPF, newCldfbBands, st_fx->L_frame, 1 ); #ifdef IVAS_CODE IF((EQ_16(st_fx->element_mode, IVAS_CPE_MDCT) || idchan == 0 ) && NE_16(mc_mode, MC_MODE_MCT) && NE_16(mc_mode, MC_MODE_PARAMUPMIX) ) // TBV Fixed point missing #else @@ -768,7 +768,7 @@ ivas_error init_decoder_fx( } /* Init FD-CNG */ - initFdCngDec( st_fx, st_fx->cldfbSyn_fx->scale ); + initFdCngDec( st_fx, st_fx->cldfbSyn->scale ); } ELSE { @@ -1609,29 +1609,29 @@ ivas_error init_decoder_ivas_fx( IF ((idchan == 0 && NE_16(st_fx->element_mode , IVAS_CPE_MDCT)) || EQ_16(st_fx->element_mode, IVAS_CPE_TD)) { /* open analysis for max. SR 48kHz */ - IF ((error = openCldfb_ivas_fx(&st_fx->cldfbAna_fx, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) + IF ((error = openCldfb_ivas_fx(&st_fx->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) { return error; } /* open analysis BPF for max. SR 16kHz */ - IF ((error = openCldfb_ivas_fx(&st_fx->cldfbBPF_fx, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) + IF ((error = openCldfb_ivas_fx(&st_fx->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) { return error; } } ELSE { - st_fx->cldfbAna_fx = NULL; - st_fx->cldfbBPF_fx = NULL; + st_fx->cldfbAna = NULL; + st_fx->cldfbBPF = NULL; } /* open synthesis for output SR */ - IF ((error = openCldfb_ivas_fx(&st_fx->cldfbSyn_fx, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) + IF ((error = openCldfb_ivas_fx(&st_fx->cldfbSyn, CLDFB_SYNTHESIS, st_fx->output_Fs, CLDFB_PROTOTYPE_1_25MS)) != IVAS_ERR_OK) { return error; } -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED // To be removed when fixed version is available. +#if 0//def IVAS_FLOAT_FIXED_TO_BE_REMOVED // To be removed when fixed version is available. if ((idchan == 0 && st_fx->element_mode != IVAS_CPE_MDCT) || st_fx->element_mode == IVAS_CPE_TD) { /* open analysis for max. sampling rate 48kHz */ @@ -1888,8 +1888,8 @@ ivas_error init_decoder_ivas_fx( IF ((idchan == 0 && NE_16(st_fx->element_mode, IVAS_CPE_MDCT))) { - resampleCldfb_ivas_fx(st_fx->cldfbAna_fx, L_mult0( st_fx->L_frame, FRAMES_PER_SEC )); - resampleCldfb_ivas_fx(st_fx->cldfbBPF_fx, L_mult0( st_fx->L_frame, FRAMES_PER_SEC )); + resampleCldfb_ivas_fx(st_fx->cldfbAna, L_mult0( st_fx->L_frame, FRAMES_PER_SEC )); + resampleCldfb_ivas_fx(st_fx->cldfbBPF, L_mult0( st_fx->L_frame, FRAMES_PER_SEC )); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED // To be removed when fixed version is available. resampleCldfb_ivas(st_fx->cldfbAna, st_fx->L_frame * FRAMES_PER_SEC); resampleCldfb_ivas(st_fx->cldfbBPF, st_fx->L_frame * FRAMES_PER_SEC); @@ -1913,7 +1913,7 @@ ivas_error init_decoder_ivas_fx( #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED // To be removed when fixed version is available. initFdCngDec_flt(st_fx); #endif - ivas_initFdCngDec_fx(st_fx, st_fx->cldfbSyn_fx->scale); + ivas_initFdCngDec_fx(st_fx, st_fx->cldfbSyn->scale); } ELSE { @@ -2013,13 +2013,13 @@ void destroy_cldfb_decoder( /* CLDFB BPF & resampling tools */ /* delete analysis for max. SR 16kHz */ - deleteCldfb(&st_fx->cldfbAna_fx); + deleteCldfb(&st_fx->cldfbAna); /* delete analysis BPF for max. SR 16kHz */ - deleteCldfb(&st_fx->cldfbBPF_fx); + deleteCldfb(&st_fx->cldfbBPF); /* delete synthesis for output SR */ - deleteCldfb(&st_fx->cldfbSyn_fx); + deleteCldfb(&st_fx->cldfbSyn); deleteFdCngDec( &st_fx->hFdCngDec ); diff --git a/lib_dec/ivas_agc_dec_fx.c b/lib_dec/ivas_agc_dec_fx.c index c54fa9a1c680698b5466c3a2bc563e11a93dce0b..693ab84d811085d578bfe63852ab345786adf9bd 100644 --- a/lib_dec/ivas_agc_dec_fx.c +++ b/lib_dec/ivas_agc_dec_fx.c @@ -182,7 +182,7 @@ void ivas_agc_dec_process_fx( Word16 gainLast, gain; ivas_agc_dec_state_t *pState = hAgcDec; - offset = output_frame - pState->agc_com.in_delay; + offset = sub(output_frame, pState->agc_com.in_delay); FOR( i = 0; i < n_channels; i++ ) { @@ -191,8 +191,9 @@ void ivas_agc_dec_process_fx( IF( GT_16( pState->gain_state[i].gainExpVal, ( pState->agc_com.maxAttExp + 1 ) ) || LT_16( pState->gain_state[i].gainExpVal, -1 ) ) { /* Such conditions indicate packet loss, better reset and do nothing*/ - pState->gain_data[i].absGainExp = pState->agc_com.absEmin; + pState->gain_data[i].absGainExp = pState->agc_com.absEmin; move16(); pState->gain_state[i].gainExpVal = 0; + move16(); } // pState->gain_state[i].lastGain = powf( pState->agc_com.winFunc[offset - 1], ( -1.f * (float) ( pState->gain_data[i].absGainExp - pState->agc_com.absEmin ) ) ); @@ -202,6 +203,7 @@ void ivas_agc_dec_process_fx( IF( LT_16( tmp, 0 ) ) { tmp_2 = MAX_16; + move16(); FOR( idx = 0; idx < negate( tmp ); idx++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); @@ -211,12 +213,14 @@ void ivas_agc_dec_process_fx( ELSE { tmp_2 = MAX_16; + move16(); FOR( idx = 0; idx < ( tmp ); idx++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); } } pState->gain_state[i].lastGain_fx = tmp_2; + move16(); gainLast = div_l( ONE_IN_Q29, pState->gain_state[i].lastGain_fx ); // Q13 IF( NE_16( pState->gain_state[i].gainExpVal, 0 ) ) @@ -227,27 +231,27 @@ void ivas_agc_dec_process_fx( { // gain = powf( pState->agc_com.winFunc[idx - pState->agc_com.in_delay], (float) ( -1 * pState->gain_state[i].gainExpVal ) ) * gainLast; - tmp = negate( pState->gain_state[i].gainExpVal ); + tmp = negate( pState->gain_state[i].gainExpVal ); move16(); IF( LT_16( tmp, 0 ) ) { - tmp_2 = MAX_16; + tmp_2 = MAX_16; move16(); FOR( j = 0; j < negate( tmp ); j++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); } - if ( LT_16( tmp_2, 0 ) ) + IF ( LT_16( tmp_2, 0 ) ) { tmp_2 = div_l( ONE_IN_Q30, negate( tmp_2 ) ); // Q14 tmp_2 = negate( tmp_2 ); } - else + ELSE { tmp_2 = div_l( ONE_IN_Q30, tmp_2 ); // Q14 } } ELSE { - tmp_2 = MAX_16; + tmp_2 = MAX_16; move16(); FOR( j = 0; j < ( tmp ); j++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[idx - pState->agc_com.in_delay], tmp_2 ); @@ -265,10 +269,10 @@ void ivas_agc_dec_process_fx( } // pState->gain_state[i].lastGain *= powf( pState->agc_com.winFunc[offset - 1], (float) pState->gain_state[i].gainExpVal ); - tmp = pState->gain_state[i].gainExpVal; + tmp = pState->gain_state[i].gainExpVal; move16(); IF( LT_16( tmp, 0 ) ) { - tmp_2 = MAX_16; + tmp_2 = MAX_16; move16(); FOR( idx = 0; idx < negate( tmp ); idx++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); @@ -277,7 +281,7 @@ void ivas_agc_dec_process_fx( } ELSE { - tmp_2 = MAX_16; + tmp_2 = MAX_16; move16(); FOR( idx = 0; idx < ( tmp ); idx++ ) { tmp_2 = mult( pState->agc_com.winFunc_fx[offset - 1], tmp_2 ); @@ -294,7 +298,7 @@ void ivas_agc_dec_process_fx( pcm_out[i][idx] = Mpy_32_16_1( pcm_in[i][idx], gain ); // Q_pcm_out = Q_pcm_in - 3 } } - pState->gain_data[i].absGainExp = pState->gain_data[i].absGainExpCurr; + pState->gain_data[i].absGainExp = pState->gain_data[i].absGainExpCurr; move16(); } return; diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index c6bdc167ab04a25d691cc86cea7519e347e22b6c..e837afa779ae4b25e057cf3d0413083a4799dcda 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1408,14 +1408,6 @@ ivas_error ivas_core_dec( #ifdef IVAS_FLOAT_FIXED - IF( EQ_16( st->core, ACELP_CORE ) && st->bfi && st->hHQ_core != NULL && !st->con_tcx ) - { - 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 ) - { - return error; - } - } - ELSE { #ifndef IVAS_CODE_TO_BE_REMOVED @@ -1424,11 +1416,11 @@ ivas_error ivas_core_dec( /*------------------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; - } + 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; @@ -1445,7 +1437,7 @@ ivas_error ivas_core_dec( 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 ) + IF( p_output_mem != NULL ) { floatToFixed_arr( p_output_mem, output_mem_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); } @@ -1462,16 +1454,16 @@ ivas_error ivas_core_dec( Word16 delta = 1; move16(); - IF ( GE_16( output_frame, L_FRAME16k ) ) + IF( GE_16( output_frame, L_FRAME16k ) ) { delta = shr( Fs_kHz, 3 ); } Word16 delay_comp = i_mult2( delta, HQ_DELAY_COMP ); - if ( st->hBWE_FD != NULL ) + if ( st->hBWE_FD != NULL ) { - st->hBWE_FD->mem_deemph_old_syn_fx = floatToFixed( st->hBWE_FD->mem_deemph_old_syn, 0 ); + st->hBWE_FD->mem_deemph_old_syn_fx = (Word16)floatToFixed( st->hBWE_FD->mem_deemph_old_syn, 0 ); } IF( st->hHQ_core != NULL ) { @@ -1488,7 +1480,7 @@ ivas_error ivas_core_dec( if ( st->hTcxDec != NULL ) { - st->hTcxDec->conceal_eof_gain = floatToFixed( st->hTcxDec->conceal_eof_gain_float, 14); + 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*/ @@ -1515,12 +1507,54 @@ ivas_error ivas_core_dec( } /*-------------------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); + } + 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); + } + if (st->hGSCDec != NULL) + { + st->hGSCDec->Last_GSC_pit_band_idx_fx = st->hGSCDec->Last_GSC_pit_band_idx; + } + if (st->hMusicPF != NULL) + { + floatToFixed_arr(st->hMusicPF->dct_post_old_exc, st->hMusicPF->dct_post_old_exc_fx, st->Q_exc, DCT_L_POST - OFFSET2); + } + if (st->hBPF) { + floatToFixed_arr(st->hBPF->pst_old_syn, st->hBPF->pst_old_syn_fx, st->Q_syn2 - 1, NBPSF_PIT_MAX); + st->hBPF->pst_mem_deemp_err_fx = (Word16)floatToFixed(st->hBPF->pst_mem_deemp_err, st->Q_syn2 - 1); + floatToFixed_arr(st->hBPF->mem_mean_pit, st->hBPF->mem_mean_pit_fx, Q4, L_TRACK_HIST); + Copy(st->hBPF->Track_on_hist, st->hBPF->Track_on_hist_fx, L_TRACK_HIST); + Copy(st->hBPF->vibrato_hist, st->hBPF->vibrato_hist_fx, L_TRACK_HIST); + 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-------------------------*/ @@ -2282,6 +2316,25 @@ ivas_error ivas_core_dec( #endif } +#ifdef IVAS_FLOAT_FIXED + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + /*----------------------------------------------------------------* + * BFI waveform adjustment + *----------------------------------------------------------------*/ + + IF( EQ_16( st->core, ACELP_CORE ) && !st->bfi && st->prev_bfi && GE_32( st->last_total_brate, HQ_48k ) && EQ_16( st->last_codec_mode, MODE2 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_16( st->hPlcInfo->nbLostCmpt, 4 ) ) + { + tmps = NS2SA_fx2( output_Fs, DELAY_CLDFB_NS ); + + waveform_adj2_fix( st->hTonalMDCTConc->secondLastPcmOut, synth_16fx[n] + tmps, st->plcInfo.data_noise, &st->plcInfo.outx_new_n1_fx, + &st->plcInfo.nsapp_gain_fx, &st->plcInfo.nsapp_gain_n_fx, &st->plcInfo.recovery_gain, st->plcInfo.step_concealgain_fx, + st->plcInfo.Pitch_fx, st->plcInfo.FrameSize, tmps, st->hPlcInfo->nbLostCmpt + 1, st->bfi ); + + st->hPlcInfo->Pitch = 0; + } + } +#else if ( st->element_mode == EVS_MONO ) { /*----------------------------------------------------------------* @@ -2297,6 +2350,7 @@ ivas_error ivas_core_dec( st->hPlcInfo->Pitch = 0; } } +#endif // IVAS_FLOAT_FIXED /*----------------------------------------------------------------* * Transition and synchronization of BWE components @@ -3615,4 +3669,4 @@ ivas_error ivas_core_dec( pop_wmops(); return error; } -#endif \ No newline at end of file +#endif diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 24d27f7b8d0aec137c653ad632f64a51bd6e8352..3124e1bd9c53c17783df2fd5ce2ef23e9c26b0df 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -247,11 +247,11 @@ ivas_error ivas_dec_setup( IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, Q31, 3 ); TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); @@ -274,8 +274,8 @@ ivas_error ivas_dec_setup( Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { - fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); - fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, Q31, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, Q30, 3 ); } } FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) @@ -301,8 +301,8 @@ ivas_error ivas_dec_setup( Src_p->Gain = 1.0f; Src_p->prevGain = 1.0f; TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; - fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); - fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, Q31, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, Q30, 3 ); SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); @@ -394,11 +394,11 @@ ivas_error ivas_dec_setup( IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) { st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, Q31, 3 ); TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); @@ -421,8 +421,8 @@ ivas_error ivas_dec_setup( Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { - fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); - fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, Q31, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, Q30, 3 ); } } FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) @@ -448,8 +448,8 @@ ivas_error ivas_dec_setup( Src_p->Gain = 1.0f; Src_p->prevGain = 1.0f; TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; - fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); - fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, Q31, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, Q30, 3 ); SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 459e5cf587710647604fa8d2c9c5ffa995e713ae..42b70ab1c9312d7d57c218f00a35f2fb683f149b 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -220,11 +220,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( } #if 1 // Cleanup changes for ivas_td_binaural_open: fixed to float st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); - fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, Q31, 3 ); + fixedToFloat_arrL( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, Q31, 3 ); TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); @@ -247,8 +247,8 @@ static ivas_error ivas_ism_bitrate_switching_dec( Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { - fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); - fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, Q31, 3 ); + fixedToFloat_arrL( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, Q30, 3 ); } } FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) @@ -274,8 +274,8 @@ static ivas_error ivas_ism_bitrate_switching_dec( Src_p->Gain = 1.0f; Src_p->prevGain = 1.0f; TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; - fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); - fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, Q31, 3 ); + fixedToFloat_arrL( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, Q30, 3 ); SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index bec2e773b7ef1fdf83ca3f8f2584dadb51a80cae..48cea7061e6302822d7e59f1844e39a54cd6eb4a 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -109,6 +109,23 @@ static void ivas_ism_get_interpolator( return; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_ism_get_interpolator_fx( + const Word16 subframe_nbslots, + Word16 *interpolator ) +{ + Word16 interp_idx, q_tmp, tmp; + + FOR ( interp_idx = 0; interp_idx < subframe_nbslots; interp_idx++ ) + { + tmp = BASOP_Util_Divide1616_Scale(add(interp_idx, 1), subframe_nbslots, &q_tmp);/*Q = 15 - q_tmp*/ + interpolator[interp_idx] = shl_sat(tmp, q_tmp); /* Q15 */move16(); + } + + return; +} +#endif + static void ivas_ism_get_proto_matrix( IVAS_OUTPUT_SETUP hOutSetup, @@ -158,6 +175,55 @@ static void ivas_ism_get_proto_matrix( } +#ifdef IVAS_FLOAT_FIXED +static void ivas_ism_get_proto_matrix_fx( + IVAS_OUTPUT_SETUP hOutSetup, + const Word16 nchan_transport, + Word16 *proto_matrix ) +{ + Word16 idx; + + /* compute proto_matrix */ + SWITCH ( nchan_transport ) + { + case 2: + { + IF ( hOutSetup.nchan_out_woLFE ) + { + FOR ( idx = 0; idx < hOutSetup.nchan_out_woLFE; idx++ ) + { + IF (GT_32(hOutSetup.ls_azimuth_fx[idx], 0) ) + { + proto_matrix[idx] = shl_sat(ONE_IN_Q14, 1);move16(); + proto_matrix[idx + hOutSetup.nchan_out_woLFE] = 0;move16(); + } + ELSE IF ( LT_32(hOutSetup.ls_azimuth_fx[idx], 0) ) + { + proto_matrix[idx] = 0;move16(); + proto_matrix[idx + hOutSetup.nchan_out_woLFE] = shl_sat(ONE_IN_Q14, 1);move16(); + } + ELSE + { + proto_matrix[idx] = ONE_IN_Q14;/* 0.5 -> Q15*/move16(); + proto_matrix[idx + hOutSetup.nchan_out_woLFE] = ONE_IN_Q14;/* 0.5 -> Q15*/move16(); + } + } + } + ELSE + { + assert( 0 && "Error: number of output channels not supported" ); + } + BREAK; + } + + default: + assert( 0 && "Error: number of transport channels not supported" ); + } + + return; +} +#endif + static void ivas_param_ism_collect_slot( PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */ float *Cldfb_RealBuffer_in, @@ -516,11 +582,28 @@ static ivas_error ivas_param_ism_rendering_init( if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { /* computation of proto matrix */ +#ifdef IVAS_FLOAT_FIXED + ivas_ism_get_proto_matrix_fx( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix_fx ); + for ( int idx = 0; idx < hOutSetup.nchan_out_woLFE; idx++ ) + { + hParamIsmRendering->proto_matrix[idx] = (float)hParamIsmRendering->proto_matrix_fx[idx]/(1<<15); + hParamIsmRendering->proto_matrix[idx + hOutSetup.nchan_out_woLFE] = (float)hParamIsmRendering->proto_matrix_fx[idx + hOutSetup.nchan_out_woLFE]/(1<<15); + } +#else ivas_ism_get_proto_matrix( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix ); +#endif } /* computation of interpolator*/ +#ifdef IVAS_FLOAT_FIXED + ivas_ism_get_interpolator_fx( subframe_nbslots, hParamIsmRendering->interpolator_fx ); + for ( int i = 0; i < subframe_nbslots; i++ ) + { + hParamIsmRendering->interpolator[i] = (float)hParamIsmRendering->interpolator_fx[i]/(1<<15); + } +#else ivas_ism_get_interpolator( subframe_nbslots, hParamIsmRendering->interpolator ); +#endif // IVAS_FLOAT_FIXED return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 1335b4aa11251580ec7f13567ccea25892138942..3d4d4c9d9ccc2ea8f4898cedb65fc6568ab17f9b 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1161,8 +1161,32 @@ ivas_error ivas_jbm_dec_tc( ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); } else if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame ); + { +#ifdef IVAS_FLOAT_FIXED + Word16 size = st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; + if (st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport == 3) + size += 1; + + FOR(Word16 i = 0; i < size; i++) + { + FOR(Word16 j = 0; j < output_frame; j++) + { + p_output_fix[i][j] = (Word32)(p_output[i][j] * ONE_IN_Q14); + } + } + + ivas_spar_dec_agc_pca_fx( st_ivas, p_output_fix, output_frame ); + + FOR(Word16 i = 0; i < size; i++) + { + FOR(Word16 j = 0; j < output_frame; j++) + { + p_output[i][j] = (float)p_output_fix[i][j] / ONE_IN_Q11; + } + } +#else + ivas_spar_dec_agc_pca(st_ivas, p_output, output_frame); +#endif } } @@ -2107,7 +2131,31 @@ ivas_error ivas_jbm_dec_tc( } else if ( st_ivas->renderer_type != RENDERER_DISABLE && !st_ivas->sba_dirac_stereo_flag ) { - ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame ); +#ifdef IVAS_FLOAT_FIXED + Word16 size = st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport + sba_ch_idx; + if (size == 3) + size += 1; + + FOR(Word16 i = sba_ch_idx; i < size; i++) + { + FOR(Word16 j = 0; j < output_frame; j++) + { + p_output_fix[i][j] = (Word32)(p_output[i][j] * ONE_IN_Q14); + } + } + + ivas_spar_dec_agc_pca_fx( st_ivas, &p_output_fix[sba_ch_idx], output_frame ); + + FOR(Word16 i = sba_ch_idx; i < size; i++) + { + FOR(Word16 j = 0; j < output_frame; j++) + { + p_output[i][j] = (float)p_output_fix[i][j] / ONE_IN_Q11; + } + } +#else + ivas_spar_dec_agc_pca(st_ivas, &p_output[sba_ch_idx], output_frame); +#endif } if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) @@ -3816,7 +3864,11 @@ ivas_error ivas_jbm_dec_render( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4196,7 +4248,11 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4558,7 +4614,11 @@ ivas_error ivas_jbm_dec_flush_renderer( /* Binaural rendering */ if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4746,7 +4806,11 @@ ivas_error ivas_jbm_dec_flush_renderer( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4795,7 +4859,11 @@ ivas_error ivas_jbm_dec_flush_renderer( if ( st_ivas->nchan_ism > 0 ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 69116e3b70b43b044f77735fc5289d2150c071c1..f48a262c352a72911069d0ea6d7c2b06e0f9562a 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -39,13 +39,15 @@ #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) +#define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) ) +#define fixed_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) #endif + /*---------------------------------------------------------------------* * ivas_td_binaural_open() * @@ -265,7 +267,7 @@ ivas_error ivas_td_binaural_renderer_sf( for ( j = 0; j < ( ( 0 + 1 ) * hReverb->full_block_size ); j++ ) { - pcm_in_fx[i][j] = (Word32) float_to_fix( tc_local[i][j], exp ); + pcm_in_fx[i][j] = (Word32) float_to_fixed( tc_local[i][j], exp ); } } for ( i = 0; i < BINAURAL_CHANNELS; i++ ) @@ -277,7 +279,7 @@ ivas_error ivas_td_binaural_renderer_sf( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - pcm_out_fx[i][0 * hReverb->full_block_size + j] = (Word32) float_to_fix( p_reverb_signal[i][0 * hReverb->full_block_size + j], ( exp ) ); + pcm_out_fx[i][0 * hReverb->full_block_size + j] = (Word32) float_to_fixed( p_reverb_signal[i][0 * hReverb->full_block_size + j], ( exp ) ); } } @@ -295,7 +297,7 @@ ivas_error ivas_td_binaural_renderer_sf( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - p_reverb_signal[i][0 * hReverb->full_block_size + j] = fix_to_float( pcm_out_fx[i][0 * hReverb->full_block_size + j], ( exp - 2 ) ); + p_reverb_signal[i][0 * hReverb->full_block_size + j] = fixed_to_float( pcm_out_fx[i][0 * hReverb->full_block_size + j], ( exp - 2 ) ); } } #endif @@ -335,3 +337,397 @@ ivas_error ivas_td_binaural_renderer_sf( return IVAS_ERR_OK; } + +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_td_binaural_renderer_sf_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ +) +{ +#define FIXED_CODE_WIP +#ifdef FIXED_CODE_WIP + Word32 output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; + for (int i = 0; i < st_ivas->hDecoderConfig->nchan_out; i++) + { + for (int j = 0; j < L_FRAME48k; j++) + { + output_fx[i][j] = floatToFixed(output[i][j], Q11); + } + } +#endif + + Word16 first_sf, last_sf, subframe_idx; + float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float *p_reverb_signal[BINAURAL_CHANNELS]; + float *output_f_local[BINAURAL_CHANNELS]; + float *tc_local[MAX_TRANSPORT_CHANNELS]; + Word32 reverb_signal_fx[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 *output_fx_local[BINAURAL_CHANNELS]; + Word32 *p_reverb_signal_fx[BINAURAL_CHANNELS]; + Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS]; + Word16 ch, slot_size, slots_to_render, output_frame, tmp; + ivas_error error; + + Word16 ism_md_subframe_update_jbm; + Word16 c_indx, nS; + Word16 nchan_ism_internal, nchan_ism, ch_offset; + + /* Set the number of ISMs */ + IF ( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + nchan_ism_internal = st_ivas->nchan_ism; + move16(); + nchan_ism = st_ivas->nchan_ism; + move16(); + ch_offset = 2; + move16(); + } + ELSE IF ( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) + { + nchan_ism_internal = st_ivas->nchan_ism; + move16(); + nchan_ism = st_ivas->nchan_ism; + move16(); + ch_offset = 0; + move16(); + } + ELSE + { + nchan_ism_internal = st_ivas->hTcBuffer->nchan_transport_internal; + move16(); + nchan_ism = st_ivas->nchan_transport; + move16(); + ch_offset = 0; + move16(); + } + + /* Number of subframes to delay metadata to sync with audio */ + IF( st_ivas->hDecoderConfig->Opt_delay_comp ) + { + ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 3 ) ); + } + ELSE + { + ism_md_subframe_update_jbm = sub( st_ivas->hTcBuffer->nb_subframes, 2 ); + } + + IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) ) + { + ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 2 ) ); + } + + FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_reverb_signal[ch] = reverb_signal[ch]; +#ifdef FIXED_CODE_WIP + p_reverb_signal_fx[ch] = reverb_signal_fx[ch]; +#endif + } + + FOR( ch = 0; ch < nchan_ism_internal; ch++ ) + { + tc_local[ch] = st_ivas->hTcBuffer->tc[ch + ch_offset] + st_ivas->hTcBuffer->n_samples_rendered; +#ifdef FIXED_CODE_WIP + tc_local_fx[ch] = st_ivas->hTcBuffer->tc_fx[ch + ch_offset] + st_ivas->hTcBuffer->n_samples_rendered; +#endif + } + + FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + output_f_local[ch] = output[ch]; +#ifdef FIXED_CODE_WIP + output_fx_local[ch] = output_fx[ch]; +#endif + } + + slot_size = st_ivas->hTcBuffer->n_samples_granularity; + move16(); + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + tmp = 0; + IF(n_samples_granularity != 0) + { + tmp = idiv1616(n_samples_granularity, slot_size); + } + slots_to_render = s_min( sub( st_ivas->hTcBuffer->num_slots, st_ivas->hTcBuffer->slots_rendered ), tmp ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + move16(); + last_sf = first_sf; + move16(); + st_ivas->hTcBuffer->slots_rendered = add(st_ivas->hTcBuffer->slots_rendered, slots_to_render); + + WHILE( slots_to_render > 0 ) + { + slots_to_render = sub(slots_to_render, st_ivas->hTcBuffer->subframe_nbslots[last_sf]); + last_sf = add(last_sf, 1); + } + + FOR ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + output_frame = i_mult( st_ivas->hTcBuffer->subframe_nbslots[subframe_idx], st_ivas->hTcBuffer->n_samples_granularity ); + + /* Update object position(s) */ + c_indx = 0; + move16(); + + FOR( nS = 0; nS < nchan_ism; nS++ ) + { + IF( !( EQ_16( st_ivas->ivas_format, MC_FORMAT ) && EQ_16( nS, LFE_CHANNEL ) ) ) /* Skip LFE for MC */ + { + st_ivas->hBinRendererTd->Sources[c_indx]->InputFrame_p = tc_local[nS]; +#ifdef FIXED_CODE_WIP + st_ivas->hBinRendererTd->Sources[c_indx]->InputFrame_p_fx = tc_local_fx[nS]; +#endif + st_ivas->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; + move16(); + c_indx = add(c_indx, 1); + } + } + IF ( EQ_16( subframe_idx, ism_md_subframe_update_jbm ) ) + { +#ifdef FIXED_CODE_WIP + if (st_ivas->hBinRendererTd != NULL) + { + st_ivas->hBinRendererTd->DirAtten_p->ConeInnerAngle_fx = float_to_fix16(st_ivas->hBinRendererTd->DirAtten_p->ConeInnerAngle, Q6); + st_ivas->hBinRendererTd->DirAtten_p->ConeOuterAngle_fx = float_to_fix16(st_ivas->hBinRendererTd->DirAtten_p->ConeOuterAngle, Q6); + st_ivas->hBinRendererTd->DirAtten_p->ConeOuterGain_fx = float_to_fix16(st_ivas->hBinRendererTd->DirAtten_p->ConeOuterGain, Q15); + IF(st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT) + { + FOR(int nS1 = 0; nS1 < nchan_ism; nS1++) + { + st_ivas->hIsmMetaData[nS1]->radius_fx = float_to_fix16(st_ivas->hIsmMetaData[nS1]->radius, Q9); + st_ivas->hIsmMetaData[nS1]->azimuth_fx = float_to_fix(st_ivas->hIsmMetaData[nS1]->azimuth, Q22); + st_ivas->hIsmMetaData[nS1]->elevation_fx = float_to_fix(st_ivas->hIsmMetaData[nS1]->elevation, Q22); + st_ivas->hIsmMetaData[nS1]->yaw_fx = float_to_fix(st_ivas->hIsmMetaData[nS1]->yaw, Q22); + st_ivas->hIsmMetaData[nS1]->pitch_fx = float_to_fix(st_ivas->hIsmMetaData[nS1]->pitch, Q22); + } + } + } + + IF ( ( error = TDREND_Update_object_positions_fx( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) + { + return error; + } + + // Fixed to float // + if (st_ivas->hBinRendererTd != NULL) + { + IF(st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT) + { + FOR(int nS1 = 0; nS1 < nchan_ism; nS1++) + { + st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeInnerAngle = fix16_to_float(st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeInnerAngle_fx, Q6); + st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeOuterAngle = fix16_to_float(st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeOuterAngle_fx, Q6); + st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeOuterGain = fix16_to_float(st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->DirAtten.ConeOuterGain_fx, Q15); + FOR(int i = 0; i < 3; i++) + { + st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->Pos_p[i] = fix_to_float(st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->Pos_p_fx[i], Q25 ); + st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->Front_p[i] = fix_to_float(st_ivas->hBinRendererTd->Sources[nS1]->SrcSpatial_p->Front_p_fx[i], Q30 ); // This is actually a normalised vector. can be scaled to Q14 (since it includes 1.0f) + } + } + } + } +#else + IF ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + } + + /* Update the listener's location/orientation */ +#ifdef FIXED_CODE_WIP + IVAS_QUATERNION_FX *tmp_Quaternion_fx; + IVAS_QUATERNION *tmp_Quaternion; + IVAS_VECTOR3_FX *tmp_vector_fx; + IVAS_VECTOR3 *tmp_vector; + Word16 enableCombinedOrientation = 0; + /////////////////////////////////////////// Float to fixed starts here /////////////////////////////////////////// + if (st_ivas->hCombinedOrientationData != NULL) + { + // For Quaternion + tmp_Quaternion = &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx]; + tmp_Quaternion_fx = &st_ivas->hCombinedOrientationData->Quaternions_fx[st_ivas->hCombinedOrientationData->subframe_idx]; + float max_val = 0; + max_val = (float)max(max_val, fabs(tmp_Quaternion->w)); + max_val = (float)max(max_val, fabs(tmp_Quaternion->x)); + max_val = (float)max(max_val, fabs(tmp_Quaternion->y)); + max_val = (float)max(max_val, fabs(tmp_Quaternion->z)); + Word16 quat_q = Q_factor_L(max_val); + tmp_Quaternion_fx->w_fx = (Word32)float_to_fix(tmp_Quaternion->w, quat_q); + tmp_Quaternion_fx->x_fx = (Word32)float_to_fix(tmp_Quaternion->x, quat_q); + tmp_Quaternion_fx->y_fx = (Word32)float_to_fix(tmp_Quaternion->y, quat_q); + tmp_Quaternion_fx->z_fx = (Word32)float_to_fix(tmp_Quaternion->z, quat_q); + tmp_Quaternion_fx->w_qfact = tmp_Quaternion_fx->x_qfact = tmp_Quaternion_fx->y_qfact = tmp_Quaternion_fx->z_qfact = quat_q; + // For Vector + tmp_vector = &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx]; + tmp_vector_fx = &st_ivas->hCombinedOrientationData->listenerPos_fx[st_ivas->hCombinedOrientationData->subframe_idx]; + Word16 pos_q = Q25; + tmp_vector_fx->x_fx = (Word32)float_to_fix(tmp_vector->x, pos_q); + tmp_vector_fx->y_fx = (Word32)float_to_fix(tmp_vector->y, pos_q); + tmp_vector_fx->z_fx = (Word32)float_to_fix(tmp_vector->z, pos_q); + tmp_vector_fx->x_qfact = tmp_vector_fx->y_qfact = tmp_vector_fx->z_qfact = pos_q; + // For enableCombinedOrientation + enableCombinedOrientation = st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx]; + } + for (int i = 0; i < 3; i++) + { + st_ivas->hBinRendererTd->Listener_p->Front_fx[i] = float_to_fix(st_ivas->hBinRendererTd->Listener_p->Front[i], Q30); + st_ivas->hBinRendererTd->Listener_p->Up_fx[i] = float_to_fix(st_ivas->hBinRendererTd->Listener_p->Up[i], Q30); + st_ivas->hBinRendererTd->Listener_p->Right_fx[i] = float_to_fix(st_ivas->hBinRendererTd->Listener_p->Right[i], Q30); + + st_ivas->hBinRendererTd->Listener_p->Pos_q = Q25; + st_ivas->hBinRendererTd->Listener_p->Pos_fx[i] = float_to_fix(st_ivas->hBinRendererTd->Listener_p->Pos[i], st_ivas->hBinRendererTd->Listener_p->Pos_q); + } + /////////////////////////////////////////// Float to fixed ends here /////////////////////////////////////////// + + IF(st_ivas->hCombinedOrientationData != NULL) + { + tmp_Quaternion_fx = &st_ivas->hCombinedOrientationData->Quaternions_fx[st_ivas->hCombinedOrientationData->subframe_idx]; + tmp_vector_fx = &st_ivas->hCombinedOrientationData->listenerPos_fx[st_ivas->hCombinedOrientationData->subframe_idx]; + enableCombinedOrientation = st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx]; + } + ELSE + { + tmp_Quaternion_fx = NULL; + tmp_vector_fx = NULL; + enableCombinedOrientation = 0; + } + + if ( ( error = TDREND_Update_listener_orientation_fx( st_ivas->hBinRendererTd, + enableCombinedOrientation, + tmp_Quaternion_fx, + tmp_vector_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + + /////////////////////////////////////////// Fixed to float starts here /////////////////////////////////////////// + for (int i = 0; i < 3; i++) + { + st_ivas->hBinRendererTd->Listener_p->Front[i] = fix_to_float(st_ivas->hBinRendererTd->Listener_p->Front_fx[i], Q30); + st_ivas->hBinRendererTd->Listener_p->Up[i] = fix_to_float(st_ivas->hBinRendererTd->Listener_p->Up_fx[i], Q30); + st_ivas->hBinRendererTd->Listener_p->Right[i] = fix_to_float(st_ivas->hBinRendererTd->Listener_p->Right_fx[i], Q30); + st_ivas->hBinRendererTd->Listener_p->Pos[i] = fix_to_float(st_ivas->hBinRendererTd->Listener_p->Pos_fx[i], st_ivas->hBinRendererTd->Listener_p->Pos_q); + } + /////////////////////////////////////////// Fixed to float ends here ///////////////////////////////////////////// +#else + if ( ( error = TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] : 0, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx] : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx] : NULL ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + if ( st_ivas->hRenderConfig != NULL && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { +#ifdef IVAS_FLOAT_FIXED + Word16 i,j,exp; + Word32 pcm_in_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + Word32 pcm_out_buff[BINAURAL_CHANNELS][L_FRAME48k]; + Word32 *pcm_in_fx[MAX_OUTPUT_CHANNELS]; + Word32 *pcm_out_fx[BINAURAL_CHANNELS]; + Word16 nchan_transport = audioCfg2channels( st_ivas->transport_config ); + REVERB_HANDLE hReverb = st_ivas->hReverb; + exp = Q7; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + pcm_in_fx[i] = pcm_in_buff[i]; + } + for ( i = 0; i < nchan_transport; i++ ) + { + + for ( j = 0; j < ( ( 0 + 1 ) * hReverb->full_block_size ); j++ ) + { + + pcm_in_fx[i][j] = (Word32) float_to_fixed( tc_local[i][j], exp ); + } + } + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + pcm_out_fx[i] = pcm_out_buff[i]; + } + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + + for ( j = 0; j < ( hReverb->full_block_size ); j++ ) + { + pcm_out_fx[i][0 * hReverb->full_block_size + j] = (Word32) float_to_fixed( p_reverb_signal[i][0 * hReverb->full_block_size + j], ( exp ) ); + } + } + + if ( ( error = ivas_reverb_process_fx( st_ivas->hReverb, st_ivas->transport_config, 0, pcm_in_fx, pcm_out_fx, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_reverb_process( st_ivas->hReverb, st_ivas->transport_config, 0, tc_local, p_reverb_signal, 0 ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + + for ( j = 0; j < ( hReverb->full_block_size ); j++ ) + { + + p_reverb_signal[i][0 * hReverb->full_block_size + j] = fixed_to_float( pcm_out_fx[i][0 * hReverb->full_block_size + j], ( exp - 2 ) ); + } + } +#endif + } + + /* Render subframe */ + /* ism_md_subframe_update_jbm != subframe_idx: trigger update only for ism_md_subframe_update_jbm == subframe_idx, + where then the two TDREND_GetMix()-arguments subframe_idx and ism_md_subframe_update are equal, and we want to enforce the update inside TDREND_GetMix to use subframe_idx == 0 */ +#ifdef IVAS_FLOAT_FIXED + if ( ( error = TDREND_GetMix_fx( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm != subframe_idx ) ) != IVAS_ERR_OK ) + { + return error; + } +#else + if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0, ism_md_subframe_update_jbm != subframe_idx ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + if ( st_ivas->hRenderConfig != NULL && st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + /* add reverb to rendered signals */ + v_add( reverb_signal[0], output_f_local[0], output_f_local[0], output_frame ); + v_add( reverb_signal[1], output_f_local[1], output_f_local[1], output_frame ); + } + + + for ( ch = 0; ch < nchan_ism_internal; ch++ ) + { + tc_local[ch] += output_frame; + } + + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + output_f_local[ch] += output_frame; + } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, output_frame ); + } + + st_ivas->hTcBuffer->subframes_rendered = last_sf; + +#ifdef FIXED_CODE_WIP + for (int i = 0; i < st_ivas->hDecoderConfig->nchan_out; i++) + { + for (int j = 0; j < L_FRAME48k; j++) + { + output[i][j] = fixedToFloat(floatToFixed(output[i][j], Q11),Q11); + } + } +#endif + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 82a19c7b1731f67f5e21ba3849d5fda7b12f3ba1..e57d0325c01e205515e08546726e4cc82a7926a0 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -1409,10 +1409,17 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( /* reset combined orientation access index before calling the td renderer */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } +#endif for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index f5ff2bcdf2a85f3b7640e40c6e92be6b15baa8b6..9e1b817a922c192b51e3911ad1c96f07d5c9e244 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -38,6 +38,7 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "wmc_auto.h" +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* @@ -148,8 +149,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( } - +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c new file mode 100644 index 0000000000000000000000000000000000000000..5c35be2c3d60d3dc83d2b99f2cb0f49af8d49c58 --- /dev/null +++ b/lib_dec/ivas_pca_dec_fx.c @@ -0,0 +1,320 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot.h" +#include "ivas_prot.h" +#include +#include "ivas_cnst.h" +#include "wmc_auto.h" +#include "prot_fx2.h" +#include "math.h" + +/*-----------------------------------------------------------------------* + * Local function definitions + *-----------------------------------------------------------------------*/ + +static Word32 ivas_bitstream_read_int32_fx( + Decoder_State *st0, + const Word16 bits ) +{ + Word32 val; + + /* MSB */ + val = get_next_indice_fx( st0, bits - 16 ) << 16; + + /* + LSB */ + val += get_next_indice_fx( st0, 16 ); + + return val; +} + +static void pca_dec_reset_dquat_fx( + Word16 *ql_fx, + Word16 *qr_fx ) +{ + set16_fx( ql_fx, 0, IVAS_PCA_INTERP ); + ql_fx[0] = 32767; + move16(); + set16_fx( qr_fx, 0, IVAS_PCA_INTERP ); + qr_fx[0] = 32767; + move16(); + return; +} + + +static void pca_dec_reset_mem_eigvec_fx( + PCA_DEC_STATE *hPCA ) +{ + Word16 i; + + FOR( i = 0; i < shr( IVAS_PCA_LEN_INTERP_EIG_DEC, 4 ); i++ ) + { + eye_matrix_fx( &hPCA->mem_eigVec_interp_fx[16 * i], FOA_CHANNELS, 32767 ); + } + + return; +} + + +static void pca_inv_transform_sub_fx( + Word16 *eigVec, + Word32 *transformed_data[], /* i : input/transformed audio channels */ + const Word16 start, + const Word16 len, + const Word16 n_channels ) +{ + Word16 i, j, k; + Word32 temp, temp2; + Word32 buffer_data[FOA_CHANNELS]; + + FOR( j = 0; j < len; j++ ) + { + FOR( k = 0; k < n_channels; k++ ) + { + buffer_data[k] = transformed_data[k][j + start]; + move32(); + } + + FOR( k = 0; k < n_channels; k++ ) + { + temp = 0; + FOR( i = 0; i < n_channels; i++ ) + { + temp2 = Mpy_32_16_1(buffer_data[i], eigVec[k * IVAS_PCA_INTERP + i]); + temp = L_add( temp, temp2 ); + } + transformed_data[k][j + start] = temp; + move32(); + } + } + + return; +} + + +static void pca_dec_inv_transform_fx( + PCA_DEC_STATE *hPCA, + Word16 *ql_fx, + Word16 *qr_fx, + const Word16 n_samples, + const Word16 n_channels, + Word32 *decoded_data[] ) +{ + Word16 j; + Word16 slot_len; + Word16 ql_interp_fx[IVAS_PCA_LEN_INTERP_Q], qr_interp_fx[IVAS_PCA_LEN_INTERP_Q]; + // todo : updtate prev buffer, find Q + quat_shortestpath_fx( hPCA->prev_ql_fx, ql_fx, hPCA->prev_qr_fx, qr_fx ); + + pca_interp_preproc_fx( hPCA->prev_ql_fx, hPCA->prev_qr_fx, ql_fx, qr_fx, IVAS_PCA_N_SLOTS, ql_interp_fx, qr_interp_fx ); + + slot_len = (Word16) ( n_samples / IVAS_PCA_N_SLOTS ); + move16(); + for ( j = 0; j < IVAS_PCA_N_SLOTS; j++ ) + { + /* convert from double quaternion to 4D matrix */ + dquat2mat_fx( &ql_interp_fx[4 * j], &qr_interp_fx[4 * j], &hPCA->mem_eigVec_interp_fx[16 * j + IVAS_PCA_DELAY_CMP * 16] ); + + pca_inv_transform_sub_fx( &hPCA->mem_eigVec_interp_fx[16 * j], decoded_data, slot_len * j, slot_len, n_channels ); + } + + return; +} + +static void pca_dec_update_dquat_fx( + PCA_DEC_STATE *hPCA, + const Word16 *ql_fx, + const Word16 *qr_fx ) +{ + /* update state for next frame */ + Copy( qr_fx, hPCA->prev_qr_fx, IVAS_PCA_INTERP ); + Copy( ql_fx, hPCA->prev_ql_fx, IVAS_PCA_INTERP ); + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_pca_dec_init_fx() + * + * Initialize PCA decoder + *------------------------------------------------------------------------*/ + + +void ivas_pca_dec_init_fx( + PCA_DEC_STATE *hPCA /* i/o: PCA decoder structure */ +) +{ + pca_dec_reset_dquat_fx( hPCA->prev_ql_fx, hPCA->prev_qr_fx ); + pca_dec_reset_mem_eigvec_fx( hPCA ); + + /* set counter saturated to 2 frames */ + hPCA->prev_pca_bypass = 2; + move16(); + return; +} +/*------------------------------------------------------------------------- + * ivas_pca_read_bits_fx() + * + * Decode PCA indexes + *------------------------------------------------------------------------*/ + +void ivas_pca_read_bits_fx( + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + PCA_DEC_STATE *hPCA ) +{ + /*first bit in the PCA payload (first bit after 3 header bits) signals bypass/active*/ + hPCA->pca_bypass = get_next_indice_fx( st0, 1 ); + move16(); + IF( hPCA->pca_bypass == PCA_MODE_INACTIVE ) + { + return; + } + + hPCA->index[0] = ivas_bitstream_read_int32_fx( st0, IVAS_PCA_QBITS - 1 ); + move32(); + hPCA->index[1] = ivas_bitstream_read_int32_fx( st0, IVAS_PCA_QBITS ); + move32(); + + return; +} + +/*------------------------------------------------------------------------- + * ivas_pca_dec_fx() + * + * PCA decoder + *------------------------------------------------------------------------*/ + +void ivas_pca_dec_fx( + PCA_DEC_STATE *hPCA, /* i/o: PCA decoder structure */ + const Word16 output_frame, /* i : output frame length */ + const Word16 n_channels, /* i : number of channels */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word32 last_ivas_total_brate, /* i : last IVAS total bitrate */ + const Word16 bfi, /* i : bad frame indicator */ + Word32 *pcm_out_fx[] /* o : output audio channels */ +) +{ + Word16 ql_fx[IVAS_PCA_INTERP], qr_fx[IVAS_PCA_INTERP]; + Word16 pca_bypass; + // todo : check if mem_eigVec_interp_fx values are being updated / add loop to update + Copy( &hPCA->mem_eigVec_interp_fx[IVAS_PCA_N_SLOTS * 16], hPCA->mem_eigVec_interp_fx, IVAS_PCA_DELAY_CMP * 16 ); + + /* @@@TODO: check how ivas_total_brate is set if bfi == 1 */ // ToDo: and what happens in DTX where "ivas_total_brate" can be close to zero? + + /* handle bit rate switching */ + IF( NE_32(ivas_total_brate, PCA_BRATE) || ( EQ_32(ivas_total_brate, PCA_BRATE) && GT_16( n_channels, FOA_CHANNELS) ) ) + { + /* set PCA by-pass mode in current frame and interpolate transform as previous frame used PCA */ + pca_dec_reset_dquat_fx( ql_fx, qr_fx ); + + IF( ( NE_32(last_ivas_total_brate, PCA_BRATE) ) || ( EQ_32(last_ivas_total_brate, PCA_BRATE) && GT_16(hPCA->prev_pca_bypass, 1) ) ) + { + pca_dec_reset_mem_eigvec_fx( hPCA ); + } + ELSE + { + pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + } + + pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + hPCA->prev_pca_bypass = add(hPCA->prev_pca_bypass, 1); + move16(); + + IF( GT_16(hPCA->prev_pca_bypass, 2 )) + { + hPCA->prev_pca_bypass = 2; + move16(); + } + + return; + } + + IF( !bfi ) + { + /* set PCA by-pass mode indicator */ + pca_bypass = hPCA->pca_bypass; + move16(); + } + ELSE + { + pca_bypass = hPCA->prev_pca_bypass; + move16(); + } + + IF( EQ_16(pca_bypass, PCA_MODE_INACTIVE )) + { + pca_dec_reset_dquat_fx( ql_fx, ql_fx ); + + IF( GT_16(hPCA->prev_pca_bypass, 1 )) //&& (hPCA->pca_off_hangover == 0)) + { + /* copy input data into output directly as previous frame was already in by-pass mode */ + pca_dec_reset_mem_eigvec_fx( hPCA ); + } + ELSE + { + pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + } + + pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + + hPCA->prev_pca_bypass = add(hPCA->prev_pca_bypass , 1); + hPCA->prev_pca_bypass = min( hPCA->prev_pca_bypass, 2 ); + move16(); + return; // exit happens here + } + + IF( !bfi ) + { + pca_dec_s3_fx( hPCA->index[0], ql_fx ); + pca_dec_s3_fx( hPCA->index[1], ql_fx ); + } + ELSE + { + /* freeze */ + // todo : check if update of prev_ql_fx is required + Copy( hPCA->prev_ql_fx, ql_fx, IVAS_PCA_INTERP ); + Copy( hPCA->prev_qr_fx, ql_fx, IVAS_PCA_INTERP ); + } + pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + + /* update for next frame */ + pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + + hPCA->prev_pca_bypass = 0; + move16(); + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 324143705c72482cd69f97f4fff607aedadddc1f..f509541076b824b1b90c9ef8c36c37692cd3b8e3 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -342,6 +342,10 @@ ivas_error ivas_sba_dec_reconfigure( } ivas_pca_dec_init( hSpar->hPCA ); +#ifdef IVAS_FLOAT_FIXED + ivas_pca_dec_init_fx(hSpar->hPCA); +#endif + } ivas_spar_config( ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, st_ivas->sid_format ); diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index a2fbfb68e6ecf9d8a9dd736b4ea39a14ed3d7d8c..c7b648968ee87f02e3b76fd2c058c27d0aefbf77 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -171,6 +171,10 @@ ivas_error ivas_spar_dec_open( } ivas_pca_dec_init( hSpar->hPCA ); +#ifdef IVAS_FLOAT_FIXED + ivas_pca_dec_init_fx(hSpar->hPCA); +#endif + } /* mixer_mat intitialization */ @@ -1353,7 +1357,12 @@ static ivas_error ivas_spar_dec_MD( if ( hSpar->hPCA != NULL ) { - ivas_pca_read_bits( st0, hSpar->hPCA ); +#ifdef IVAS_FLOAT_FIXED + ivas_pca_read_bits_fx(st0, hSpar->hPCA); +#else + ivas_pca_read_bits(st0, hSpar->hPCA); +#endif + } /*---------------------------------------------------------------------* @@ -1954,6 +1963,63 @@ void ivas_spar_dec_agc_pca( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_spar_dec_agc_pca_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Word32 *output[], /* i/o: input/output audio channels */ + const Word16 output_frame /* i : output frame length */ +) +{ + Word16 nchan_transport; + Word16 num_in_ingest; + DECODER_CONFIG_HANDLE hDecoderConfig; + SPAR_DEC_HANDLE hSpar; + + push_wmops( "ivas_spar_dec_agc_pca" ); + + hSpar = st_ivas->hSpar; + hDecoderConfig = st_ivas->hDecoderConfig; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; move16(); + + IF ( GE_16(st_ivas->nchan_transport, 3 )) + { + Word32 temp; + Word16 i; + /*convert WYZX downmix to WYXZ*/ + FOR ( i = 0; i < output_frame; i++ ) + { + temp = output[2][i]; move32(); + output[2][i] = output[3][i]; move32(); + output[3][i] = temp; move32(); + } + } + + IF ( hSpar->hMdDec->td_decorr_flag ) + { + num_in_ingest = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); + move16(); + } + ELSE + { + num_in_ingest = nchan_transport; + move16(); + } + + /*---------------------------------------------------------------------* + * AGC + *---------------------------------------------------------------------*/ + + ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output ), ( output ), nchan_transport, output_frame ); + + IF ( hSpar->hPCA != NULL ) + { + ivas_pca_dec_fx( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); + } + pop_wmops(); + + return; +} +#endif /*-------------------------------------------------------------------* * ivas_spar_dec_set_render_map() diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 1fd5d06e8152cc16fc6a906dc2c627b3b04aac56..ca22eedf27c49ba2d21faa0645aa1b5a560f16f5 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -898,7 +898,9 @@ typedef struct /* parser output: */ int16_t pca_bypass; int32_t index[2]; - + Word16 prev_ql_fx[IVAS_PCA_INTERP]; + Word16 prev_qr_fx[IVAS_PCA_INTERP]; + Word16 mem_eigVec_interp_fx[IVAS_PCA_LEN_INTERP_EIG_DEC]; } PCA_DEC_STATE; diff --git a/lib_dec/post_dec_fx.c b/lib_dec/post_dec_fx.c index e4a278bc44c35ccdd37573676caf3727e445506b..03ea35e08020d0cc88568baf9a8d7f289eff9788 100644 --- a/lib_dec/post_dec_fx.c +++ b/lib_dec/post_dec_fx.c @@ -498,7 +498,7 @@ void cldfb_synth_set_bandsToZero( move16(); } - FOR (i = 0; i < (st->cldfbSyn_fx->no_channels - st->cldfbSyn_fx->bandsToZero); i++) + FOR (i = 0; i < (st->cldfbSyn->no_channels - st->cldfbSyn->bandsToZero); i++) { nrgQ31 = 0; move32(); @@ -524,7 +524,7 @@ void cldfb_synth_set_bandsToZero( move16(); } } - FOR(; i < st->cldfbSyn_fx->no_channels; i++) + FOR(; i < st->cldfbSyn->no_channels; i++) { nrg_band[i] = 0; move16(); @@ -595,7 +595,7 @@ void cldfb_synth_set_bandsToZero( { IF( (st->perc_bwddec >= perc_detect || (st->perc_bwddec >= perc_miss && st->last_flag_filter_NB)) && (sum16_fx(st->flag_buffer, WBcnt) != 0)) /*decision hysterysis*/ { - st->cldfbSyn_fx->bandsToZero = sub( st->cldfbSyn_fx->no_channels, 10 ); + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, 10 ); move16(); st->last_flag_filter_NB = 1; move16(); /*VAD processing must be dependent on hysterysis, as if hysterysis fails, but threshold passes, we dont want next vad frames to have NB only*/ @@ -626,7 +626,7 @@ void cldfb_synth_set_bandsToZero( { IF(st->last_flag_filter_NB == 1) { - st->cldfbSyn_fx->bandsToZero = st->last_active_bandsToZero_bwdec; + st->cldfbSyn->bandsToZero = st->last_active_bandsToZero_bwdec; move16(); } st->total_frame_cnt_bwddec = add(st->total_frame_cnt_bwddec, 1); @@ -637,7 +637,7 @@ void cldfb_synth_set_bandsToZero( } } - st->last_active_bandsToZero_bwdec = st->cldfbSyn_fx->bandsToZero; + st->last_active_bandsToZero_bwdec = st->cldfbSyn->bandsToZero; return; } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index ff5d9d0b03ca6ebb138448f78b1e5583979bd7d8..1717aa9a5bbb18990b90584f06727eed060b5021 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -2068,13 +2068,13 @@ typedef struct Decoder_State BPF_DEC_HANDLE hBPF; /* Bass post-filter handle */ HANDLE_CLDFB_FILTER_BANK cldfbAna; /* main analysis filter bank handle */ - HANDLE_CLDFB_FILTER_BANK cldfbAna_fx; /* main analysis filter bank handle */ + //HANDLE_CLDFB_FILTER_BANK cldfbAna_fx; /* main analysis filter bank handle */ HANDLE_CLDFB_FILTER_BANK cldfbBPF; /* BPF analysis filter bank handle */ - HANDLE_CLDFB_FILTER_BANK cldfbBPF_fx; /* BPF analysis filter bank handle */ + //HANDLE_CLDFB_FILTER_BANK cldfbBPF_fx; /* BPF analysis filter bank handle */ HANDLE_CLDFB_FILTER_BANK cldfbSyn; /* main synthesis filter bank handle */ - HANDLE_CLDFB_FILTER_BANK cldfbSyn_fx; /* main synthesis filter bank handle */ + //HANDLE_CLDFB_FILTER_BANK cldfbSyn_fx; /* main synthesis filter bank handle */ HANDLE_CLDFB_FILTER_BANK cldfbSynHB; /* high band synthesis filter bank needed in SBA2Stereo DTX handling */ diff --git a/lib_dec/updt_dec_fx.c b/lib_dec/updt_dec_fx.c index 9b0e16de07127fc0036d9eea809475106d414763..2bee4fa0a5efae25e7c295e2859cd152f6ee270a 100644 --- a/lib_dec/updt_dec_fx.c +++ b/lib_dec/updt_dec_fx.c @@ -306,7 +306,7 @@ void updt_IO_switch_dec_fx( move16(); if (EQ_16(st_fx->last_flag_filter_NB, 1)) { - st_fx->cldfbSyn_fx->bandsToZero = 0; + st_fx->cldfbSyn->bandsToZero = 0; } st_fx->last_active_bandsToZero_bwdec = 0; st_fx->perc_bwddec = 0; diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 0ac0e60cf6a8052aa8a1411b045d9b01f3856a42..f6b0cbc53225cc53772559dfcb310a27b3db4ca3 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -239,11 +239,8 @@ ivas_error ivas_limiter_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) ); } hLimiter->sampling_rate = sampling_rate; - hLimiter->gain = 1.f; hLimiter->gain_fx = ONE_IN_Q30; - hLimiter->release_heuristic = 0.f; hLimiter->release_heuristic_fx = 0; - hLimiter->attack_constant = powf( 0.01f, 1.0f / ( IVAS_LIMITER_ATTACK_SECONDS * sampling_rate ) ); SWITCH( sampling_rate ) { case 48000: @@ -258,8 +255,8 @@ ivas_error ivas_limiter_open( case 8000: attack_cnst_fx = ATTACK_CNST_8k; BREAK; - - + default: + assert(0); } hLimiter->attack_constant_fx = attack_cnst_fx; @@ -267,7 +264,6 @@ ivas_error ivas_limiter_open( for ( i = 0; i < max_num_channels; ++i ) { - hLimiter->channel_ptrs[i] = NULL; hLimiter->channel_ptrs_fx[i] = NULL; } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 44c58a9e8c9f13b42e9e60221cddef5787f62706..dbca8eaf72eaef34653476668ab4f87fb49daabf 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -40,12 +40,13 @@ #include "ivas_rom_com.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" #include "ivas_rom_com_fx.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) +#define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) ) +#define fixed_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) #endif /*---------------------------------------------------------------------* @@ -54,14 +55,23 @@ static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); +#ifdef IVAS_FLOAT_FIXED +static void TDREND_Clear_Update_flags_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ +); +#endif // IVAS_FLOAT_FIXED + + static void angles_to_vec( const float radius, const float azimuth, const float elevation, float *vec ); +#ifdef IVAS_FLOAT_FIXED static void angles_to_vec_fx( const Word16 radius, /* i : radius */ const Word32 azimuth, /* i : Azimuth angle */ const Word32 elevation, /* i : Elevation angle */ - Word16 *vec /* o : Pos/Dir vector */ + Word32 *vec /* o : Pos/Dir vector */ ); +#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open_unwrap() @@ -87,8 +97,8 @@ ivas_error ivas_td_binaural_open_unwrap_fx( TDREND_PosType_t PosType; Word16 nS; const Word32 *ls_azimuth_fx, *ls_elevation_fx; - Word16 Pos_fx[3]; - Word16 Dir_fx[3]; + Word32 Pos_fx[3]; // Q25 + Word32 Dir_fx[3]; // Q30 TDREND_DirAtten_t *DirAtten_p; Word16 nchan_rend; ivas_error error; @@ -188,14 +198,14 @@ ivas_error ivas_td_binaural_open_unwrap_fx( FOR( nS = 0; nS < nchan_rend; nS++ ) { /* Set source positions according to loudspeaker layout */ - angles_to_vec_fx( 32767, ls_azimuth_fx[nS], ls_elevation_fx[nS], Pos_fx ); + angles_to_vec_fx( ONE_IN_Q9, ls_azimuth_fx[nS], ls_elevation_fx[nS], Pos_fx ); - Dir_fx[0] = 32767; - move16(); + Dir_fx[0] = ONE_IN_Q30; + move32(); Dir_fx[1] = 0; - move16(); + move32(); Dir_fx[2] = 0; - move16(); + move32(); /* Source directivity info */ DirAtten_p->ConeInnerAngle_fx = 23040; move16(); @@ -209,7 +219,7 @@ ivas_error ivas_td_binaural_open_unwrap_fx( { return error; } - IF( ( error = TDREND_MIX_SRC_SetDir_fx( pBinRendTd, nS, Dir_fx ) ) != IVAS_ERR_OK ) + IF( ( error = TDREND_MIX_SRC_SetDir_fx( pBinRendTd, nS, Dir_fx, Q30 ) ) != IVAS_ERR_OK ) { return error; } @@ -590,7 +600,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( for ( j = 0; j < ( ( subframe_idx + 1 ) * hReverb->full_block_size ); j++ ) { - pcm_in_fx[i][j] = (Word32) float_to_fix( output[i][j], exp ); + pcm_in_fx[i][j] = (Word32) float_to_fixed( output[i][j], exp ); } } for ( i = 0; i < BINAURAL_CHANNELS; i++ ) @@ -602,7 +612,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - pcm_out_fx[i][j] = (Word32) float_to_fix( p_reverb_signal[i][j], ( exp ) ); + pcm_out_fx[i][j] = (Word32) float_to_fixed( p_reverb_signal[i][j], ( exp ) ); } } if ( ( error = ivas_reverb_process_fx( hReverb, transport_config, 0, pcm_in_fx, pcm_out_fx, subframe_idx) ) != IVAS_ERR_OK ) @@ -620,7 +630,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( for ( j = 0; j < ( hReverb->full_block_size ); j++ ) { - p_reverb_signal[i][subframe_idx * hReverb->full_block_size + j] = fix_to_float( pcm_out_fx[i][subframe_idx * hReverb->full_block_size + j], (exp - 2) ); + p_reverb_signal[i][subframe_idx * hReverb->full_block_size + j] = fixed_to_float( pcm_out_fx[i][subframe_idx * hReverb->full_block_size + j], (exp - 2) ); } } #endif @@ -729,12 +739,137 @@ ivas_error TDREND_GetMix( } +#ifdef IVAS_FLOAT_FIXED +void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ + TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i : Spatial aspects of source */ + float *hrf_left_prev_flt, /* o : Left filter */ + float *hrf_right_prev_flt, /* o : Right filter */ + float *hrf_left_delta_flt, /* o : Left filter interpolation delta */ + float *hrf_right_delta_flt, /* o : Right filter interpolation delta */ + Word32 *hrf_left_prev, /* o : Left filter */ + Word32 *hrf_right_prev, /* o : Right filter */ + Word32 *hrf_left_delta, /* o : Left filter interpolation delta */ + Word32 *hrf_right_delta, /* o : Right filter interpolation delta */ + Word16 *intp_count, /* o : Interpolation count */ + Word16 *filterlength, /* o : Length of filters */ + Word16 *itd, /* o : ITD value */ + float *Gain_flt, /* o : Gain value */ + Word16 *Gain, /* o : Gain value */ + TDREND_SRC_t *Src_p, /* i/o: Source pointer */ + const Word16 subframe_update_flag); +ivas_error TDREND_GetMix_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + float *output_flt[], /* i/o: ISM object synth / rendered output in 0,1 */ + const Word16 subframe_length, /* i/o: subframe length */ + const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */ + const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ +) +{ + int16_t i; + TDREND_SRC_t *Src_p; + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + TDREND_SRC_REND_t *SrcRend_p; + ivas_error error; + float output_buf_flt[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ + float hrf_left_delta_flt[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float hrf_right_delta_flt[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word32 output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ + Word16 hrf_left_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word16 hrf_right_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word16 intp_count; + Word16 subframe_update_flag; + + subframe_update_flag = (Word16)EQ_16( subframe_idx, ism_md_subframe_update ); + + error = IVAS_ERR_OK; + + /* Clear the output buffer to accumulate rendered sources */ + set_f( output_buf_flt[0], 0.0f, subframe_length ); + set_f( output_buf_flt[1], 0.0f, subframe_length ); + set32_fx( output_buf[0], 0, subframe_length ); + set32_fx( output_buf[1], 0, subframe_length ); + + /* Clear interpolation buffers and counter */ + set_f( hrf_left_delta_flt, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set_f( hrf_right_delta_flt, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set16_fx( hrf_left_delta, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set16_fx( hrf_right_delta, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + intp_count = 0; + move16(); + + /* Create the mix */ + /* Loop through the source list and render each source */ + FOR( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) + { + Src_p = hBinRendererTd->Sources[i]; + SrcSpatial_p = Src_p->SrcSpatial_p; + SrcRend_p = Src_p->SrcRend_p; + + /* Update rendering params if needed */ + test(); test(); + IF ( ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) && ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) ) + { +#if 0 + TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hrf_left_prev, + Src_p->hrf_right_prev, hrf_left_delta_flt, hrf_right_delta_flt, &intp_count, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain, Src_p, subframe_update_flag ); +#else + TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( hBinRendererTd, SrcRend_p, SrcSpatial_p, + Src_p->hrf_left_prev, Src_p->hrf_right_prev, hrf_left_delta_flt, hrf_right_delta_flt, + Src_p->hrf_left_prev_fx, Src_p->hrf_right_prev_fx, hrf_left_delta, hrf_right_delta, + &intp_count, &Src_p->filterlength, &Src_p->itd, + &Src_p->Gain, + &Src_p->Gain_fx, + Src_p, subframe_update_flag ); +#endif + } + + /* Render source if needed */ + if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) + { + error = TDREND_REND_RenderSourceHRFilt( Src_p, hrf_left_delta_flt, hrf_right_delta_flt, intp_count, output_buf_flt, subframe_length ); + } + } + + /* Populate output variable */ + mvr2r( output_buf_flt[0], output_flt[0] + subframe_idx * subframe_length, subframe_length ); /* Left */ + mvr2r( output_buf_flt[1], output_flt[1] + subframe_idx * subframe_length, subframe_length ); /* Right */ + + /* Clear the PoseUpdated and Source position update flags */ + TDREND_Clear_Update_flags( hBinRendererTd ); + + return error; +} +#endif + + + /*---------------------------------------------------------------------* * TDREND_Clear_Update_flags() * * Initializes the audio mixer module *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void TDREND_Clear_Update_flags_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ +) +{ + Word16 i; + + hBinRendererTd->Listener_p->PoseUpdated = FALSE;move16(); + + for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) + { + hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE;move16(); + } + + return; +} + +#endif + static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ) @@ -752,6 +887,79 @@ static void TDREND_Clear_Update_flags( } +/*---------------------------------------------------------------------* + * TDREND_Update_object_positions_fx() + * + * Update object position(s) + *---------------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_Update_object_positions_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ + const Word16 num_src, /* i : number of sources to render */ + const IVAS_FORMAT in_format, /* i : Format of input sources */ + const ISM_METADATA_HANDLE *hIsmMetaData /* i : Input metadata for ISM objects */ +) +{ + TDREND_DirAtten_t *DirAtten_p; + Word16 nS; + Word32 Pos_fx[3]; // Q25 + Word32 Dir_fx[3]; // Q30 + ivas_error error; + + DirAtten_p = hBinRendererTd->DirAtten_p; + + /* For each source, write the frame data to the source object*/ + FOR( nS = 0; nS < num_src; nS++ ) + { + test(); test(); + IF( in_format == ISM_FORMAT || in_format == MASA_ISM_FORMAT || in_format == SBA_ISM_FORMAT ) + { + /* Update the source positions */ + /* Source position and direction */ + angles_to_vec_fx( hIsmMetaData[nS]->radius_fx /*Q9*/, hIsmMetaData[nS]->azimuth_fx, hIsmMetaData[nS]->elevation_fx, Pos_fx ); + angles_to_vec_fx( ONE_IN_Q14, hIsmMetaData[nS]->yaw_fx, hIsmMetaData[nS]->pitch_fx, Dir_fx ); + + IF ( ( error = TDREND_MIX_SRC_SetPos_fx( hBinRendererTd, nS, Pos_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF ( ( error = TDREND_MIX_SRC_SetDirAtten_fx( hBinRendererTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) + { + return error; + } + + IF( hIsmMetaData[nS]->non_diegetic_flag ) + { + Word16 tmp, tmp_e; + Pos_fx[0] = 0; + tmp = BASOP_Util_Divide3232_Scale(hIsmMetaData[nS]->azimuth_fx, 377487360 /* 90.f in Q22 */, &tmp_e); + Pos_fx[1] = shr(tmp, sub(6, tmp_e)); // Q25 + Pos_fx[2] = 0; + + IF( ( error = TDREND_MIX_SRC_SetPos_fx( hBinRendererTd, nS, Pos_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + hBinRendererTd->Sources[nS]->SrcSpatial_p->PosType = TDREND_POSTYPE_NON_DIEGETIC; + } + ELSE + { + hBinRendererTd->Sources[nS]->SrcSpatial_p->PosType = TDREND_POSTYPE_ABSOLUTE; + } + + IF ( ( error = TDREND_MIX_SRC_SetDir_fx( hBinRendererTd, nS, Dir_fx, Q30 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} +#endif + /*---------------------------------------------------------------------* * TDREND_Update_object_positions() * @@ -889,6 +1097,93 @@ ivas_error TDREND_Update_listener_orientation( return error; } +#ifdef IVAS_FLOAT_FIXED +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 */ +) +{ + Word32 FrontVec_fx[3]; + Word32 UpVec_fx[3]; + Word32 Rmat_fx[3][3]; + Word16 orient_q, headPosition_q; + Word32 Pos_p_fx[3]; + ivas_error error; + + IF ( headRotEnabled ) + { + Word16 Rmat_q; + + assert(headPosition_fx->w_qfact == headPosition_fx->x_qfact + && headPosition_fx->x_qfact == headPosition_fx->y_qfact + && headPosition_fx->y_qfact == headPosition_fx->z_qfact); + headPosition_q = headPosition_fx->w_qfact; // Assuming Q is same for w, x, y and z + move16(); + + /* Obtain head rotation matrix */ + QuatToRotMat_fx( *headPosition_fx, Rmat_fx ); // Rmat_fx Q: 2*Qx-32 + Rmat_q = 2 * headPosition_q - 32; + + /* Apply rotation matrix to looking vector [1;0;0] */ + FrontVec_fx[0] = Rmat_fx[0][0]; + FrontVec_fx[1] = Rmat_fx[0][1]; + FrontVec_fx[2] = Rmat_fx[0][2]; + + /* Apply rotation matrix to up vector [0;0;1] */ + UpVec_fx[0] = Rmat_fx[2][0]; + UpVec_fx[1] = Rmat_fx[2][1]; + UpVec_fx[2] = Rmat_fx[2][2]; + + orient_q = Rmat_q; + + IF ( Pos_fx != NULL ) + { + // Assuming Q is same for x, y and z + assert((*Pos_fx).x_qfact == (*Pos_fx).y_qfact && (*Pos_fx).y_qfact == (*Pos_fx).z_qfact ); + assert((*Pos_fx).x_qfact == hBinRendererTd->Listener_p->Pos_q ); + + /* Input position */ + Pos_p_fx[0] = ( *Pos_fx ).x_fx; + Pos_p_fx[1] = ( *Pos_fx ).y_fx; + Pos_p_fx[2] = ( *Pos_fx ).z_fx; + } + ELSE + { + /* Listener at the origin */ + Pos_p_fx[0] = 0; + Pos_p_fx[1] = 0; + Pos_p_fx[2] = 0; + } + } + ELSE + { + /* Oriented with looking vector along the x axis */ + FrontVec_fx[0] = ONE_IN_Q30; + FrontVec_fx[1] = 0; + FrontVec_fx[2] = 0; + /* Oriented with up vector along the z axis */ + UpVec_fx[0] = 0; + UpVec_fx[1] = 0; + UpVec_fx[2] = ONE_IN_Q30; + + orient_q = Q30; + + /* Listener at the origin */ + Pos_p_fx[0] = 0; + Pos_p_fx[1] = 0; + Pos_p_fx[2] = 0; + } + + /* Set the listener position and orientation:*/ + TDREND_MIX_LIST_SetPos_fx( hBinRendererTd, Pos_p_fx ); + error = TDREND_MIX_LIST_SetOrient_fx( hBinRendererTd, FrontVec_fx, UpVec_fx, orient_q ); + + return error; +} +#endif + /*---------------------------------------------------------------------* * ivas_td_binaural_open_ext() @@ -1143,18 +1438,18 @@ ivas_error ivas_td_binaural_renderer_ext( *---------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED static void angles_to_vec_fx( - const Word16 radius, /* i : radius */ - const Word32 azimuth, /* i : Azimuth angle */ - const Word32 elevation, /* i : Elevation angle */ - Word16 *vec /* o : Pos/Dir vector */ + const Word16 radius, /* i : radius Qx */ + const Word32 azimuth, /* i : Azimuth angle Q22 */ + const Word32 elevation, /* i : Elevation angle Q22 */ + Word32 *vec /* o : Pos/Dir vector Qx+16 */ ) { Word16 elevation_fx, azimuth_fx; elevation_fx =(Word16)L_shr( Mult_32_16( elevation, 91 ), 7 ); azimuth_fx = (Word16)L_shr( Mult_32_16( azimuth, 91 ), 7 ); - vec[0] = mult( radius, mult( getCosWord16R2( elevation_fx ), getCosWord16R2( azimuth_fx ) ) ); - vec[1] = mult( radius, mult( getCosWord16R2( elevation_fx ), getSineWord16R2( azimuth_fx ) ) ); - vec[2] = mult( radius, getSineWord16R2( elevation_fx ) ); + vec[0] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getCosWord16R2( azimuth_fx ) ) ); + vec[1] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getSineWord16R2( azimuth_fx ) ) ); + vec[2] = L_mult( radius, getSineWord16R2( elevation_fx ) ); return; } #endif // IVAS_FLOAT_FIXED diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 4182c77a7493dc307dc63adf5e2c94dca9023ea4..bf564630090d291fc2555bad2192d35ab79faf18 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -52,6 +52,20 @@ static void GenerateFilter( const float elev, float azim, ModelParams_t *model, static void GenerateITD( const float elev, float azim, ModelParamsITD_t *model, ModelEval_t *modelEval ); static void SkipSmallest_ValueIndex( int16_t *use_inds, const ValueIndex_t *VI, const int16_t N, const int16_t n_smallest ); +#ifdef IVAS_FLOAT_FIXED +static void getStandardBSplineSampVec_fx( + Word32 *BfVec, /* i/o: values for non-zero basis functions */ + Word16 *NzIdx, /* i/o: indices of non-zero basis functions */ + Word16 *num_idx, /* i/o: number of non-zero indices */ + const Word16 NumBFs, /* i : the number of basis functions = third index of Bf */ + const Word32 t, /* i : estimation point */ + const Word32 *KSeq, /* i : knot sequence including multiplicities */ + const Word16 SegSamples, /* i : samples per segment */ + const Word16 *BsLen, /* i : lengths of basis shapes */ + const Word16 *BsStart, /* i : start of basis shapes */ + const Word32 *BsShape /* i : basis shapes */ +); +#endif /*-------------------------------------------------------------------* * TDREND_REND_RenderSourceHRFilt() @@ -417,6 +431,85 @@ static void getPeriodicBSplineSampVec( * Obtain a sampled B Spline basis vector. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void getStandardBSplineSampVec_fx( + Word32 *BfVec, /* i/o: values for non-zero basis functions */ + Word16 *NzIdx, /* i/o: indices of non-zero basis functions */ + Word16 *num_idx, /* i/o: number of non-zero indices */ + const Word16 NumBFs, /* i : the number of basis functions = third index of Bf */ + const Word32 t, /* i : estimation point */ + const Word32 *KSeq, /* i : knot sequence including multiplicities */ + const Word16 SegSamples, /* i : samples per segment */ + const Word16 *BsLen, /* i : lengths of basis shapes */ + const Word16 *BsStart, /* i : start of basis shapes */ + const Word32 *BsShape /* i : basis shapes */ +) +{ + + int16_t i, nI; + //float knot_interval; + Word16 knot_interval; + Word16 d0, d, shape_idx, start_idx; + Word16 tmp_1, tmp_2, tmp_e; + Word32 tmp_32; + + tmp_1 = i_mult((NumBFs - 3), SegSamples); + + tmp_2 = BASOP_Util_Divide3232_Scale(t - KSeq[0], KSeq[NumBFs - 3] - KSeq[0], &tmp_e); // Q15 - tmp_e + + tmp_1 = shl(tmp_1, tmp_e); // Q0 + tmp_e + + d0 = mult_r(tmp_1, tmp_2); // Q0 + + //knot_interval = (KSeq[NumBFs - 3] - KSeq[0]) / (NumBFs - 3); /* assuming triple knot at the first knot */ + /* index of closest sample point */ + //d0 = (int16_t)round_f((t - KSeq[0]) / (knot_interval / SegSamples)); + /* find segment */ + //nI = d0 / SegSamples; + tmp_1 = BASOP_Util_Divide3232_Scale(d0, SegSamples, &tmp_e); + nI = shr(tmp_1, 15 - tmp_e); + + *num_idx = HRTF_MODEL_BSPLINE_NUM_COEFFS; + + if (d0 % SegSamples == 0) + { + (*num_idx)--; /* on the knot points, the last basis function is zero */ + } + + + FOR (i = 0; i < *num_idx; i++) + { + + //start_idx = max(0, i + nI - 3); + start_idx = s_max(0, add(i, sub(nI, 3))); + //shape_idx = min(i + nI, min(3, NumBFs - 1 - (i + nI))); + shape_idx = s_min(add(i, nI), s_min(3, sub(sub(NumBFs, 1), add(i, nI)))); + //d = d0 - start_idx * SegSamples; + d = sub(d0, i_mult(start_idx, SegSamples)); + + //if (i + nI > NumBFs - 4) /* reverse full shape */ + if (add(i, nI) > sub(NumBFs, 4)) /* reverse full shape */ + { + //d = BsLen[shape_idx] - 1 - d; + d = sub(sub(BsLen[shape_idx], 1), d); + } + //else if (d > BsLen[shape_idx] - 1) /* reverse half shape */ + else if (d > sub(BsLen[shape_idx], 1)) /* reverse half shape */ + { + //d = 2 * (BsLen[shape_idx] - 1) - d; + d = sub(shl(sub(BsLen[shape_idx], 1),1), d); + } + //BfVec[i] = BsShape[BsStart[shape_idx] + (int16_t)abs(d)]; /*TT, verify if abs is needed */ + BfVec[i] = BsShape[BsStart[shape_idx] + (int16_t)abs(d)]; /*TT, verify if abs is needed */ + //NzIdx[i] = nI + i; + NzIdx[i] = add(nI, i); + } + + return; +} +#endif + + static void getStandardBSplineSampVec( float *BfVec, /* i/o: values for non-zero basis functions */ int16_t *NzIdx, /* i/o: indices of non-zero basis functions */ diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 77a13ea7ef01aeb4f44a7c3efdb46bbcbcdd4f17..9830e57593a12f707c9d888ed535385c3ba2ed45 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -67,6 +67,30 @@ static ivas_error DefaultBSplineModel_fx( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, * Sets the listener's position in the specified mixer unit. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void TDREND_MIX_LIST_SetPos_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word32 *Pos_p /* i : Listener's position */ +) +{ + TDREND_MIX_Listener_t *Listener_p; + + Listener_p = hBinRendererTd->Listener_p; + + IF( NE_32( Pos_p[0], Listener_p->Pos_fx[0] ) || NE_32( Pos_p[1], Listener_p->Pos_fx[1] ) || NE_32( Pos_p[2], Listener_p->Pos_fx[2] ) ) + { + /* Set position */ + Copy32( Pos_p, Listener_p->Pos_fx, 3 ); + + /* Set pose update flag */ + Listener_p->PoseUpdated = TRUE; + move16(); + } + + return; +} +#endif + void TDREND_MIX_LIST_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *Pos_p /* i : Listener's position */ @@ -123,6 +147,39 @@ ivas_error TDREND_MIX_LIST_SetOrient( } +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_LIST_SetOrient_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word32 *FrontVec_p_fx, /* i : Listener's orientation front vector */ + const Word32 *UpVec_p_fx, /* i : Listener's orientation up vector */ + const Word16 orient_q /* i : Listener's orientation q-factor */ +) +{ + + TDREND_MIX_Listener_t *List_p; + /* Value verification */ + test(); test(); + IF( ( FrontVec_p_fx[0] == 0 ) && ( FrontVec_p_fx[1] == 0 ) && ( FrontVec_p_fx[2] == 0 ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero front vector. Command is ignored!\n" ) ); + } + + IF( ( UpVec_p_fx[0] == 0 ) && ( UpVec_p_fx[1] == 0 ) && ( UpVec_p_fx[2] == 0 ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero up vector. Command is ignored!\n" ) ); + } + + /* Get listener */ + List_p = hBinRendererTd->Listener_p; + + /* Evaluate the normalized orientation vectors and set pose update flag */ + List_p->PoseUpdated = TDREND_SPATIAL_EvalOrthonormOrient_fx( List_p->Front_fx, List_p->Up_fx, List_p->Right_fx, FrontVec_p_fx, UpVec_p_fx, orient_q ); + + return IVAS_ERR_OK; +} +#endif + + /*-------------------------------------------------------------------* * TDREND_MIX_Dealloc() * @@ -292,9 +349,9 @@ ivas_error TDREND_MIX_Init_fx( /* Init virtual and rendering listeners for spatial mixers */ TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Pos_fx, 0, 0, 0 ); TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Vel_fx, 0, 0, 0 ); - TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Front_fx, 0, 0, -32767 );/*Q15*/ - TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Up_fx, 0, 32767, 0 );/*Q15*/ - TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Right_fx, 32767, 0, 0 );/*Q15*/ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Front_fx, 0, 0, -ONE_IN_Q31 );/*Q31*/ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Up_fx, 0, ONE_IN_Q31, 0 );/*Q31*/ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Right_fx, ONE_IN_Q31, 0, 0 );/*Q31*/ /* Init HR filter set */ IF ( *hHrtfTD == NULL ) { diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 9c9c3d1a82f02903c71117c387edb088a250ac46..73ca8fc1cea0ba3c326162e74f9d4ebfacde21cc 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -37,6 +37,7 @@ #include "ivas_prot_rend.h" #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED +#include "ivas_prot_fx.h" #include "prot_fx2.h" #endif // IVAS_FLOAT_FIXED @@ -73,22 +74,22 @@ static void TDREND_SRC_REND_Init_fx( TDREND_SRC_REND_t *SrcRend_p ); ivas_error TDREND_MIX_SRC_SetPos_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ - const Word16 *Vec_p /* i : Position vector */ + const Word32 *Vec_p /* i : Position vector */ ) { TDREND_SRC_SPATIAL_t *SrcSpatial_p; - IF ( GT_16(SrcInd , hBinRendererTd->MaxSrcInd) ) + IF(GT_16(SrcInd, hBinRendererTd->MaxSrcInd)) { - return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) ); + return (IVAS_ERROR(IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n")); } ELSE { SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; - IF ( NE_16(SrcSpatial_p->Pos_p_fx[0] , Vec_p[0]) || NE_16(SrcSpatial_p->Pos_p_fx[1] , Vec_p[1]) || NE_16(SrcSpatial_p->Pos_p_fx[2] , Vec_p[2]) ) + IF(NE_32(SrcSpatial_p->Pos_p_fx[0] , Vec_p[0]) || NE_32(SrcSpatial_p->Pos_p_fx[1] , Vec_p[1]) || NE_32(SrcSpatial_p->Pos_p_fx[2] , Vec_p[2])) { - Copy( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); + Copy32(Vec_p, SrcSpatial_p->Pos_p_fx, 3); SrcSpatial_p->Updated = TRUE; move16(); } @@ -131,14 +132,15 @@ ivas_error TDREND_MIX_SRC_SetPos( --------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetDir_fx( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const Word16 SrcInd, /* i : Source index */ - const Word16 *Vec_p /* i : Direction vector */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word32 *Vec_p, /* i : Direction vector */ + const Word16 Vec_p_q /* i : Direction vector q */ ) { TDREND_SRC_SPATIAL_t *SrcSpatial_p; /* Value verification */ - IF ( EQ_16( Vec_p[0] , 0 ) && EQ_16( Vec_p[1] , 0 ) && EQ_16( Vec_p[2] , 0 ) ) + IF ( EQ_32( Vec_p[0] , 0 ) && EQ_32( Vec_p[1] , 0 ) && EQ_32( Vec_p[2] , 0 ) ) { return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Zero direction vector. Command is ignored!\n" ) ); } @@ -149,7 +151,7 @@ ivas_error TDREND_MIX_SRC_SetDir_fx( ELSE { SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; - TDREND_SPATIAL_VecNormalize_fx( Vec_p, SrcSpatial_p->Front_p_fx ); + TDREND_SPATIAL_VecNormalize_fx( Vec_p, Vec_p_q, SrcSpatial_p->Front_p_fx ); SrcSpatial_p->Updated = TRUE; move16(); } @@ -501,6 +503,165 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( return; } +#ifdef IVAS_FLOAT_FIXED +void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ + TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i : Spatial aspects of source */ + float *hrf_left_prev_flt, /* o : Left filter */ + float *hrf_right_prev_flt, /* o : Right filter */ + float *hrf_left_delta_flt, /* o : Left filter interpolation delta */ + float *hrf_right_delta_flt, /* o : Right filter interpolation delta */ + Word32 *hrf_left_prev, /* o : Left filter */ + Word32 *hrf_right_prev, /* o : Right filter */ + Word32 *hrf_left_delta, /* o : Left filter interpolation delta */ + Word32 *hrf_right_delta, /* o : Right filter interpolation delta */ + Word16 *intp_count, /* o : Interpolation count */ + Word16 *filterlength, /* o : Length of filters */ + Word16 *itd, /* o : ITD value */ + float *Gain_flt, /* o : Gain value */ + Word16 *Gain, /* o : Gain value */ + TDREND_SRC_t *Src_p, /* i/o: Source pointer */ + const Word16 subframe_update_flag ) +{ + TDREND_MIX_Listener_t *Listener_p; + TDREND_HRFILT_FiltSet_t *HrFiltSet_p; + float ListRelPos_flt[3], ListRelDist_flt; + float ListRelPosAbs_flt[3]; /* Relative position, ignoring orientation of listener */ + float Azim_flt, Elev_flt; + float hrf_left_flt[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float hrf_right_flt[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + float azim_delta_flt; + float elev_delta_flt; + Word32 ListRelPos[3]; + Word32 ListRelDist; + Word32 ListRelPosAbs[3]; /* Relative position, ignoring orientation of listener */ + Word32 Azim, Elev; + Word32 hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word32 hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word32 azim_delta; + Word32 elev_delta; + Word16 tmp_e1, tmp_e2; + + /* Evaluate the HR filters from the source and listener positions and orientations */ + Listener_p = hBinRendererTd->Listener_p; + HrFiltSet_p = hBinRendererTd->HrFiltSet_p; + + *filterlength = s_min( HrFiltSet_p->FiltLength, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + + if ( SrcSpatial_p->PosType == TDREND_POSTYPE_ABSOLUTE ) + { + /* Absolute position */ + // Float to fixed + for (int i = 0; i < 3; i++) + { + SrcSpatial_p->Pos_p_fx[i] = float_to_fix(SrcSpatial_p->Pos_p[i], Q25); + } + TDREND_SPATIAL_VecMapToNewCoordSystem_fx( SrcSpatial_p->Pos_p_fx, Listener_p->Pos_fx, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs ); + tmp_e1 = 62 - Q25 - Q30; // output q of above function is Q25 + Q30 - 31. so exp will be 62 - Q25 - Q30. + ListRelDist = TDREND_SPATIAL_VecNorm_fx( ListRelPos, tmp_e1, &tmp_e2 ); + + // Fixed to float + for (int i = 0; i < 3; i++) + { + ListRelPosAbs_flt[i] = fix_to_float(ListRelPosAbs[i], Q25 ); + ListRelPos_flt[i] = fix_to_float(ListRelPos[i], tmp_e1 ); + } + ListRelDist_flt = me2f(ListRelDist, tmp_e2); + //////////////// + + /* 2. Evaluate the Elevation and Azimuth angles */ + IF( ( ListRelPos[0] == 0 ) && ( ListRelPos[1] == 0 ) && ( ListRelPos[2] == 0 ) ) + { + Elev_flt = 0.0; + Azim_flt = 0.0; + + Elev = 0; + Azim = 0; + } + ELSE + { + Elev_flt = _180_OVER_PI * atan2f( ListRelPos_flt[2], sqrtf( ListRelPos_flt[0] * ListRelPos_flt[0] + ListRelPos_flt[1] * ListRelPos_flt[1] ) ); + /* Basis set is [front, right, up], which is a left-handed coordinate system. Minus sign here is to change to a positive-left system for azimuth */ + Azim_flt = -1.0f * _180_OVER_PI * (float) atan2f( ListRelPos_flt[1], ListRelPos_flt[0] ); + + Elev = float_to_fix(Elev_flt, Q22); + Azim = float_to_fix(Azim_flt, Q22); + } + + GetFilterFromAngle( HrFiltSet_p, Elev_flt, Azim_flt, *filterlength, hrf_left_flt, hrf_right_flt, itd ); + + /* 6. Evaluate the directional and distance gains */ + /* Directional gain */ + *SrcRend_p->DirGain_p = 1.0f; + if ( SrcSpatial_p->DirAttenEnabled ) + { + *SrcRend_p->DirGain_p = TDREND_SRC_SPATIAL_GetDirGain( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p, ListRelPosAbs_flt ); + } + + /* Distance gain */ + *SrcRend_p->DistGain_p = 1.0f; + if ( hBinRendererTd->UseCommonDistAttenModel ) + { + if ( hBinRendererTd->DistAttenEnabled ) + { + SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel; + *SrcRend_p->DistGain_p = TDREND_SRC_SPATIAL_GetDistGain( &SrcSpatial_p->DistAtten, ListRelDist_flt ); + } + } + else + { + if ( SrcSpatial_p->DistAttenEnabled ) + { + *SrcRend_p->DistGain_p = TDREND_SRC_SPATIAL_GetDistGain( &SrcSpatial_p->DistAtten, ListRelDist_flt ); + } + } + + /* Update total gains */ + *Gain_flt = ( *SrcRend_p->SrcGain_p ) * ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ) * hBinRendererTd->Gain; + + /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP */ + elev_delta_flt = Elev_flt - Src_p->elev_prev; + azim_delta_flt = Azim_flt - Src_p->azim_prev; + Src_p->elev_prev = Elev_flt; + Src_p->azim_prev = Azim_flt; + + azim_delta_flt = ( azim_delta_flt > 180.0f ) ? ( azim_delta_flt - 360 ) : ( ( azim_delta_flt < -180.0f ) ? ( azim_delta_flt + 360 ) : ( azim_delta_flt ) ); /* map to -180:180 range */ + *intp_count = min( MAX_INTERPOLATION_STEPS, max( (int16_t) ( fabsf( azim_delta_flt ) * MAX_ANGULAR_STEP_INV ), (int16_t) ( fabsf( elev_delta_flt ) * MAX_ANGULAR_STEP_INV ) ) ); + } + else /* TDREND_POSTYPE_NON_DIEGETIC */ + { + *itd = 0; + *Gain_flt = 1.0f; + set_f( hrf_left_flt, 0.0f, *filterlength ); + set_f( hrf_right_flt, 0.0f, *filterlength ); + hrf_left_flt[0] = ( SrcSpatial_p->Pos_p[1] + 1.f ) * 0.5f; + hrf_right_flt[0] = 1.f - hrf_left_flt[0]; + *intp_count = MAX_INTERPOLATION_STEPS; + Src_p->elev_prev = 0; + Src_p->azim_prev = 360.0f; /* Dummy angle -- sets max interpolation if switching to TDREND_POSTYPE_ABSOLUTE */ + } + + if ( ( *intp_count > 0 ) && subframe_update_flag ) + { + /* Set deltas for interpolation */ + v_sub( hrf_left_flt, hrf_left_prev_flt, hrf_left_delta_flt, *filterlength ); + v_multc( hrf_left_delta_flt, 1.0f / *intp_count, hrf_left_delta_flt, *filterlength ); + v_sub( hrf_right_flt, hrf_right_prev_flt, hrf_right_delta_flt, *filterlength ); + v_multc( hrf_right_delta_flt, 1.0f / *intp_count, hrf_right_delta_flt, *filterlength ); + } + else + { + /* No interpolation, just set the new filters and reset deltas */ + mvr2r( hrf_left_flt, hrf_left_prev_flt, *filterlength ); + mvr2r( hrf_right_flt, hrf_right_prev_flt, *filterlength ); + set_f( hrf_left_delta_flt, 0.0f, *filterlength ); + set_f( hrf_right_delta_flt, 0.0f, *filterlength ); + } + + return; +} +#endif /*-------------------------------------------------------------------* * TDREND_SRC_SPATIAL_Alloc() @@ -588,10 +749,10 @@ static void TDREND_SRC_SPATIAL_Init_fx( FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) { /* Source position */ - TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Pos_p_fx + nC * 3, 0, 0, 0 );/*Assuming Q15*/ + TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Pos_p_fx + nC * 3, 0, 0, 0 );/*Assuming Q31*/ /* Source direction */ - TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, 32767);/*Assuming Q15*/ + TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, ONE_IN_Q30);/*Assuming Q30*/ } @@ -909,23 +1070,23 @@ void TDREND_SRC_Init_fx( move16(); Src_p->filterlength = 1; /* Init to unit impulse of length 1 */ move16(); - set16_fx( Src_p->mem_itd_fx, 0, ITD_MEM_LEN ); - set16_fx( Src_p->mem_hrf_left_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); - set16_fx( Src_p->mem_hrf_right_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); - - set16_fx( Src_p->hrf_left_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); - set16_fx( Src_p->hrf_right_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); - Src_p->hrf_left_prev_fx[0] = 32767; - move16(); - Src_p->hrf_right_prev_fx[0] = 32767; - move16(); + set32_fx( Src_p->mem_itd_fx, 0, ITD_MEM_LEN ); + set32_fx( Src_p->mem_hrf_left_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set32_fx( Src_p->mem_hrf_right_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + + set32_fx( Src_p->hrf_left_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set32_fx( Src_p->hrf_right_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + Src_p->hrf_left_prev_fx[0] = ONE_IN_Q30; + move32(); + Src_p->hrf_right_prev_fx[0] = ONE_IN_Q30; + move32(); Src_p->azim_prev_fx = 0; - move16(); + move32(); Src_p->elev_prev_fx = 0; + move32(); + Src_p->Gain_fx = MAX16B; move16(); - Src_p->Gain_fx = 32767; - move16(); - Src_p->prevGain_fx = 32767; + Src_p->prevGain_fx = MAX16B; move16(); return; } diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 31541a4e0730b7f1deb135820d2e35bbd272339c..cd30ab368d4e29ac97cbf7489191c95a1a098cf4 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -36,6 +36,8 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" +#include "prot_fx1.h" +#include "prot_fx2.h" /*-------------------------------------------------------------------* @@ -46,18 +48,18 @@ #ifdef IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecInit_fx( - Word16 *Pos_p, /* o : Output vector */ - const Word16 PosX, /* i : X value */ - const Word16 PosY, /* i : Y value */ - const Word16 PosZ /* i : Z value */ + Word32 *Pos_p, /* o : Output vector */ + const Word32 PosX, /* i : X value */ + const Word32 PosY, /* i : Y value */ + const Word32 PosZ /* i : Z value */ ) { Pos_p[0] = PosX; Pos_p[1] = PosY; Pos_p[2] = PosZ; - move16(); - move16(); - move16(); + move32(); + move32(); + move32(); return; } #endif // IVAS_FLOAT_FIXED @@ -83,6 +85,27 @@ void TDREND_SPATIAL_VecInit( *-------------------------------------------------------------------*/ /*! r: Euclidian norm value */ + +#ifdef IVAS_FLOAT_FIXED +Word32 TDREND_SPATIAL_VecNorm_fx( + const Word32 *Vec_p, /* i : Vector for norm calculation */ + const Word16 in_exp, /* i : Input exp */ + Word16 *out_exp /* o : Output exp */ +) +{ + Word32 tmp; + Word16 tmp_e; + tmp = L_add(L_add(Mpy_32_32(Vec_p[0], Vec_p[0]), Mpy_32_32(Vec_p[1], Vec_p[1])), Mpy_32_32(Vec_p[2], Vec_p[2])); + tmp_e = shl( in_exp, 1 ); // 2 * in_exp + tmp = Sqrt32( tmp, &tmp_e ); + *out_exp = tmp_e; + move16(); + + return tmp; +} + +#endif + float TDREND_SPATIAL_VecNorm( const float *Vec_p /* i : Vector for norm calculation */ ) @@ -96,25 +119,6 @@ float TDREND_SPATIAL_VecNorm( * * Normalize vector to unit norm *-------------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED -void TDREND_SPATIAL_VecNormalize_fx( - const Word16 *Vec_p, /* i : Input vector */ - Word16 *VecNorm_p /* o : Output vector */ -) -{ - Word32 scaler; - scaler = L_shr(Isqrt( L_add( L_mult0( Vec_p[0], Vec_p[0] ), L_add( L_mult0( Vec_p[1], Vec_p[1] ), L_mult0( Vec_p[2], Vec_p[2] ) ) ) ),1);//15 bit output - IF( scaler > MAX16B ) - { - scaler = MAX16B;/*Handling the overflow*/ - move32(); - } - VecNorm_p[0] = mult((Word16)scaler , Vec_p[0]); - VecNorm_p[1] = mult((Word16)scaler , Vec_p[1]); - VecNorm_p[2] = mult((Word16)scaler , Vec_p[2]); - return; -} -#endif // IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecNormalize( const float *Vec_p, /* i : Input vector */ @@ -131,6 +135,42 @@ void TDREND_SPATIAL_VecNormalize( return; } +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecNormalize_fx( + const Word32 *Vec_p_fx, /* i : Input vector Qx */ + Word16 q, /* i : Input vector Q-factor */ + Word32 *VecNorm_p_fx /* o : Normalised output vector Q30 */ +) +{ + Word32 scaler_fx; + Word32 sqrd_sum; + Word16 exp, shift; + + sqrd_sum = L_add( Mpy_32_32( Vec_p_fx[0], Vec_p_fx[0] ), L_add( Mpy_32_32( Vec_p_fx[1], Vec_p_fx[1] ), Mpy_32_32( Vec_p_fx[2], Vec_p_fx[2] ) ) ); + exp = 62-2*q; + scaler_fx = ISqrt32( sqrd_sum, &exp ); + + VecNorm_p_fx[0] = Mpy_32_32( scaler_fx, Vec_p_fx[0] ); + move16(); + VecNorm_p_fx[1] = Mpy_32_32( scaler_fx, Vec_p_fx[1] ); + move16(); + VecNorm_p_fx[2] = Mpy_32_32( scaler_fx, Vec_p_fx[2] ); + move16(); + exp = exp + (31 - q); + + // Since vector is normalised, all values will be <= 1. Hence making all values in Q30 + shift = exp - 1; + VecNorm_p_fx[0] = L_shl( VecNorm_p_fx[0], shift ); + move16(); + VecNorm_p_fx[1] = L_shl( VecNorm_p_fx[1], shift ); + move16(); + VecNorm_p_fx[2] = L_shl( VecNorm_p_fx[2], shift ); + move16(); + + return; +} +#endif + /*-------------------------------------------------------------------* * TDREND_SPATIAL_VecMapToNewCoordSystem() @@ -138,6 +178,30 @@ void TDREND_SPATIAL_VecNormalize( * Transform vector to new coordinate system *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecMapToNewCoordSystem_fx( + const Word32 *Vec_p, /* i : Input vector Qx */ + const Word32 *TranslVec_p, /* i : Translation vector Qx */ + const Word32 *DirVec_p, /* i : Direction vector Qy */ + const Word32 *UpVec_p, /* i : Up vector Qy */ + const Word32 *RightVec_p, /* i : Right vector Qy */ + Word32 *MappedVec_p, /* o : Transformed vector Qx+Qy-31 */ + Word32 *LisRelPosAbs /* o : Transformed vector ignoring orientation Qy */ +) +{ + v_sub_32(Vec_p, TranslVec_p, LisRelPosAbs, 3); + /* Evalute the relative Vec in the coordinates of the Orientation vectors, */ + /* which form an orthonormal basis */ + MappedVec_p[0] = dotp_fixed(LisRelPosAbs, DirVec_p, 3); + move32(); + MappedVec_p[1] = dotp_fixed(LisRelPosAbs, RightVec_p, 3); + move32(); + MappedVec_p[2] = dotp_fixed(LisRelPosAbs, UpVec_p, 3); + move32(); + return; +} +#endif + void TDREND_SPATIAL_VecMapToNewCoordSystem( const float *Vec_p, /* i : Input vector */ const float *TranslVec_p, /* i : Translation vector */ @@ -157,7 +221,6 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem( return; } - /*-------------------------------------------------------------------* * TDREND_SPATIAL_EvalOrthonormOrient() * @@ -212,3 +275,57 @@ int16_t TDREND_SPATIAL_EvalOrthonormOrient( return orientation_updated; } + +#ifdef IVAS_FLOAT_FIXED +Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( + Word32 *FrontVecON_p_fx, /* i/o: Normalized front vector Q30 */ + Word32 *UpVecON_p_fx, /* i/o: Normalized up vector Q30 */ + Word32 *RightVecON_p_fx, /* i/o: Normalized right vector Q30 */ + const Word32 *FrontVec_p_fx, /* i : Input front vector */ + const Word32 *UpVec_p_fx, /* i : Input up vector */ + const Word16 orient_q /* i : Input up Q-factor */ +) +{ + Word32 tmp_fx[9]; + Word16 orientation_updated; + + orientation_updated = FALSE; + move16(); + + /* Store current state to detect change */ + // Q30 + Copy32( FrontVecON_p_fx, tmp_fx, 3 ); + Copy32( RightVecON_p_fx, tmp_fx + 3, 3 ); + Copy32( UpVecON_p_fx, tmp_fx + 6, 3 ); + + /* Evaluate the normalized front vector */ + TDREND_SPATIAL_VecNormalize_fx( FrontVec_p_fx, orient_q, FrontVecON_p_fx ); // FrontVecON_p_fx -> Q30 + + /* Evaluate the orthonormal right vector */ + /* through the cross product of the front and the up vectors */ + RightVecON_p_fx[0] = L_shl_sat(L_sub(Mpy_32_32(FrontVecON_p_fx[1], UpVec_p_fx[2]), Mpy_32_32(FrontVecON_p_fx[2], UpVec_p_fx[1])),1); + RightVecON_p_fx[1] = L_shl_sat(L_sub(Mpy_32_32(FrontVecON_p_fx[2], UpVec_p_fx[0]), Mpy_32_32(FrontVecON_p_fx[0], UpVec_p_fx[2])),1); + RightVecON_p_fx[2] = L_shl_sat(L_sub(Mpy_32_32(FrontVecON_p_fx[0], UpVec_p_fx[1]), Mpy_32_32(FrontVecON_p_fx[1], UpVec_p_fx[0])),1); + + TDREND_SPATIAL_VecNormalize_fx( RightVecON_p_fx, orient_q, RightVecON_p_fx ); // RightVecON_p_fx -> Q30 + + /* Evaluate the orthonormal up vector */ + /* through the cross product of the front and the right vectors */ + UpVecON_p_fx[0] = L_shl_sat(L_sub( Mpy_32_32( RightVecON_p_fx[1], FrontVecON_p_fx[2] ), Mpy_32_32( RightVecON_p_fx[2], FrontVecON_p_fx[1] ) ), 1); + UpVecON_p_fx[1] = L_shl_sat(L_sub( Mpy_32_32( RightVecON_p_fx[2], FrontVecON_p_fx[0] ), Mpy_32_32( RightVecON_p_fx[0], FrontVecON_p_fx[2] ) ), 1); + UpVecON_p_fx[2] = L_shl_sat(L_sub( Mpy_32_32( RightVecON_p_fx[0], FrontVecON_p_fx[1] ), Mpy_32_32( RightVecON_p_fx[1], FrontVecON_p_fx[0] ) ), 1); + + TDREND_SPATIAL_VecNormalize_fx( UpVecON_p_fx, orient_q, UpVecON_p_fx); // UpVecON_p_fx -> Q30 + + /* Check if vectors have been changed */ + IF( NE_32( FrontVecON_p_fx[0], tmp_fx[0] ) || NE_32( FrontVecON_p_fx[1], tmp_fx[1] ) || NE_32( FrontVecON_p_fx[2], tmp_fx[2] ) || + NE_32( RightVecON_p_fx[0], tmp_fx[3] ) || NE_32( RightVecON_p_fx[1], tmp_fx[4] ) || NE_32( RightVecON_p_fx[2], tmp_fx[5] ) || + NE_32( UpVecON_p_fx[0], tmp_fx[6] ) || NE_32( UpVecON_p_fx[1], tmp_fx[7] ) || NE_32( UpVecON_p_fx[2], tmp_fx[8] ) ) + { + orientation_updated = TRUE; + move16(); + } + + return orientation_updated; +} +#endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index a66c4854376a945db234cdf118f3af45f03f6cce..37d26ae1f4665e5c0ca56882baf3fdf30e6959cc 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -963,6 +963,15 @@ ivas_error TDREND_GetMix( const int16_t subframe_idx, /* i : Subframe index to 5 ms subframe */ const int16_t ism_md_subframe_update /* i : Number of subframes to delay metadata to sync with audio */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_GetMix_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + float *output_flt[], /* i/o: ISM object synth / rendered output in 0,1 */ + const Word16 subframe_length, /* i/o: subframe length */ + const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */ + const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */ +); +#endif ivas_error TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ @@ -1020,7 +1029,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt( ivas_error TDREND_MIX_SRC_SetPos_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const Word16 SrcInd, /* i : Source index */ - const Word16 *Vec_p /* i : Position vector */ + const Word32 *Vec_p /* i : Position vector */ ); #endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetPos( @@ -1028,14 +1037,6 @@ ivas_error TDREND_MIX_SRC_SetPos( const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ); - -#ifdef IVAS_FLOAT_FIXED -ivas_error TDREND_MIX_SRC_SetDir_fx( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const Word16 SrcInd, /* i : Source index */ - const Word16 *Vec_p /* i : Direction vector */ -); -#endif ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -1043,9 +1044,10 @@ ivas_error TDREND_MIX_SRC_SetDir( ); #ifdef IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetDir_fx( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - const Word16 SrcInd, /* i : Source index */ - const Word16 *Vec_p /* i : Direction vector */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word32 *Vec_p, /* i : Direction vector */ + const Word16 Vec_p_q /* i : Direction vector q */ ); ivas_error TDREND_MIX_SRC_SetDirAtten_fx( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -1119,10 +1121,10 @@ void TDREND_SPATIAL_VecInit( ); #ifdef IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecInit_fx( - Word16 *Pos_p, /* o : Output vector */ - const Word16 PosX, /* i : X value */ - const Word16 PosY, /* i : Y value */ - const Word16 PosZ /* i : Z value */ + Word32 *Pos_p, /* o : Output vector */ + const Word32 PosX, /* i : X value */ + const Word32 PosY, /* i : Y value */ + const Word32 PosZ /* i : Z value */ ); #endif // IVAS_FLOAT_FIXED @@ -1132,8 +1134,9 @@ float TDREND_SPATIAL_VecNorm( ); #ifdef IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecNormalize_fx( - const Word16 *Vec_p, /* i : Input vector */ - Word16 *VecNorm_p /* o : Output vector */ + const Word32 *Vec_p_fx, /* i : Input vector Qx */ + Word16 q, /* i : Input vector Q-factor */ + Word32 *VecNorm_p_fx /* o : Normalised output vector Q30 */ ); #endif // IVAS_FLOAT_FIXED @@ -1152,6 +1155,16 @@ void TDREND_SPATIAL_VecMapToNewCoordSystem( float *LisRelPosAbs /* o : Transformed vector ignoring orientation */ ); +#ifdef IVAS_FLOAT_FIXED +Word16 TDREND_SPATIAL_EvalOrthonormOrient_fx( + Word32 *FrontVecON_p_fx, /* i/o: Normalized front vector Q30 */ + Word32 *UpVecON_p_fx, /* i/o: Normalized up vector Q30 */ + Word32 *RightVecON_p_fx, /* i/o: Normalized right vector Q30 */ + const Word32 *FrontVec_p_fx, /* i : Input front vector */ + const Word32 *UpVec_p_fx, /* i : Input up vector */ + const Word16 orient_q /* i : Input up Q-factor */ +); +#endif /*! r: Flag if the orientation has been updated */ int16_t TDREND_SPATIAL_EvalOrthonormOrient( float *FrontVecON_p, /* o : Normalized front vector */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index f0e39920a066b4eacb4fa86d4fb1b287b88a897a..2af418973548c471c52f6fbae220959cd7897e16 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -208,6 +208,69 @@ void ivas_headTrack_close( * Quaternion handling: calculate rotation matrices in real-space and SHD *---------------------------------------------------------------------------------*/ +#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 */ +) +{ + Word32 w = quat.w_fx; + move32(); + Word32 x = quat.x_fx; + move32(); + Word32 y = quat.y_fx; + move32(); + Word32 z = quat.z_fx; + move32(); + + // 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 + move32(); + Word32 xx = L_shr( Mpy_32_32( x, x ), 1 ); + move32(); + Word32 yy = L_shr( Mpy_32_32( y, y ), 1 ); + move32(); + Word32 zz = L_shr( Mpy_32_32( z, z ), 1 ); + move32(); + Word32 wx = Mpy_32_32( w, x ); + move32(); + Word32 wz = Mpy_32_32( w, z ); + move32(); + Word32 wy = Mpy_32_32( w, y ); + move32(); + Word32 xy = Mpy_32_32( x, y ); + move32(); + Word32 xz = Mpy_32_32( x, z ); + move32(); + Word32 yz = Mpy_32_32( y, z ); + move32(); + + Rmat[0][0] = L_sub( L_sub( L_add( ww, xx ), yy ), zz ); + move32(); + Rmat[0][1] = L_sub( xy, wz ); + move32(); + Rmat[0][2] = L_add( xz, wy ); + move32(); + + Rmat[1][0] = L_add( xy, wz ); + move32(); + Rmat[1][1] = L_sub( L_add( L_sub( ww, xx ), yy ), zz ); + move32(); + Rmat[1][2] = L_sub( yz, wx ); + move32(); + + Rmat[2][0] = L_sub( xz, wy ); + move32(); + Rmat[2][1] = L_add( yz, wx ); + move32(); + Rmat[2][2] = L_add( L_sub( L_sub( ww, xx ), yy ), zz ); + move32(); + + return; +} +#endif + void QuatToRotMat( const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 478e84c65e4af88880a680e3dbabbe495c06b8ce..8d1c7808f314bed003fd91a6464edaadc83ccce3 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1009,6 +1009,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 Quaternion_prev_extOrientation; IVAS_QUATERNION Quaternions_ext_interpolation_start; IVAS_QUATERNION Quaternions_ext_interpolation_target; @@ -1020,6 +1021,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_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; Word8 isExtOrientationFrozen; @@ -1521,11 +1523,12 @@ typedef struct float Vel[3]; #ifdef IVAS_FLOAT_FIXED - Word16 Pos_fx[3]; - Word16 Front_fx[3]; - Word16 Up_fx[3]; - Word16 Right_fx[3]; - Word16 Vel_fx[3]; + Word32 Pos_fx[3]; + Word32 Pos_q; + Word32 Front_fx[3]; + Word32 Up_fx[3]; + Word32 Right_fx[3]; + Word32 Vel_fx[3]; #endif // IVAS_FLOAT_FIXED } TDREND_MIX_Listener_t; @@ -1583,9 +1586,9 @@ typedef struct float ConeOuterAngle; float ConeOuterGain; #ifdef IVAS_FLOAT_FIXED - Word16 ConeInnerAngle_fx; - Word16 ConeOuterAngle_fx; - Word16 ConeOuterGain_fx; + Word16 ConeInnerAngle_fx; // Q6 + Word16 ConeOuterAngle_fx; // Q6 + Word16 ConeOuterGain_fx; // Q15 #endif // IVAS_FLOAT_FIXED } TDREND_DirAtten_t; @@ -1628,8 +1631,8 @@ typedef struct float Pos_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; float Front_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; #ifdef IVAS_FLOAT_FIXED - Word16 Pos_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; - Word16 Front_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; + Word32 Pos_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; // Q25 + Word32 Front_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; // Q30 #endif // IVAS_FLOAT_FIXED int16_t DirAttenEnabled; TDREND_DirAtten_t DirAtten; @@ -1647,13 +1650,14 @@ typedef struct int16_t previtd; int16_t filterlength; #ifdef IVAS_FLOAT_FIXED - Word16 mem_itd_fx[ITD_MEM_LEN]; - Word16 mem_hrf_left_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; - Word16 mem_hrf_right_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; - Word16 hrf_left_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; - Word16 hrf_right_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; - Word16 azim_prev_fx; - Word16 elev_prev_fx; + Word32 *InputFrame_p_fx; /* Input frame pointer */ + Word32 mem_itd_fx[ITD_MEM_LEN]; + Word32 mem_hrf_left_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + Word32 mem_hrf_right_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + Word32 hrf_left_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word32 hrf_right_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word32 azim_prev_fx; + Word32 elev_prev_fx; Word16 Gain_fx; Word16 prevGain_fx; #endif // IVAS_FLOAT_FIXED diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f0ab84417180806664ef9d2968a66ed8f5cca3d0..6ceed8018cb855fd9344f31cc4b27fe0acf6cf54 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -615,6 +615,8 @@ static Word32 limitRendererOutput_fx( } #endif + +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * limitRendererOutput() * @@ -659,6 +661,7 @@ static int32_t limitRendererOutput( return numClipping; } +#endif #ifdef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* @@ -10020,66 +10023,69 @@ static ivas_error getSamplesInternal( ) { ivas_error error; - int16_t numOutChannels; + Word16 numOutChannels; /* Validate function arguments */ - if ( hIvasRend == NULL || outAudio.data == NULL ) + test(); + IF ( hIvasRend == NULL || outAudio.data == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) + test(); + IF ( LE_16(outAudio.config.numSamplesPerChannel , 0) || LT_16(MAX_BUFFER_LENGTH_PER_CHANNEL , outAudio.config.numSamplesPerChannel) ) { return IVAS_ERR_INVALID_BUFFER_SIZE; } - if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) + test(); + IF ( LE_16(outAudio.config.numChannels , 0) || LT_16(MAX_OUTPUT_CHANNELS , outAudio.config.numChannels) ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && - outAudio.config.numSamplesPerChannel * 1000 != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) + IF ( EQ_32(getAudioConfigType( hIvasRend->outputConfig ) , IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL) && + NE_32(outAudio.config.numSamplesPerChannel * 1000 , ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut) ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } /* Check that there is allowed configuration for MASA format output */ - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + IF ( EQ_32(getAudioConfigType( hIvasRend->outputConfig ) , IVAS_REND_AUDIO_CONFIG_TYPE_MASA) ) { - int16_t i; - int16_t numMasaInputs = 0; - int16_t numOtherInputs = 0; + Word16 i; + Word16 numMasaInputs = 0; move16(); + Word16 numOtherInputs = 0; move16(); - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) + FOR ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) { numMasaInputs += hIvasRend->inputsMasa[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; } - for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) + FOR ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) { numOtherInputs += hIvasRend->inputsMc[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; } - for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; i++ ) + FOR ( i = 0; i < RENDERER_MAX_SBA_INPUTS; i++ ) { numOtherInputs += hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; } /* For ISM, we check only first as all ISMs are handled together via OMASA when merging to MASA. */ numOtherInputs += hIvasRend->inputsIsm[0].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; - - if ( numMasaInputs == 0 || numOtherInputs == 0 ) + test(); + IF ( EQ_16(numMasaInputs , 0) || EQ_16(numOtherInputs , 0) ) { return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } } - if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + IF ( NE_32(( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) , IVAS_ERR_OK) ) { return error; } - if ( numOutChannels != outAudio.config.numChannels ) + IF ( NE_16(numOutChannels , outAudio.config.numChannels) ) { return IVAS_ERR_WRONG_NUM_CHANNELS; } @@ -10088,37 +10094,36 @@ static ivas_error getSamplesInternal( set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); set_val_Word32( outAudio.data_fx, 0, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); - if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF ( NE_32(( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) , IVAS_ERR_OK) ) { return error; } - if ( ( error = renderActiveInputsMc( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF ( NE_32(( error = renderActiveInputsMc( hIvasRend, outAudio ) ) , IVAS_ERR_OK) ) { return error; } - if ( ( error = renderActiveInputsSba( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF ( NE_32(( error = renderActiveInputsSba( hIvasRend, outAudio ) ) , IVAS_ERR_OK) ) { return error; } - if ( ( error = renderActiveInputsMasa( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + IF ( NE_32(( error = renderActiveInputsMasa( hIvasRend, outAudio ) ) , IVAS_ERR_OK) ) { return error; } - if ( hIvasRend->inputsSba[0].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + IF ( NE_32(hIvasRend->inputsSba[0].base.inConfig , IVAS_AUDIO_CONFIG_INVALID) ) { - #ifndef DISABLE_LIMITER Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.pq_fact ); limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.pq_fact ); #endif } - else + ELSE { #ifndef DISABLE_LIMITER - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); + Word32 limiter_thresold = L_lshl( IVAS_LIMITER_THRESHOLD, *outAudio.pq_fact ); + limitRendererOutput_fx( hIvasRend->hLimiter, outAudio.data_fx, outAudio.config.numSamplesPerChannel, limiter_thresold, *outAudio.pq_fact); #endif - *outAudio.pq_fact = 0; } /* update global cominbed orientation start index */