diff --git a/lib_com/cnst.h b/lib_com/cnst.h index feece3ae908957fa0bffcc4f51cb4e4161073386..5619e905d47a82e1763c594e8d50905073b31474 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -144,6 +144,7 @@ * General constants *----------------------------------------------------------------------------------*/ +#define DEGREE_90_Q_22 377487360 #define DEGREE_180_Q_22 754974720 #define DEGREE_360_Q_22 1509949440 diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 029c82634c0a19c10b9e4ddac02da4504ded2dad..9ac7c79fa0c1c67526b1e4c58e1cc970e447891a 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -45,7 +45,8 @@ #define PI_OVER_2 ( EVS_PI / 2.0f ) #define PI_OVER_180 ( EVS_PI / 180.0f ) -#define ONE_BY_PI_OVER_180_Q25 ( 1922527360 ) +#define ONE_BY_PI_OVER_180_Q25 ( 1922527360 ) +#define PI_OVER_180_Q22 ( 73204 ) #define _180_OVER_PI ( 180.0f / EVS_PI ) #ifdef IVAS_FLOAT_FIXED #define _180_OVER_PI_Q25 1922521886 diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 0a07ebf4708e83fec11b6c4d4a8ccaac7214d5ac..008aa1b2e2956accf30ea70dc33ce60ecf4c9d20 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3295,4 +3295,45 @@ void ivas_mct_core_enc_fx( const Word16 sba_order /* i : Ambisonic (SBA) order */ ); +Word16 quantize_phi_chan_compand_fx( + Word32 phi, /* i : azimuth value Q22 */ + Word32 *phi_hat, /* o : quantized azimuth Q22 */ + const Word16 n, /* i : azimuth codebook size */ + const Word16 theta_flag, /* i : flag signaling high elevation */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +); + +Word16 quantize_phi_chan_lbr_fx( + const Word32 phi, /* i : azimuth value, Q22 */ + Word32 *phi_hat, /* o : quantized azimuth, Q22 */ + const Word16 n /* i : azimuth codebook size */ +); + +UWord16 quantize_direction_fx( + const Word32 theta, /* i : input elevation value, Q22 */ + Word32 phi, /* i : input azimuth value, Q22 */ + const Word16 no_bits, /* i : number of bits */ + Word32 *theta_q, /* o : quantized elevation, Q22 */ + Word32 *phi_q, /* o : quantized azimuth, Q22 */ + UWord16 *index_theta, /* o : quantized elevation index */ + UWord16 *index_phi, /* o : quantized azimuth index */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +); + +void quantize_direction_frame_fx( + IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ + Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* o : Q22 */ + Word32 elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* o : Q22 */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +); + +ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx( + BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ + IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */ + const Word16 bits_sph_idx, + const Word16 bits_sp_coh ); +void ivas_merge_masa_metadata_fx( + MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */ + OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */ +); #endif diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com.c index e4ae2107919bffa213460f371769c06169dd9cce..38a108a9ca36c74cf5cd53b44df1cf56e4ea9082 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com.c @@ -42,6 +42,7 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" #ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" #include "ivas_rom_com_fx.h" #endif @@ -421,9 +422,9 @@ int16_t quantize_phi( } #ifdef IVAS_FLOAT_FIXED Word16 quantize_phi_fx( - Word32 phi, /* i : azimuth value */ + Word32 phi, /* i : azimuth value, Q22 */ const Word16 flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */ - Word32 *phi_hat, /* o : quantized azimuth */ + Word32 *phi_hat, /* o : quantized azimuth, Q22 */ const Word16 n /* i : azimuth codebook size */ ) { @@ -584,7 +585,7 @@ float companding_azimuth( #ifdef IVAS_FLOAT_FIXED Word32 companding_azimuth_fx( - const Word32 azi_fx, /* i : input azimuth value */ + const Word32 azi_fx, /* i : input azimuth value, Q22 */ const MC_LS_SETUP mc_format, /* i : input channel format */ const Word16 theta_flag, /* i : zero/non zero elevation flag */ const Word16 direction /* i : direction of companding (direct or inverse)*/ @@ -813,6 +814,45 @@ int16_t quantize_phi_chan_lbr( return id_phi; } +#ifdef IVAS_FLOAT_FIXED +/*! r: index azimuth */ +Word16 quantize_phi_chan_lbr_fx( + const Word32 phi, /* i : azimuth value, Q22 */ + Word32 *phi_hat, /* o : quantized azimuth, Q22 */ + const Word16 n /* i : azimuth codebook size */ +) +{ + Word16 id_phi, phi_hat_16; + + + IF( LE_16( n, 1 ) ) + { + *phi_hat = 0; + move32(); + + return 0; + } + + id_phi = squant_fx( extract_l( L_shr( L_abs( phi ), 22 ) ) /* Q0 */, &phi_hat_16 /* Q0 */, cb_azi_chan_16fx, shr( n, 1 ) ); + *phi_hat = L_shl( L_deposit_l( phi_hat_16 ), Q22 ); // Q0 -> Q22 + move32(); + + test(); + IF( phi < 0 && id_phi > 0 ) + { + id_phi = sub( shl( id_phi, 1 ), 1 ); + *phi_hat = L_negate( *phi_hat ); + move32(); + } + ELSE + { + // id_phi *= 2; + id_phi = shl( id_phi, 1 ); + } + + return id_phi; +} +#endif /*-----------------------------------------------------------------------* @@ -884,3 +924,73 @@ int16_t quantize_phi_chan_compand( return id_phi; } +#ifdef IVAS_FLOAT_FIXED +/*! r: index azimuth */ +Word16 quantize_phi_chan_compand_fx( + Word32 phi, /* i : azimuth value Q22 */ + Word32 *phi_hat, /* o : quantized azimuth Q22 */ + const Word16 n, /* i : azimuth codebook size */ + const Word16 theta_flag, /* i : flag signaling high elevation */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +) +{ + Word16 id_phi; + Word32 delta_phi; // Q22 + Word16 tmp_e; + + IF( LE_16( n, 1 ) ) + { + *phi_hat = 0; + move32(); + + return 0; + } + + phi = companding_azimuth_fx( L_sub( phi, 180 << Q22 ), mc_format, theta_flag, 1 ); + + /* quantize companded value */ + // delta_phi = 360.0f / (float) n; + delta_phi = BASOP_Util_Divide3232_Scale_cadence( 360, n, &tmp_e ); + delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); // Q22 + // id_phi = (int16_t) round_f( ( phi / (float) delta_phi ) ); + id_phi = BASOP_Util_Divide3232_Scale( phi, delta_phi, &tmp_e ); + id_phi = shr( id_phi, sub( 15, tmp_e ) ); + + IF( add( id_phi, shr( n, 1 ) ) < 0 ) + { + id_phi = add( id_phi, 1 ); + } + IF( sub( id_phi, shr( n, 1 ) ) >= 0 ) + { + id_phi = negate( shr( n, 1 ) ); + } + + IF( EQ_16( id_phi, negate( add( shr( n, 1 ), ( n % 2 ) ) ) ) ) + { + id_phi = add( id_phi, ( n % 2 ) ); + } + ELSE{ + IF( EQ_16( id_phi, add( shr( n, 1 ), ( n % 2 ) ) ) ){ + IF( n % 2 ){ + id_phi = sub( id_phi, 1 ); +} +ELSE +{ + id_phi = negate( id_phi ); +} +} +} +//*phi_hat = id_phi * delta_phi; +*phi_hat = imult3216( delta_phi, id_phi ); +move32(); + +// id_phi += ( n >> 1 ); +id_phi = add( id_phi, shr( n, 1 ) ); + + +*phi_hat = L_add( companding_azimuth_fx( *phi_hat, mc_format, theta_flag, -1 ), DEGREE_180_Q_22 ); +move32(); + +return id_phi; +} +#endif diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index d0f437e70f554699f4c4d37b86607af27f1c9974..1ede703080ce5ab1b09cd2710fe20592755a663b 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1674,7 +1674,8 @@ const Word32 dd_val[90] = { 8778776, 8677870, 8579258, 8482862 }; -const Word32 cb_azi_chan_fx[] = { 0, 125829120, 461373440, 566231040 }; +const Word32 cb_azi_chan_fx[] = { 0, 125829120, 461373440, 566231040 }; // Q22 +const Word16 cb_azi_chan_16fx[] = { 0, 30, 110, 135 }; // Q0 /*----------------------------------------------------------------------------------* * MASA and ISM (OMASA) combined format ROM tables diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index ffb6692aab95733ed10e177e6b512f085acd9c1e..93a59b83c015bc25493cb07858d3ef299e368233 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -190,7 +190,8 @@ extern const Word32 shoebox_sin_cos_tbl_fx[11][2]; extern const Word32 delta_phi_val[90]; extern const Word32 inv_delta_phi_val[90]; extern const Word32 dd_val[90]; -extern const Word32 cb_azi_chan_fx[]; +extern const Word32 cb_azi_chan_fx[]; // Q22 +extern const Word16 cb_azi_chan_16fx[]; // Q0 /*----------------------------------------------------------------------------------* * MASA and ISM (OMASA) combined format ROM tables diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 283896b865d9b25b10d65c38653ff7df4609bbe7..ed28e35ea4a117c07948b994b75f9d7d625af4e6 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -471,9 +471,9 @@ typedef struct ivas_masa_common_spatial_meta_struct float diffuse_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; float surround_coherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; #ifdef IVAS_FLOAT_FIXED - Word32 diffuse_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word16 surround_coherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 remainder_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 diffuse_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q30 + Word16 surround_coherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q15 + Word32 remainder_to_total_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; // Q30 #endif float remainder_to_total_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index a468fe60781de9389288dc3825bce0da4fec8508..6bce3e26534ddfb011648b35ba96c28e86f2c8b4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6535,28 +6535,28 @@ void bass_psfilter_init_fx( ); void bass_psfilter_fx( - BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ - const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag */ - Word16 synth_in_fx[], /* i : i synthesis (at 16kHz) */ - const Word16 L_frame, /* i : length of the last frame */ - Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] */ - const Word16 bpf_off, /* i : do not use BPF when set to 1 */ - Word16 v_stab_fx, /* i : stability factor */ - Word16 *v_stab_smooth_fx, /* i/o: smoothed stability factor */ - const Word16 coder_type, /* i : coder_type */ + BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ + const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag Q0*/ + Word16 synth_in_fx[], /* i : input synthesis (at 16kHz) Q_syn2-1*/ + const Word16 L_frame, /* i : length of the last frame Q0*/ + Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] Q6*/ + const Word16 bpf_off, /* i : do not use BPF when set to 1 Q0*/ + Word16 v_stab_fx, /* i : stability factor Q15*/ + Word16 *v_stab_smooth_fx, /* i/o: smoothed stability factor Q15*/ + const Word16 coder_type, /* i : coder_type Q0*/ Word16 Q_syn, - Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ + Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) Qx*/ ); void addBassPostFilter_fx( - const Word16 *harm_timeIn_Fx, - Word32 **rAnalysis_Fx, - Word32 **iAnalysis_Fx, + const Word16 *harm_timeIn_Fx, /* timeIn_e */ + Word32 **rAnalysis_Fx, /* Qx - 5 */ + Word32 **iAnalysis_Fx, /* Qx - 5 */ HANDLE_CLDFB_FILTER_BANK cldfbBank_bpf_Fx, - Word32 *workBuffer, + Word32 *workBuffer, /* Qx */ const Word16 timeIn_e, - const Word16 nTimeSlots, - const Word16 nTimeSlotsTotal, - const Word16 nBandsTotal, + const Word16 nTimeSlots, /* Q0 */ + const Word16 nTimeSlotsTotal, /* Q0 */ + const Word16 nBandsTotal, /* Q0 */ CLDFB_SCALE_FACTOR *cldfb_scale ); // FEC_fx.c @@ -6837,19 +6837,19 @@ Word16 gain_dequant_fx( /* o: decoded gain */ // avq_dec_fx.c void AVQ_demuxdec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - Word16 xriq[], /* o : decoded subvectors [0..8*Nsv-1]*/ - Word16 *nb_bits, /* i/o: number of allocated bits */ - const Word16 Nsv, /* i : number of subvectors */ - Word16 nq[], /* i/o: AVQ nq index */ - Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution */ - Word16 trgtSvPos /* i : target SV for AVQ bit savings */ + Decoder_State *st, /* i/o: decoder state structure */ + Word16 xriq[], /* o : decoded subvectors [0..8*Nsv-1] Q0*/ + Word16 *nb_bits, /* i/o: number of allocated bits Q0*/ + const Word16 Nsv, /* i : number of subvectors Q0*/ + Word16 nq[], /* i/o: AVQ nq index Q0*/ + Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution Q0*/ + Word16 trgtSvPos /* i : target SV for AVQ bit savings Q0*/ ); void AVQ_dec_lpc( - Word16 *indx, /* i : index[] (4 bits per words) */ - Word16 *nvecq, /* o : vector quantized */ - Word16 Nsv ); /* i : number of subvectors (lg=Nsv*8) */ + Word16 *indx, /* input: index[] (4 bits per words) Q0*/ + Word16 *nvecq, /* output: vector quantized Q0*/ + Word16 Nsv ); /* input: number of subvectors (lg=Nsv*8) Q0*/ #ifdef IVAS_FLOAT_FIXED diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index f2209944953031b27796dfe8798b715ad9731a8c..a72d87b8a1291e5b60bd4dea993eaab1270e74a8 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -36,16 +36,18 @@ static void common_overlapping_fx( Word16 *auOut_fx, Word16 *ImdctOutWin_fx, Wor *--------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED static void Regression_Anal_fx( - const Word32 *values_fx, /* i : Previous values */ - Word32 *r_p_fx, /* o : Output r[a b] array : y=ax+b */ - const Word16 num_pgf /* i : Number of previous good frame */ + const Word32 *values_fx, + /* i : Previous values */ // Q12 + Word32 *r_p_fx, + /* o : Output r[a b] array : y=ax+b */ // Q5 + const Word16 num_pgf /* i : Number of previous good frame */ ) { Word16 i; Word16 tmp; Word32 L_tmp1, L_tmp2; - Word16 aindex_fx[MAX_PGF + 1]; - Word32 b_p_fx[MAX_PGF + 1]; + Word16 aindex_fx[MAX_PGF + 1]; // Q0 + Word32 b_p_fx[MAX_PGF + 1]; // Q10 #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); @@ -97,18 +99,21 @@ static void Regression_Anal_fx( L_tmp2 = L_sub( Mult_32_16( b_p_fx[1], shl( aindex_fx[0], 10 ) ), Mult_32_16( b_p_fx[0], shl( aindex_fx[1], 10 ) ) ); /*5 */ r_p_fx[0] = Mult_32_16( L_tmp1, tmp ); move32(); - r_p_fx[1] = Mult_32_16( L_tmp2, tmp ); + r_p_fx[1] = Mult_32_16( L_tmp2, tmp ); // Q15 + Q5 - Q15 move32(); return; } static void FEC_scaling_fx( - Word32 *old_coeffs_fx, /* i/o : Pointer to old MDCT coeffs. */ - Word32 *t_audio_q_fx, /* o : MDCT coeffs. (for synthesis) */ - Word16 *Norm_gain_fx, /* i : Gain for Norm of each band */ - Word16 *HQ_FEC_seed, /* i/o : Seed for Ransom number Generator */ - Word16 nb_sfm, /* i : Number of sub-band */ + Word32 *old_coeffs_fx, + /* i/o : Pointer to old MDCT coeffs. */ // Q12 + Word32 *t_audio_q_fx, + /* o : MDCT coeffs. (for synthesis) */ // Q12 + Word16 *Norm_gain_fx, + /* i : Gain for Norm of each band */ // Q15 + Word16 *HQ_FEC_seed, /* i/o : Seed for Ransom number Generator */ + Word16 nb_sfm, /* i : Number of sub-band */ const Word16 *start_band, const Word16 *end_band ) { @@ -118,7 +123,7 @@ static void FEC_scaling_fx( { FOR( j = start_band[i]; j < end_band[i]; j++ ) { - t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); /*12 */ + t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); // Q12 + Q15 - Q15 move32(); } } @@ -129,12 +134,12 @@ static void FEC_scaling_fx( { IF( Random( HQ_FEC_seed ) < 0 ) { - t_audio_q_fx[j] = Mult_32_16( L_negate( old_coeffs_fx[j] ), Norm_gain_fx[i] ); /*12*/ + t_audio_q_fx[j] = Mult_32_16( L_negate( old_coeffs_fx[j] ), Norm_gain_fx[i] ); // Q12 + Q15 - Q15 move32(); } ELSE { - t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); /*12*/ + t_audio_q_fx[j] = Mult_32_16( old_coeffs_fx[j], Norm_gain_fx[i] ); // Q12 + Q15 - Q15 move32(); } } @@ -163,8 +168,8 @@ void HQ_FEC_processing_fx( Word16 tmp_fx, exp1, exp2; Word32 norm_p_fx[MAX_SB_NB]; - Word32 *norm_values_fx, *r_p_fx; - Word16 energy_diff_fx; + Word32 *norm_values_fx /*Q12*/, *r_p_fx /*Q5*/; + Word16 energy_diff_fx; // Q10 HQ_NBFEC_HANDLE hHQ_nbfec; HQ_DEC_HANDLE hHQ_core; #ifdef BASOP_NOGLOB_DECLARE_LOCAL @@ -238,7 +243,7 @@ void HQ_FEC_processing_fx( { FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ ) { - t_audio_q_fx[add( i, imult1616( sfm, HQ_FEC_BAND_SIZE ) )] = L_negate( t_audio_q_fx[add( i, imult1616( sfm, HQ_FEC_BAND_SIZE ) )] ); + t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] = L_negate( t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] ); move32(); } } @@ -252,7 +257,7 @@ void HQ_FEC_processing_fx( { FOR( i = 0; i < HQ_FEC_BAND_SIZE; i++ ) { - t_audio_q_fx[add( i, imult1616( sfm, HQ_FEC_BAND_SIZE ) )] = L_negate( t_audio_q_fx[add( i, imult1616( sfm, HQ_FEC_BAND_SIZE ) )] ); + t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] = L_negate( t_audio_q_fx[i + sfm * HQ_FEC_BAND_SIZE] ); move32(); } } @@ -446,9 +451,9 @@ void ivas_HQ_FEC_Mem_update_fx( Word16 i, j, k; Word16 offset; Word16 exp, exp1, exp2, tmp_fx; - Word32 *norm_values_fx; - Word32 L_tmp, tmp_energy_fx = 0, Max_coeff_fx; - Word32 en_high_fx[MAX_SB_NB]; + Word32 *norm_values_fx; // Q12 + Word32 L_tmp, tmp_energy_fx = 0 /*Q8*/, Max_coeff_fx /*Q12*/; + Word32 en_high_fx[MAX_SB_NB]; // Q12 HQ_NBFEC_HANDLE hHQ_nbfec; HQ_DEC_HANDLE hHQ_core; hHQ_nbfec = st_fx->hHQ_nbfec; @@ -480,7 +485,7 @@ void ivas_HQ_FEC_Mem_update_fx( test(); test(); test(); - IF( ( hHQ_nbfec->old_coeffs_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] > 0 && t_audio_q_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] < 0 && t_audio_q_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] > 0 ) ) + IF( ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] > 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] < 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] > 0 ) ) { hHQ_nbfec->prev_sign_switch[j] = add( hHQ_nbfec->prev_sign_switch[j], 1 ); move16(); @@ -624,7 +629,7 @@ void ivas_HQ_FEC_Mem_update_fx( Max_coeff_fx = L_deposit_l( 0 ); FOR( i = 0; i < 8; i++ ) { - L_tmp = L_abs( t_audio_q_fx[i] ); + L_tmp = L_abs( t_audio_q_fx[i] ); // Q12 IF( LT_32( Max_coeff_fx, L_tmp ) ) { Max_coeff_fx = L_add( L_tmp, 0 ); @@ -739,9 +744,9 @@ void HQ_FEC_Mem_update_fx( Word16 i, j, k; Word16 offset; Word16 exp, exp1, exp2, tmp_fx; - Word32 *norm_values_fx; - Word32 L_tmp, tmp_energy_fx = 0, Max_coeff_fx; - Word32 en_high_fx[MAX_SB_NB]; + Word32 *norm_values_fx; // Q12 + Word32 L_tmp, tmp_energy_fx = 0 /*Q8*/, Max_coeff_fx /*Q12*/; + Word32 en_high_fx[MAX_SB_NB]; // Q12 HQ_NBFEC_HANDLE hHQ_nbfec; HQ_DEC_HANDLE hHQ_core; hHQ_nbfec = st_fx->hHQ_nbfec; @@ -775,7 +780,7 @@ void HQ_FEC_Mem_update_fx( test(); test(); test(); - IF( ( hHQ_nbfec->old_coeffs_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] > 0 && t_audio_q_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] < 0 && t_audio_q_fx[add( i, imult1616( j, HQ_FEC_BAND_SIZE ) )] > 0 ) ) + IF( ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] > 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] < 0 ) || ( hHQ_nbfec->old_coeffs_fx[i + j * HQ_FEC_BAND_SIZE] < 0 && t_audio_q_fx[i + j * HQ_FEC_BAND_SIZE] > 0 ) ) { hHQ_nbfec->prev_sign_switch[j] = add( hHQ_nbfec->prev_sign_switch[j], 1 ); move16(); @@ -1023,8 +1028,8 @@ void HQ_FEC_Mem_update_fx( #ifdef IVAS_FLOAT_FIXED static Word16 find_best_delay_fx( - Word16 *mu_o_fx, - Word16 *in_fx, + Word16 *mu_o_fx, // Qx + Word16 *in_fx, // Qx Word16 mind1, Word16 maxd1, Word16 lin, @@ -1056,8 +1061,8 @@ static Word16 find_best_delay_fx( FOR( i = 0; i < lin; i += delta ) { #ifdef BASOP_NOGLOB - accA_fx = L_add_sat( accA_fx, L_shr( L_mult_sat( mu_o_fx[add( d1, i )], mu_o_fx[add( d1, i )] ), 2 ) ); - accB_fx = L_add_sat( accB_fx, L_shr( L_mult_sat( mu_o_fx[add( d1, i )], in_fx[i] ), 2 ) ); + accA_fx = L_add_sat( accA_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], mu_o_fx[d1 + i] ), 2 ) ); + accB_fx = L_add_sat( accB_fx, L_shr( L_mult_sat( mu_o_fx[d1 + i], in_fx[i] ), 2 ) ); #else accA_fx = L_add( accA_fx, L_shr( L_mult( mu_o_fx[d1 + i], mu_o_fx[d1 + i] ), 2 ) ); accB_fx = L_add( accB_fx, L_shr( L_mult( mu_o_fx[d1 + i], in_fx[i] ), 2 ) ); @@ -1134,9 +1139,10 @@ static Word16 find_best_delay_fx( } static Word16 Search_Max_Corr_fx( - Word16 *mu_o_fx, /* i : *old_auOut_2fr, */ - Word16 old_Min_ind, /* i : *old_auOut_2fr, */ - const Word16 L /* i : L/2 */ + Word16 *mu_o_fx, + /* i : *old_auOut_2fr, */ // Qx + Word16 old_Min_ind, /* i : *old_auOut_2fr, */ + const Word16 L /* i : L/2 */ ) { Word16 pos; @@ -1146,7 +1152,7 @@ static Word16 Search_Max_Corr_fx( Word16 false_flag; Word16 min_d1, max_d1; Word16 tmp1, tmp2; - Word16 *in_fx; + Word16 *in_fx; // Qx IF( old_Min_ind == 0 ) { @@ -1233,11 +1239,11 @@ static Word16 Search_Max_Corr_fx( } static Word16 FEC_phase_matching_fx( - HQ_NBFEC_HANDLE st_fx, /* i : Decoder State */ - Word32 *ImdctOut_fx, /* i : input */ - Word16 *auOut_fx, /* o : output audio */ - Word16 *OldauOut_fx, - Word16 OldauOut_pha_fx[2][N_LEAD_NB] ) + HQ_NBFEC_HANDLE st_fx, /* i : Decoder State */ + Word32 *ImdctOut_fx, /* i : input, Q6 */ + Word16 *auOut_fx, /* o : output audio, Q0 */ + Word16 *OldauOut_fx, // Q0 + Word16 OldauOut_pha_fx[2][N_LEAD_NB] ) // Qx { Word16 i; Word16 pos, remain; @@ -1246,10 +1252,10 @@ static Word16 FEC_phase_matching_fx( Word16 ImdctOutWin_fx[2 * L_FRAME8k]; Word16 OldauOutnoWin_fx[L_FRAME8k]; Word16 OldauOut2_fx[L_FRAME8k]; - Word16 win_NB_fx[L_FRAME8k + 25]; + Word16 win_NB_fx[L_FRAME8k + 25]; // Q15 Word16 exp1, exp2, tmp; Word32 pow1_fx, pow22_fx; - Word16 SmoothingWin_NB3_fx[24]; + Word16 SmoothingWin_NB3_fx[24]; // Q15 L = L_FRAME8k; move16(); @@ -1260,13 +1266,13 @@ static Word16 FEC_phase_matching_fx( FOR( i = 0; i < L_overlap; i++ ) { - SmoothingWin_NB3_fx[i] = SmoothingWin_NB875_fx[imult1616( i, 3 )]; + SmoothingWin_NB3_fx[i] = SmoothingWin_NB875_fx[i * 3]; move16(); } - FOR( i = 0; i < add( L, 25 ); i++ ) + FOR( i = 0; i < L + 25; i++ ) { - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } set16_fx( ImdctOutWin_fx, 0, shl( L, 1 ) ); @@ -1283,24 +1289,24 @@ static Word16 FEC_phase_matching_fx( Copy( &st_fx->old_auOut_2fr_fx[pos], &ImdctOutWin_fx[N_ZERO_NB], sub( shl( L, 1 ), pos ) ); /* OldauOut without windowing */ - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { - OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[L / 2 - 1 - i] ), 6 ) ); // Q6 -> Q0 move16(); } - FOR( i = 0; i < shr( L, 1 ); i++ ) + FOR( i = 0; i < L / 2; i++ ) { - OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[i] ), 6 ) ); + OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( st_fx->oldIMDCTout_fx[i] ), 6 ) ); // Q6 -> Q0 move16(); } - Copy( OldauOutnoWin_fx, &ImdctOutWin_fx[add( N_ZERO_NB, sub( shl( L, 1 ), pos ) )], remain ); + Copy( OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB + ( 2 * L ) - pos], remain ); pow1_fx = L_deposit_l( 0 ); pow22_fx = L_deposit_l( 0 ); FOR( i = 0; i < L; i++ ) { - pow1_fx = L_add( pow1_fx, shr( abs_s( st_fx->old_auOut_2fr_fx[add( L, i )] ), 1 ) ); + pow1_fx = L_add( pow1_fx, shr( abs_s( st_fx->old_auOut_2fr_fx[L + i] ), 1 ) ); pow22_fx = L_add( pow22_fx, shr( abs_s( ImdctOutWin_fx[N_ZERO_NB + i] ), 1 ) ); } IF( pow22_fx != 0 ) @@ -1309,7 +1315,7 @@ static Word16 FEC_phase_matching_fx( exp2 = norm_l( pow22_fx ); tmp = div_s( extract_h( L_shl( pow1_fx, exp1 ) ), extract_h( L_shl( pow22_fx, exp2 ) ) ); /*15 + exp1 - exp2*/ tmp = shl( tmp, sub( sub( exp2, exp1 ), 1 ) ); /*14*/ - FOR( i = N_ZERO_NB; i < shl( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L * 2; i++ ) { #ifdef BASOP_NOGLOB ImdctOutWin_fx[i] = shl_sat( mult( ImdctOutWin_fx[i], tmp ), 1 ); @@ -1321,30 +1327,30 @@ static Word16 FEC_phase_matching_fx( } Smoothing_vector_NB_fx( OldauOutnoWin_fx, &ImdctOutWin_fx[N_ZERO_NB], SmoothingWin_NB2_fx, auOut_fx, ol_size ); - FOR( i = 0; i < shr( L, 1 ); i++ ) + FOR( i = 0; i < L / 2; i++ ) { /*ImdctOutWin[3*L/2 + i] *= win_NB[L/2-i-1];*/ - ImdctOutWin_fx[add( shr( imult1616( 3, L ), 1 ), i )] = mult( ImdctOutWin_fx[add( shr( imult1616( 3, L ), 1 ), i )], win_NB_fx[sub( sub( shr( L, 1 ), i ), 1 )] ); + ImdctOutWin_fx[3 * L / 2 + i] = mult( ImdctOutWin_fx[3 * L / 2 + i], win_NB_fx[L / 2 - i - 1] ); move16(); } - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { /*ImdctOutWin_fx[L + i] *= win_NB_fx[(L-1-i)];*/ - ImdctOutWin_fx[add( L, i )] = mult( ImdctOutWin_fx[add( L, i )], win_NB_fx[sub( sub( L, 1 ), i )] ); + ImdctOutWin_fx[L + i] = mult( ImdctOutWin_fx[L + i], win_NB_fx[( L - 1 - i )] ); move16(); } Copy( &ImdctOutWin_fx[N_Z_L_O_NB], &OldauOut_pha_fx[0][0], N_LEAD_NB ); - Copy( &ImdctOutWin_fx[add( ol_size, N_ZERO_NB )], &auOut_fx[ol_size], sub( N_Z_L_NB, ol_size ) ); + Copy( &ImdctOutWin_fx[ol_size + N_ZERO_NB], &auOut_fx[ol_size], sub( N_Z_L_NB, ol_size ) ); Copy( &ImdctOutWin_fx[L], &auOut_fx[N_Z_L_NB], N_ZERO_NB ); Copy( &ImdctOutWin_fx[L], OldauOut_fx, L ); FOR( i = 0; i < shr( L, 1 ); i++ ) { - OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); move16(); - OldauOut2_fx[add( shr( L, 1 ), i )] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); + OldauOut2_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); move16(); } @@ -1360,9 +1366,9 @@ static Word16 FEC_phase_matching_fx( } static void FEC_phase_matching_nextgood_fx( - const Word32 *ImdctOut_fx, /* i : input */ + const Word32 *ImdctOut_fx, /* i : input Q6 */ Word16 *auOut_fx, /* o : output audio */ - Word16 *OldauOut_fx, /* i/o: audio from previous frame */ + Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */ Word16 OldauOut_pha_fx[2][N_LEAD_NB], Word16 mean_en_high_fx /*Q5 */ ) @@ -1370,7 +1376,7 @@ static void FEC_phase_matching_nextgood_fx( Word16 i; Word16 L_overlap, L; Word16 oldout_pha_idx; - Word16 *OldOut_pha_fx; + Word16 *OldOut_pha_fx; // Qx Word16 ImdctOutWin_fx[2 * L_FRAME48k]; Word16 win_NB_fx[L_FRAME8k + 25]; @@ -1379,7 +1385,7 @@ static void FEC_phase_matching_nextgood_fx( FOR( i = 0; i < L + 25; i++ ) { /* win_NB[i] = window_48kHz[i*6+3]; */ - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } @@ -1402,7 +1408,7 @@ static void FEC_phase_matching_nextgood_fx( FOR( i = 0; i < N_LEAD_NB; i++ ) { /* OldOut_pha[i] *= SmoothingWin_NB875[L_overlap-i-1]; */ - OldOut_pha_fx[i] = mult( OldOut_pha_fx[i], SmoothingWin_NB875_fx[sub( sub( L_overlap, i ), 1 )] ); + OldOut_pha_fx[i] = mult( OldOut_pha_fx[i], SmoothingWin_NB875_fx[L_overlap - i - 1] ); move16(); } @@ -1432,11 +1438,11 @@ static void FEC_phase_matching_nextgood_fx( #ifdef IVAS_FLOAT_FIXED static void FEC_phase_matching_burst_fx( - const Word32 *ImdctOut_fx, /* i : input */ - Word16 *auOut_fx, /* o : output audio */ - Word16 *OldauOut_fx, /* i/o: audio from previous frame */ + const Word32 *ImdctOut_fx, /* i : input Q6 */ + Word16 *auOut_fx, /* o : output audio Q0 */ + Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */ Word16 OldauOut_pha_fx[2][N_LEAD_NB], - Word16 *prev_oldauOut_fx /* i : OldauOut from previous frame */ + Word16 *prev_oldauOut_fx /* i : OldauOut from previous frame Q0 */ ) { Word16 i; @@ -1460,7 +1466,7 @@ static void FEC_phase_matching_burst_fx( FOR( i = 0; i < add( L, 25 ); i++ ) { - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } @@ -1480,13 +1486,13 @@ static void FEC_phase_matching_burst_fx( Copy( &ImdctOutWin_fx[L], OldauOut_fx, L ); Scaledown_fx( prev_oldauOut_fx, prev_oldauOut_fx, 23170, L ); - FOR( i = 0; i < shr( L, 1 ); i++ ) + FOR( i = 0; i < L / 2; i++ ) { /* OldauOut2[i] = -ImdctOut[L/2 - 1 - i];*/ /* OldauOut2[L/2+i] = -ImdctOut[i];*/ - OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + OldauOut2_fx[i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); // Q6 -> Q0 move16(); - OldauOut2_fx[add( shr( L, 1 ), i )] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); + OldauOut2_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); // Q6 -> Q0 move16(); } @@ -1503,10 +1509,10 @@ static void FEC_phase_matching_burst_fx( } static void Repetition_smoothing_nextgood_fx( - const Word32 *ImdctOut_fx, /* i : input */ - Word16 *auOut_fx, /* o : output audio */ - Word32 *OldImdctOut_fx, /* i : input */ - Word16 *OldauOut_fx, /* i/o: audio from previous frame */ + const Word32 *ImdctOut_fx, /* i : input Q6 */ + Word16 *auOut_fx, /* o : output audio Q0 */ + Word32 *OldImdctOut_fx, /* i : input Q6 */ + Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */ Word16 cur_data_use_flag, /* i : current imdct data use flag */ Word16 overlap_time ) { @@ -1514,7 +1520,7 @@ static void Repetition_smoothing_nextgood_fx( Word16 L_overlap; Word16 ol_size; Word16 L; - Word16 ImdctOutWin_fx[2 * L_FRAME8k]; + Word16 ImdctOutWin_fx[2 * L_FRAME8k]; // Q0 Word16 win_NB_fx[L_FRAME8k + 25]; L = L_FRAME8k; @@ -1523,17 +1529,17 @@ static void Repetition_smoothing_nextgood_fx( FOR( i = 0; i < L_FRAME8k + 25; i++ ) { /*win_NB[i] = window_48kHz[i*6+3];*/ - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { /*OldauOut[i-N_ZERO_NB] = -OldImdctOut[L/2 - 1 - i];*/ - OldauOut_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); /* Q6 -> Q0 */ + OldauOut_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */ move16(); } - FOR( i = 0; i < shr( L, 2 ); i++ ) + FOR( i = 0; i < L / 4; i++ ) { /*OldauOut[i+N_ZERO_O_NB] = -OldImdctOut[i];*/ OldauOut_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */ @@ -1546,15 +1552,15 @@ static void Repetition_smoothing_nextgood_fx( ol_size = N_LEAD_NB; move16(); - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { /* ImdctOutWin[i+L] = -ImdctOut[L/2 - 1 - i]; */ - ImdctOutWin_fx[add( i, L )] = extract_l( L_shr( L_negate( ImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + ImdctOutWin_fx[add( i, L )] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */ move16(); } - FOR( i = 0; i < shr( L, 1 ); i++ ) + FOR( i = 0; i < L / 2; i++ ) { - ImdctOutWin_fx[add( i, shr( imult1616( 3, L ), 1 ) )] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); + ImdctOutWin_fx[i + 3 * L / 2] = extract_l( L_shr( L_negate( ImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */ move16(); } @@ -1562,7 +1568,7 @@ static void Repetition_smoothing_nextgood_fx( Smoothing_vector_scaledown_NB_fx( OldauOut_fx, &ImdctOutWin_fx[N_Z_L_O_NB], SmoothingWin_NB875_fx, OldauOut_fx, ol_size ); /* Scale down the overlapped signal */ - Scaledown_fx( &ImdctOutWin_fx[add( ol_size, N_Z_L_O_NB )], &OldauOut_fx[ol_size], 23170, sub( N_Z_L_NB, ol_size ) ); + Scaledown_fx( &ImdctOutWin_fx[ol_size + N_Z_L_O_NB], &OldauOut_fx[ol_size], 23170, sub( N_Z_L_NB, ol_size ) ); // SCALE_DOWN_3dB.Q15 = 23170 } L_overlap = overlap_time; @@ -1570,7 +1576,7 @@ static void Repetition_smoothing_nextgood_fx( FOR( i = 0; i < L_overlap; i++ ) { /*OldauOut[i] *= SmoothingWin_NB875[L_overlap-i-1];*/ - OldauOut_fx[i] = mult( OldauOut_fx[i], SmoothingWin_NB875_fx[sub( sub( L_overlap, i ), 1 )] ); + OldauOut_fx[i] = mult( OldauOut_fx[i], SmoothingWin_NB875_fx[L_overlap - i - 1] ); move16(); } FOR( i = L_overlap; i < L; i++ ) @@ -1590,7 +1596,7 @@ static void Repetition_smoothing_nextgood_fx( FOR( i = 0; i < L; i++ ) { #ifdef BASOP_NOGLOB - auOut_fx[i] = add_sat( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); + auOut_fx[i] = add_sat( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); // Q0 #else auOut_fx[i] = add( ImdctOutWin_fx[N_ZERO_NB + i], OldauOut_fx[i] ); #endif @@ -1602,26 +1608,26 @@ static void Repetition_smoothing_nextgood_fx( } static Word16 Repetition_smoothing_fx( - const Word32 *ImdctOut_fx, /* i : input */ - Word16 *auOut_fx, /* o : output audio */ - Word32 *OldImdctOut_fx, /* i : input */ - Word16 *OldauOut_fx, /* i/o: audio from previous frame */ + const Word32 *ImdctOut_fx, /* i : input Q6 */ + Word16 *auOut_fx, /* o : output audio Q0 */ + Word32 *OldImdctOut_fx, /* i : input Q6 */ + Word16 *OldauOut_fx, /* i/o: audio from previous frame Q0 */ const Word16 L, /* i : length */ - Word16 *prev_oldauOut_fx, /* i : OldauOut from previous frame */ + Word16 *prev_oldauOut_fx, /* i : OldauOut from previous frame Q0 */ Word16 overlap_time /* i : overlap time */ ) { Word16 i; Word32 pow1_fx; Word32 pow22_fx; - Word16 ImdctOutWin_fx[2 * L_FRAME8k]; - Word16 OldauOutnoWin_fx[L_FRAME8k]; + Word16 ImdctOutWin_fx[2 * L_FRAME8k]; // Q0 + Word16 OldauOutnoWin_fx[L_FRAME8k]; // Q0 Word16 win_NB_fx[L_FRAME8k + 25]; FOR( i = 0; i < L_FRAME8k + 25; i++ ) { /*win_NB[i] = window_48kHz[i*6+3];*/ - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } @@ -1633,14 +1639,14 @@ static Word16 Repetition_smoothing_fx( common_overlapping_fx( auOut_fx, ImdctOutWin_fx, prev_oldauOut_fx, N_Z_L_NB, 0, N_Z_L_NB, L, N_ZERO_NB, 0 ); /* OldauOut without windowing */ - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { - OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + OldauOutnoWin_fx[i - N_ZERO_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); /* Q6 -> Q0 */ move16(); } - FOR( i = 0; i < shr( L, 1 ); i++ ) + FOR( i = 0; i < L / 2; i++ ) { - OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[i] ), 6 ) ); + OldauOutnoWin_fx[i + N_ZERO_O_NB] = extract_l( L_shr( L_negate( OldImdctOut_fx[i] ), 6 ) ); /* Q6 -> Q0 */ move16(); } @@ -1649,9 +1655,9 @@ static Word16 Repetition_smoothing_fx( pow1_fx = L_deposit_l( 0 ); pow22_fx = L_deposit_l( 0 ); - FOR( i = 0; i < idiv1616( imult1616( 4, L ), 20 ); i++ ) + FOR( i = 0; i < ( 4 * L ) / 20; i++ ) { - pow1_fx = L_add( pow1_fx, Mult_32_32( L_shl( (Word32) auOut_fx[add( idiv1616( L, 20 ), i )], 6 ), L_shl( (Word32) auOut_fx[add( idiv1616( L, 20 ), i )], 6 ) ) ); + pow1_fx = L_add( pow1_fx, Mult_32_32( L_shl( (Word32) auOut_fx[( L / 20 ) + i], 6 ), L_shl( (Word32) auOut_fx[( L / 20 ) + i], 6 ) ) ); pow22_fx = L_add( pow22_fx, Mult_32_32( L_shl( (Word32) auOut_fx[N_LEAD_NB + i], 6 ), L_shl( (Word32) auOut_fx[N_LEAD_NB + i], 6 ) ) ); } @@ -1669,9 +1675,9 @@ static Word16 Repetition_smoothing_fx( } static void common_overlapping_fx( - Word16 *auOut_fx, /* i : Input */ - Word16 *ImdctOutWin_fx, /* o : Output */ - Word16 *OldauOut_fx, /* i : Window */ + Word16 *auOut_fx, /* i : Input Q0 */ + Word16 *ImdctOutWin_fx, /* o : Output Q0 */ + Word16 *OldauOut_fx, /* i : Window Q0 */ Word16 end1, /* i : Decay */ Word16 offset1, Word16 start2, @@ -1686,7 +1692,7 @@ static void common_overlapping_fx( { /*auOut_fx[i] = L_add(ImdctOutWin_fx[i+7*L/20], OldauOut_fx[i+offset1]);*/ #ifdef BASOP_NOGLOB - auOut_fx[i] = add_sat( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[add( i, offset1 )] ); + auOut_fx[i] = add_sat( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[i + offset1] ); #else auOut_fx[i] = add( ImdctOutWin_fx[i + N_ZERO_NB], OldauOut_fx[i + offset1] ); #endif @@ -1695,7 +1701,7 @@ static void common_overlapping_fx( FOR( i = start2; i < end2; i++ ) { /*auOut_fx[i+offset2] = ImdctOutWin_fx[i+offset_i2]; move32();*/ - auOut_fx[add( i, offset2 )] = ImdctOutWin_fx[add( i, offset_i2 )]; + auOut_fx[i + offset2] = ImdctOutWin_fx[i + offset_i2]; move16(); } @@ -1704,15 +1710,15 @@ static void common_overlapping_fx( static void Smoothing_vector_NB_fx( - const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 */ - const Word16 ImdctOutWin_fx[], /* i : Input vector 2 */ - const Word16 SmoothingWin_fx[], /* i : Smoothing window */ - Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 */ + const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 Qx */ + const Word16 ImdctOutWin_fx[], /* i : Input vector 2 Qx */ + const Word16 SmoothingWin_fx[], /* i : Smoothing window Q15 */ + Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 Qx*/ const Word16 ol_size /* i : Overlap size */ ) { Word16 i; - Word16 weight_fx; + Word16 weight_fx; // Q15 FOR( i = 0; i < ol_size; i++ ) { @@ -1727,10 +1733,10 @@ static void Smoothing_vector_NB_fx( static void Windowing_1st_NB_fx( - Word16 *ImdctOutWin_fx, /* o : Output */ - const Word32 *ImdctOut_fx, /* i : Input */ - const Word16 *win_fx, /* i : Window */ - const Word16 *smoothingWin_fx, /* i : Smoothing Window */ + Word16 *ImdctOutWin_fx, /* o : Output Q0 */ + const Word32 *ImdctOut_fx, /* i : Input Q6 */ + const Word16 *win_fx, /* i : Window Q15 */ + const Word16 *smoothingWin_fx, /* i : Smoothing Window Q15 */ Word16 smoothing_flag /* i : 1=Smoothing window, 0=Original window */ ) { @@ -1741,10 +1747,10 @@ static void Windowing_1st_NB_fx( move16(); IF( smoothing_flag == 0 ) { - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { /*ImdctOutWin[i] = ImdctOut[L/2 + i] * win[(2*L-1-i)-N_LEAD_O_NB];*/ - ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[add( shr( L, 1 ), i )], win_fx[sub( sub( sub( shl( L, 1 ), 1 ), i ), N_LEAD_O_NB )] ), 6 ) ); + ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[L / 2 + i], win_fx[( 2 * L - 1 - i ) - N_LEAD_O_NB] ), 6 ) ); // Q6 -> Q0 move16(); } @@ -1752,18 +1758,18 @@ static void Windowing_1st_NB_fx( { /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * win[(3*L/2-1-i)-N_LEAD_O_NB];*/ /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/ - ImdctOutWin_fx[add( shr( L, 1 ), i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[sub( sub( L, 1 ), i )] ), win_fx[sub( ( sub( sub( shr( imult1616( 3, L ), 1 ), 1 ), i ) ), N_LEAD_O_NB )] ), 6 ) ); + ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L - 1 - i] ), win_fx[( 3 * L / 2 - 1 - i ) - N_LEAD_O_NB] ), 6 ) ); // Q6 -> Q0 move16(); - ImdctOutWin_fx[add( idiv1616( imult1616( 3, L ), 2 ), i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[sub( sub( shr( L, 1 ), i ), 1 )] ), 6 ) ); + ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[( L / 2 - i - 1 )] ), 6 ) ); // Q6 -> Q0 move16(); } } ELSE { - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { - /*ImdctOutWin[i] = ImdctOut[L/2 + i] * smoothingWin[(i-N_ZERO_NB)];*/ /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ - ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[add( shr( L, 1 ), i )], smoothingWin_fx[sub( i, N_ZERO_NB )] ), 6 ) ); /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ + /*ImdctOutWin[i] = ImdctOut[L/2 + i] * smoothingWin[(i-N_ZERO_NB)];*/ /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ + ImdctOutWin_fx[i] = extract_l( L_shr( Mult_32_16( ImdctOut_fx[L / 2 + i], smoothingWin_fx[( i - N_ZERO_NB )] ), 6 ) ); /*win[(2*L-i)*decimate-1-decay-14*L_FRAME48k/20];*/ move16(); } @@ -1771,9 +1777,9 @@ static void Windowing_1st_NB_fx( { /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i] * smoothingWin[(i+N_ZERO_O_NB)];*/ /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[(L/2-i-1)];*/ - ImdctOutWin_fx[add( shr( L, 1 ), i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[sub( sub( L, 1 ), i )] ), smoothingWin_fx[add( i, N_ZERO_O_NB )] ), 6 ) ); /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ + ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L - 1 - i] ), smoothingWin_fx[( i + N_ZERO_O_NB )] ), 6 ) ); /*win[(3*L/2-1-i)*decimate+decay-L_FRAME48k*14/20];*/ // Q6 -> Q0 move16(); - ImdctOutWin_fx[add( shr( imult1616( 3, L ), 1 ), i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[sub( sub( shr( L, 1 ), i ), 1 )] ), 6 ) ); + ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[( L / 2 - i - 1 )] ), 6 ) ); // Q6 -> Q0 move16(); } } @@ -1781,9 +1787,9 @@ static void Windowing_1st_NB_fx( return; } static void Windowing_2nd_NB_fx( - Word16 *ImdctOutWin_fx, /* o : Output */ - const Word32 *ImdctOut_fx, /* i : Input */ - const Word16 *win_fx /* i : Window */ + Word16 *ImdctOutWin_fx, /* o : Output Q0 */ + const Word32 *ImdctOut_fx, /* i : Input Q6 */ + const Word16 *win_fx /* i : Window Q15 */ ) { Word16 i; @@ -1791,27 +1797,27 @@ static void Windowing_2nd_NB_fx( L = L_FRAME8k; move16(); - FOR( i = N_ZERO_O_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_O_NB; i < L / 2; i++ ) { /*ImdctOutWin[L/2 + i] = -ImdctOut[L - 1 - i];*/ /*ImdctOutWin[3*L/2 + i] = -ImdctOut[i] * win[L/2-i-1];*/ - ImdctOutWin_fx[add( shr( L, 1 ), i )] = extract_l( L_shr( L_negate( ImdctOut_fx[sub( sub( L, 1 ), i )] ), 6 ) ); + ImdctOutWin_fx[L / 2 + i] = extract_l( L_shr( L_negate( ImdctOut_fx[L - 1 - i] ), 6 ) ); move16(); - ImdctOutWin_fx[add( shr( imult1616( 3, L ), 1 ), i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[sub( sub( shr( L, 1 ), i ), 1 )] ), 6 ) ); + ImdctOutWin_fx[3 * L / 2 + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[i] ), win_fx[L / 2 - i - 1] ), 6 ) ); move16(); } FOR( i = 0; i < N_ZERO_NB; i++ ) { /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i];*/ - ImdctOutWin_fx[add( L, i )] = extract_l( L_shr( L_negate( ImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), 6 ) ); + ImdctOutWin_fx[L + i] = extract_l( L_shr( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), 6 ) ); move16(); } - FOR( i = N_ZERO_NB; i < shr( L, 1 ); i++ ) + FOR( i = N_ZERO_NB; i < L / 2; i++ ) { /*ImdctOutWin[L + i] = -ImdctOut[L/2 - 1 - i] * win[L - 1 - i];*/ - ImdctOutWin_fx[add( L, i )] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[sub( sub( shr( L, 1 ), 1 ), i )] ), win_fx[sub( sub( L, 1 ), i )] ), 6 ) ); + ImdctOutWin_fx[L + i] = extract_l( L_shr( Mult_32_16( L_negate( ImdctOut_fx[L / 2 - 1 - i] ), win_fx[L - 1 - i] ), 6 ) ); move16(); } @@ -1819,16 +1825,16 @@ static void Windowing_2nd_NB_fx( } static void Smoothing_vector_scaledown_NB_fx( - const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 */ - const Word16 ImdctOutWin_fx[], /* i : Input vector 2 */ - const Word16 SmoothingWin_fx[], /* i : Smoothing window */ - Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 */ + const Word16 OldauOutnoWin_fx[], /* i : Input vector 1 Q0 */ + const Word16 ImdctOutWin_fx[], /* i : Input vector 2 Q0 */ + const Word16 SmoothingWin_fx[], /* i : Smoothing window Q15 */ + Word16 auOut_fx[], /* o : Output vector that contains vector 1 .* vector 2 Q0 */ const Word16 ol_size /* i : Overlap size */ ) { Word16 i; - Word16 weight_fx; + Word16 weight_fx; // Q15 FOR( i = 0; i < ol_size; i++ ) { @@ -1863,8 +1869,8 @@ static void Scaledown_fx( void time_domain_FEC_HQ_fx( Decoder_State *st_fx, /* i : Decoder State */ - Word32 *wtda_audio_fx, /* i : input */ - Word16 *out_fx, /* o : output audio */ + Word32 *wtda_audio_fx, /* i : input Q6 */ + Word16 *out_fx, /* o : output audio Q0 */ Word16 mean_en_high_fx, /* i : transient flag */ const Word16 output_frame, Word16 *Q_synth ) @@ -1989,20 +1995,20 @@ void time_domain_FEC_HQ_fx( } static void Next_good_after_burst_erasures_fx( - const Word32 *ImdctOut_fx, - Word16 *auOut_fx, - Word16 *OldauOut_fx, + const Word32 *ImdctOut_fx, // Q6 + Word16 *auOut_fx, // Q0 + Word16 *OldauOut_fx, // Q0 const Word16 ol_size ) { Word16 i, L; - Word16 ImdctOutWin_fx[2 * L_FRAME48k]; + Word16 ImdctOutWin_fx[2 * L_FRAME48k]; // Q0 Word16 win_NB_fx[L_FRAME8k + 25]; L = L_FRAME8k; move16(); FOR( i = 0; i < add( L, 25 ); i++ ) { - win_NB_fx[i] = window_48kHz_fx[add( imult1616( i, 6 ), 3 )]; + win_NB_fx[i] = window_48kHz_fx[i * 6 + 3]; // Q15 move16(); } @@ -2014,7 +2020,7 @@ static void Next_good_after_burst_erasures_fx( Smoothing_vector_scaledown_NB_fx( &OldauOut_fx[N_ZERO_NB], &ImdctOutWin_fx[N_Z_L_O_NB], SmoothingWin_NB875_fx, &OldauOut_fx[N_ZERO_NB], ol_size ); /* Scale down the overlapped signal */ - Scaledown_fx( &ImdctOutWin_fx[add( ol_size, N_Z_L_O_NB )], &OldauOut_fx[add( ol_size, N_ZERO_NB )], 23170, sub( N_Z_L_NB, ol_size ) ); + Scaledown_fx( &ImdctOutWin_fx[ol_size + N_Z_L_O_NB], &OldauOut_fx[ol_size + N_ZERO_NB], 23170, sub( N_Z_L_NB, ol_size ) ); /* Common Overlapping */ common_overlapping_fx( auOut_fx, ImdctOutWin_fx, OldauOut_fx, N_Z_L_NB, N_ZERO_NB, 0, N_ZERO_NB, L, N_Z_L_NB ); diff --git a/lib_dec/FEC_adapt_codebook_fx.c b/lib_dec/FEC_adapt_codebook_fx.c index 03e01f2bac8c2783f56b59e6328eeb756a26629e..9260d428da060c74d64107f42f839646f07cbe72 100644 --- a/lib_dec/FEC_adapt_codebook_fx.c +++ b/lib_dec/FEC_adapt_codebook_fx.c @@ -16,12 +16,13 @@ *---------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED Word16 FEC_SinOnset_fx( - Word16 *exc, /* i/o : exc vector to modify */ - Word16 puls_pos, /* i : last pulse position desired */ - const Word16 T0, /* i : Pitch information of the 1 subfr */ - Word32 enr_q, /* i : energy provide by the encoder */ - Word16 *Aq, /* i : A(z) filter Q12 */ - const Word16 L_frame /* i : frame length */ + Word16 *exc, + /* i/o : exc vector to modify */ // Qin = Qold, Qout = Q_exc + Word16 puls_pos, /* i : last pulse position desired */ + const Word16 T0, /* i : Pitch information of the 1 subfr */ + Word32 enr_q, /* i : energy provide by the encoder */ + Word16 *Aq, /* i : A(z) filter Q12 */ + const Word16 L_frame /* i : frame length */ , const Word16 Qold ) { @@ -76,7 +77,7 @@ Word16 FEC_SinOnset_fx( set16_fx( h1, 0, L_subfr ); /* Find the impulse response */ set16_fx( mem, 0, M ); - h1[0] = 1024; + h1[0] = 1024; // 1.0f Q10 move16(); Syn_filt_s( 1, Aq, M, h1, h1, L_subfr, mem, 0 ); @@ -114,7 +115,7 @@ Word16 FEC_SinOnset_fx( L_tmp = Isqrt_lc( L_tmp, &exp2 ); gain = round_fx( L_tmp ); - gain = mult_r( gain, 31457 ); /* multiply by .96 like floating point */ + gain = mult_r( gain, 31457 ); /* multiply by .96 like floating point 0.96f in Q15*/ exp2 = add( sub( exp2, 15 ), Q_exc ); /* from Q15 to Q_exc */ /* Find if rescaling needed */ @@ -162,23 +163,24 @@ Word16 FEC_SinOnset_fx( move16(); } } - Copy( &exc_tmp[sub( L_frame, L_EXC_MEM )], exc, L_EXC_MEM ); + Copy( &exc_tmp[L_frame - L_EXC_MEM], exc, L_EXC_MEM ); return Q_exc; } Word16 FEC_enhACB_fx( const Word16 L_frame, /* i : frame length */ const Word16 last_L_frame, /* i : frame length of previous frame */ - Word16 *exc_io, /* i/o : adaptive codebook memory */ - const Word16 new_pit, /* i : decoded first frame pitch */ - const Word16 puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ - const Word16 bfi_pitch /* i : Q6 pitch used for concealment */ + Word16 *exc_io, + /* i/o : adaptive codebook memory */ // st->Q_exc + const Word16 new_pit, /* i : decoded first frame pitch */ + const Word16 puls_pos, /* i : decoder position of the last glottal pulses decoded in the previous frame */ + const Word16 bfi_pitch /* i : Q6 pitch used for concealment */ ) { Word16 Tc, P0, sign, pit_search; Word16 Tlist[10], Terr, diff_pit, dist_Plast; Word16 tmp2; - Word16 exc[L_FRAME16k + L_SUBFR]; + Word16 exc[L_FRAME16k + L_SUBFR]; // Q0 Word16 Do_WI = 1; move16(); @@ -187,7 +189,7 @@ Word16 FEC_enhACB_fx( set16_fx( exc + L_FRAME16k, 0, L_SUBFR ); Copy( exc_io, exc + L_FRAME16k - L_EXC_MEM, L_EXC_MEM ); - Tc = shr( bfi_pitch, 6 ); + Tc = shr( bfi_pitch, 6 ); // Q0 Copy( exc + sub( L_FRAME16k, Tc ), exc + L_FRAME16k, L_SUBFR ); /*------------------------------------------------------------ @@ -233,7 +235,7 @@ Word16 FEC_enhACB_fx( dist_Plast = sub( Tc, Tlist[0] ); - Tlist[1] = findpulse_fx( L_frame, exc + sub( L_frame, pit_search ), add( pit_search, L_SUBFR ), DEC, &sign ); + Tlist[1] = findpulse_fx( L_frame, exc + sub( L_frame, pit_search ), add( pit_search, L_SUBFR ), DEC, &sign ); // Q0 move16(); @@ -272,17 +274,18 @@ Word16 FEC_enhACB_fx( return Do_WI; } -Word16 FEC_synchro_exc_fx( /* o : do_WI flag */ - const Word16 L_frame, /* i : length of the frame */ - Word16 *exc, /* i/o: exc vector to modify */ - const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ - const Word16 true_puls_pos, /* i : Present pulse location */ - const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ +Word16 FEC_synchro_exc_fx( /* o : do_WI flag */ + const Word16 L_frame, /* i : length of the frame */ + Word16 *exc, + /* i/o: exc vector to modify */ // st->Q_exc + const Word16 desire_puls_pos, /* i : Pulse position send by the encoder */ + const Word16 true_puls_pos, /* i : Present pulse location */ + const Word16 Old_pitch /* i : Pitch use to create temporary adaptive codebook */ ) { Word16 exc_tmp[L_FRAME16k + L_SUBFR]; Word16 fact; - Word32 L_min_energy, L_tmp; + Word32 L_min_energy, L_tmp; // Q0 Word16 *pt_exc, *pt_exc1; Word16 i, j, point_to_remove, point_to_add, nb_min; Word16 min_pos[L_FRAME16k / PIT_MIN_DOUBLEEXTEND], points_by_pos[L_FRAME16k / PIT_MIN_DOUBLEEXTEND]; @@ -324,7 +327,7 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag move16(); /* Find starting point for minimum energy search */ - start_search = mult_r( Old_pitch, -24576 ); + start_search = mult_r( Old_pitch, -24576 ); // Q0 if ( EQ_16( s_and( Old_pitch, 3 ), 1 ) ) { /* Only be align with integer operation -3*Old_pitch/4 */ @@ -348,10 +351,10 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag * --------------------------------------------------------------------*/ L_min_energy = L_add( MAX_32, 0 ); L_tmp = L_mult( pt_exc[start_search], pt_exc[start_search] ); - L_tmp = L_mac( L_tmp, pt_exc[add( start_search, 1 )], pt_exc[add( start_search, 1 )] ); - L_tmp = L_mac( L_tmp, pt_exc[add( start_search, 2 )], pt_exc[add( start_search, 2 )] ); - L_tmp = L_mac( L_tmp, pt_exc[add( start_search, 3 )], pt_exc[add( start_search, 3 )] ); - L_tmp = L_mac( L_tmp, pt_exc[add( start_search, 4 )], pt_exc[add( start_search, 4 )] ); + L_tmp = L_mac( L_tmp, pt_exc[start_search + 1], pt_exc[start_search + 1] ); + L_tmp = L_mac( L_tmp, pt_exc[start_search + 2], pt_exc[start_search + 2] ); + L_tmp = L_mac( L_tmp, pt_exc[start_search + 3], pt_exc[start_search + 3] ); + L_tmp = L_mac( L_tmp, pt_exc[start_search + 4], pt_exc[start_search + 4] ); IF( LT_32( L_tmp, L_min_energy ) ) { @@ -413,8 +416,8 @@ Word16 FEC_synchro_exc_fx( /* o : do_WI flag { /* First position */ /* fact = (float)fabs(point_to_remove) / sqi[nb_min-2]; (nb_min*nb_min) */ - fact = mult_r( shl( abs_s( point_to_remove ), 7 ), inv_sqi[sub( nb_min, 2 )] ); /*Q7 */ - points_by_pos[0] = mult_r( fact, 256 ); /*Q7 */ + fact = mult_r( shl( abs_s( point_to_remove ), 7 ), inv_sqi[nb_min - 2] ); /*Q7 */ + points_by_pos[0] = mult_r( fact, 256 ); /*Q7 */ move16(); total_point = points_by_pos[0]; move16(); diff --git a/lib_dec/FEC_clas_estim_fx.c b/lib_dec/FEC_clas_estim_fx.c index 974041a9c1667b6bc12a6c61422b3c72bc0435cb..1363d2469d21b8c4eabd331942513f28cb1527c8 100644 --- a/lib_dec/FEC_clas_estim_fx.c +++ b/lib_dec/FEC_clas_estim_fx.c @@ -62,22 +62,22 @@ void FEC_clas_estim_fx( /* i/o: hysteresis of the music/speech decision */ /*A*/ Word16 *UV_cnt, /* i/o: number of consecutives frames classified as UV */ /*A*/ - Word16 *LT_UV_cnt, + Word16 *LT_UV_cnt, // Q6 /* i/o: long term consecutives frames classified as UV */ /*A*/ - Word16 *Last_ener, - /* i/o: last_energy frame */ /*A*/ + Word16 *Last_ener, // Q8 + /* i/o: last_energy frame */ /*A*/ Word16 *locattack, /* i/o: detection of attack (mainly to localized speech burst) */ /*A*/ - Word16 *lt_diff_etot, - /* i/o: long-term total energy variation */ /*A*/ + Word16 *lt_diff_etot, // Q8 + /* i/o: long-term total energy variation */ /*A*/ Word16 *amr_io_class, /* i/o: classification for AMR-WB IO mode */ /*A*/ #ifndef FIX_871_REMOVE_UNNECESSARY_CONDITION const Word32 bitrate, /* i : Decoded bitrate */ /*A*/ #endif - Word16 Q_syn, /* i : Synthesis scaling */ - Word16 *class_para, + Word16 Q_syn, /* i : Synthesis scaling */ + Word16 *class_para, // Q14 /* o : classification para. fmerit1 */ /*A*/ Word16 *mem_syn_clas_estim, /* i/o: memory of the synthesis signal for frame class estimation */ Word16 *Q_mem_syn, @@ -144,7 +144,7 @@ void FEC_clas_estim_fx( oldLenClasBuff = extract_l( L_shr( Mpy_32_16_1( L_mult0( st_fx->last_L_frame, getInvFrameLen( st_fx->L_frame ) /*Q21*/ ) /*Q21*/, L_SYN_MEM_CLAS_ESTIM /*Q0*/ ) /*Q6*/, 6 ) /*Q0*/ ); newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; move16(); - lerp( &mem_syn_clas_estim[sub( L_SYN_MEM_CLAS_ESTIM, oldLenClasBuff )], &mem_syn_clas_estim[sub( L_SYN_MEM_CLAS_ESTIM, newLenClasBuff )], newLenClasBuff, oldLenClasBuff ); + lerp( &mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); } synth = old_synth + L_SYN_MEM_CLAS_ESTIM; @@ -291,7 +291,7 @@ void FEC_clas_estim_fx( pos = sub( L_frame, T0 ); /* T0 [34 231] */ - Corre( &pt1[pos], &pt1[sub( pos, T0 )], T0, &cor_max[0] ); + Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[0] ); #ifdef BASOP_NOGLOB T0 = mult_r_sat( add_sat( pitch[2], pitch[3] ), 256 ); #else @@ -305,14 +305,14 @@ void FEC_clas_estim_fx( j = 16384; move16(); pos = sub( pos, T0 ); /* T0 [34 231] */ - Corre( &pt1[pos], &pt1[sub( pos, T0 )], T0, &cor_max[1] ); + Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[1] ); Ltmp = L_add( Ltmp, cor_max[1] ); IF( GT_16( pos, pos_limit ) ) { j = 10923; move16(); pos = sub( pos, T0 ); /* T0 [34 231] */ - Corre( &pt1[pos], &pt1[sub( pos, T0 )], T0, &cor_max[2] ); + Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[2] ); Ltmp = L_add( Ltmp, cor_max[2] ); } IF( GT_16( pos, pos_limit ) ) @@ -320,7 +320,7 @@ void FEC_clas_estim_fx( j = 8192; move16(); pos = sub( pos, T0 ); /* T0 [34 231] */ - Corre( &pt1[pos], &pt1[sub( pos, T0 )], T0, &cor_max[3] ); + Corre( &pt1[pos], &pt1[pos - T0], T0, &cor_max[3] ); Ltmp = L_add( Ltmp, cor_max[3] ); } } @@ -853,10 +853,11 @@ static Word16 FEC_dec_class_fx( } Word16 FEC_pos_dec_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *last_pulse_pos, /* o : last glotal pulse position in the lost ACB */ - Word32 *enr_q, /* o : decoded energy in Q0 */ - const Word16 nBits_es_Pred /* i : number of bits for Es_pred Q */ + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *last_pulse_pos, + /* o : last glotal pulse position in the lost ACB */ // Q0 + Word32 *enr_q, /* o : decoded energy in Q0 */ + const Word16 nBits_es_Pred /* i : number of bits for Es_pred Q */ ) { Word16 pitch_index, T0, T0_frac, T0_min, T0_max; diff --git a/lib_dec/FEC_fx.c b/lib_dec/FEC_fx.c index 54a450eeeb47489f7813fa19a6d6e366a60e1853..c2cf11b80b307b508d9f7af6e618aae2d180d72f 100644 --- a/lib_dec/FEC_fx.c +++ b/lib_dec/FEC_fx.c @@ -510,13 +510,13 @@ void FEC_exc_estim_fx( move16(); /*ptr init*/ FOR( i = 0; i < Len; i++ ) { - exc_dct_in[add( i, Diff_len )] = mult_r( exc_dct_in[add( i, Diff_len )], sm_table_fx[i] ); + exc_dct_in[i + Diff_len] = mult_r( exc_dct_in[i + Diff_len], sm_table_fx[i] ); move16(); } FOR( ; i < max_len; i++ ) { - exc_dct_in[add( i, Diff_len )] = 0; + exc_dct_in[i + Diff_len] = 0; move16(); } Diff_len = add( Diff_len, 1 ); @@ -788,7 +788,7 @@ void FEC_exc_estim_fx( } /* L_frame / L_SUBFR */ tmp = shr( L_frame, 6 ); - st_fx->bfi_pitch_fx = pitch_buf[sub( tmp, 1 )]; + st_fx->bfi_pitch_fx = pitch_buf[tmp - 1]; move16(); st_fx->bfi_pitch_frame = st_fx->L_frame; move16(); @@ -848,7 +848,7 @@ static void pulseRes_preCalc( Word16 *cond1, Word16 *cond2, Word32 *cond3, Word1 *-------------------------------------------------------------------*/ void gain_dec_bfi_fx( - Word16 *past_qua_en /* i/o: gain quantization memory (4 words) */ + Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Qx*/ ) { Word16 i; diff --git a/lib_dec/avq_dec_fx.c b/lib_dec/avq_dec_fx.c index da9e4720c0a3359834fbdbe03ad502e87df4514e..a2d6f1d8beab6c2a3197cf4aad8aa5341af3d591 100644 --- a/lib_dec/avq_dec_fx.c +++ b/lib_dec/avq_dec_fx.c @@ -27,13 +27,13 @@ static void read_cv_fx( Decoder_State *st, UWord16 *I, Word16 *kv, Word16 nq, Wo #ifdef IVAS_FLOAT_FIXED void AVQ_demuxdec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - Word16 xriq[], /* o : decoded subvectors [0..8*Nsv-1]*/ - Word16 *nb_bits, /* i/o: number of allocated bits */ - const Word16 Nsv, /* i : number of subvectors */ - Word16 nq[], /* i/o: AVQ nq index */ - Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution */ - Word16 trgtSvPos /* i : target SV for AVQ bit savings */ + Decoder_State *st, /* i/o: decoder state structure */ + Word16 xriq[], /* o : decoded subvectors [0..8*Nsv-1] Q0*/ + Word16 *nb_bits, /* i/o: number of allocated bits Q0*/ + const Word16 Nsv, /* i : number of subvectors Q0*/ + Word16 nq[], /* i/o: AVQ nq index Q0*/ + Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution Q0*/ + Word16 trgtSvPos /* i : target SV for AVQ bit savings Q0*/ ) { Word16 i, j, bits, tmp; @@ -59,7 +59,7 @@ void AVQ_demuxdec_fx( move16(); dummy_bits = 0; move16(); - svOrder[sub( Nsv, 1 )] = trgtSvPos; + svOrder[Nsv - 1] = trgtSvPos; move16(); svOrder[0] = 0; move16(); @@ -71,15 +71,15 @@ void AVQ_demuxdec_fx( move16(); IF( EQ_16( avq_bit_sFlag, 2 ) ) { - j = add( i, 1 ); + j = i + 1; } WHILE( LT_16( i, sub( Nsv, 1 ) ) ) { move16(); svOrder[i] = j; - i = add( 1, i ); - j = add( 1, j ); + i = 1 + i; + j = 1 + j; } FOR( i = 0; i < NSV_MAX; i++ ) @@ -99,14 +99,14 @@ void AVQ_demuxdec_fx( test(); IF( EQ_16( avq_bit_sFlag, 2 ) && EQ_16( ( bits % 5 ), 4 ) && GT_16( bits, 8 ) && LT_16( bits, 30 ) && GE_16( k, trgtSvPos ) && LT_16( i, sub( Nsv, 1 ) ) ) { - ordr_esti( Nsv - i, &trgtSvPos, &svOrder[i], Nsv ); + ordr_esti( sub( Nsv, i ), &trgtSvPos, &svOrder[i], Nsv ); k = svOrder[i]; move16(); avq_bit_sFlag = 1; move16(); } test(); - IF( EQ_16( k, trgtSvPos ) && GT_16( avq_bit_sFlag, 0 ) ) + IF( EQ_16( k, trgtSvPos ) && avq_bit_sFlag > 0 ) { test(); test(); @@ -177,7 +177,7 @@ void AVQ_demuxdec_fx( /* Bit Saving Solution */ IF( ( avq_bit_sFlag > 0 ) && GT_16( bits, 8 ) ) { - i = svOrder[sub( Nsv, 1 )]; + i = svOrder[Nsv - 1]; nq[i] = 0; move16(); bitsMod = bits % 5; @@ -185,7 +185,7 @@ void AVQ_demuxdec_fx( { nullVec = 0; move16(); - FOR( j = i; j < sub( Nsv, 1 ); j++ ) + FOR( j = i; j < Nsv - 1; j++ ) { if ( ( nq[svOrder[j]] == 0 ) ) { @@ -205,7 +205,7 @@ void AVQ_demuxdec_fx( test(); test(); test(); - IF( ( ( bitsMod > 0 ) || ( EQ_16( nullVec, 4 ) && EQ_16( nq_est, 5 ) ) ) && NE_16( bitsMod, 4 ) && GE_16( add( bits, nullVec ), ( add( add( shl( nq_est, 2 ), nq_est ), 4 ) ) ) && ( nq[svOrder[sub( Nsv, 2 )]] == 0 ) ) /* dummy bits */ + IF( ( ( bitsMod > 0 ) || ( EQ_16( nullVec, 4 ) && EQ_16( nq_est, 5 ) ) ) && NE_16( bitsMod, 4 ) && GE_16( add( bits, nullVec ), ( add( add( shl( nq_est, 2 ), nq_est ), 4 ) ) ) && ( nq[svOrder[Nsv - 2]] == 0 ) ) /* dummy bits */ { dummy_bits = sub( 5, bitsMod ); bits = add( bits, dummy_bits ); /* add dummy bits */ @@ -319,7 +319,7 @@ void AVQ_demuxdec_fx( /* write decoded RE8 vector to decoded subvector #i */ FOR( j = 0; j < 8; j++ ) { - xriq[add( i * 8, j )] = code[j]; + xriq[i * 8 + j] = code[j]; move16(); } } @@ -340,9 +340,9 @@ void AVQ_demuxdec_fx( #ifdef IVAS_FLOAT_FIXED void AVQ_dec_lpc( - Word16 *indx, /* input: index[] (4 bits per words) */ - Word16 *nvecq, /* output: vector quantized */ - Word16 Nsv /* input: number of subvectors (lg=Nsv*8) */ + Word16 *indx, /* input: index[] (4 bits per words) Q0*/ + Word16 *nvecq, /* output: vector quantized Q0*/ + Word16 Nsv /* input: number of subvectors (lg=Nsv*8) Q0*/ ) { Word16 i, l, n, nq, nk, pos, ival, c[8], kv[8]; @@ -391,7 +391,7 @@ void AVQ_dec_lpc( FOR( i = 7; i >= 0; i-- ) { - kv[i] = add( ( kv[i] << 1 ), s_and( ival, 0x01 ) ); + kv[i] = add( shl( kv[i], 1 ), s_and( ival, 0x01 ) ); move16(); ival = shr( ival, 1 ); } @@ -413,7 +413,7 @@ void AVQ_dec_lpc( /* write decoded RE8 vector */ FOR( i = 0; i < 8; i++ ) { - nvecq[add( shl( l, 3 ), i )] = c[i]; + nvecq[( l * 8 ) + i] = c[i]; move16(); } } @@ -430,11 +430,11 @@ void AVQ_dec_lpc( #ifdef IVAS_FLOAT_FIXED static void read_cv_fx( - Decoder_State *st, /* i/o: decoder state structure */ - UWord16 *I, /* o : rank I code book index */ - Word16 *kv, /* o : Voronoi index kv */ - Word16 nq, /* i : AVQ nq index */ - Word16 *nbits /* i/o: bits available */ + Decoder_State *st, /* i/o: decoder state structure */ + UWord16 *I, /* o : rank I code book index Q0*/ + Word16 *kv, /* o : Voronoi index kv Q0*/ + Word16 nq, /* i : AVQ nq index Q0*/ + Word16 *nbits /* i/o: bits available Q0*/ ) { diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 3620495a89021918f149668011f652e7f828e026..4f5f6579b56ce24aa02e597fa5d4b8447103b520 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -36,15 +36,15 @@ void bass_psfilter_init_fx( ) { /* post-filter memories */ - hBPF->pst_mem_deemp_err_fx = 0; + hBPF->pst_mem_deemp_err_fx = 0; /* 0 in Q_syn2-1 */ move16(); hBPF->pst_lp_ener_fx = 0; - move16(); /*0 in Q8 */ + move16(); /*0 in Q8 */ set16_fx( hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); set16_fx( hBPF->Track_on_hist, 0, L_TRACK_HIST ); set16_fx( hBPF->vibrato_hist, 0, L_TRACK_HIST ); - set16_fx( hBPF->mem_mean_pit_fx, 1280, L_TRACK_HIST ); /* 80 in Q4*/ - hBPF->psf_att_fx = 32767; + set16_fx( hBPF->mem_mean_pit_fx, 1280, L_TRACK_HIST ); /* 80 in Q4 */ + hBPF->psf_att_fx = 32767; /* 1.0 in Q15 */ move16(); return; @@ -81,17 +81,17 @@ void bass_psfilter_init_fx( #ifdef IVAS_FLOAT_FIXED void bass_psfilter_fx( - BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ - const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag */ - Word16 synth_in_fx[], /* i : input synthesis (at 16kHz) */ - const Word16 L_frame, /* i : length of the last frame */ - Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] */ - const Word16 bpf_off, /* i : do not use BPF when set to 1 */ - Word16 v_stab_fx, /* i : stability factor */ - Word16 *v_stab_smooth_fx, /* i/o: smoothed stability factor */ - const Word16 coder_type, /* i : coder_type */ + BPF_DEC_HANDLE hBPF, /* i/o: BPF data handle */ + const Word16 Opt_AMR_WB, /* i : AMR-WB IO flag Q0*/ + Word16 synth_in_fx[], /* i : input synthesis (at 16kHz) Q_syn2-1*/ + const Word16 L_frame, /* i : length of the last frame Q0*/ + Word16 pitch_buf_fx[], /* i : pitch for every subfr [0,1,2,3] Q6*/ + const Word16 bpf_off, /* i : do not use BPF when set to 1 Q0*/ + Word16 v_stab_fx, /* i : stability factor Q15*/ + Word16 *v_stab_smooth_fx, /* i/o: smoothed stability factor Q15*/ + const Word16 coder_type, /* i : coder_type Q0*/ Word16 Q_syn, - Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) */ + Word16 bpf_noise_buf[] /* o : BPF error signal (at int_fs) Qx*/ ) { Word16 i, j, i_subfr, T, exp, exp2; @@ -150,8 +150,8 @@ void bass_psfilter_fx( Q_syn2x = shl( Q_syn, 1 ); move16(); - Copy( hBPF->pst_old_syn_fx, syn_buf_fx, nbpsf_pit_max ); - Copy( synth_in_fx, syn_buf_fx + nbpsf_pit_max, L_frame ); + Copy( hBPF->pst_old_syn_fx, syn_buf_fx, nbpsf_pit_max ); /* Q_syn2 - 1*/ + Copy( synth_in_fx, syn_buf_fx + nbpsf_pit_max, L_frame ); /* Q_syn2 - 1*/ test(); IF( !( pitch_buf_fx == NULL || bpf_off ) ) @@ -215,7 +215,7 @@ void bass_psfilter_fx( alp_tmp = mult_r( alp_tmp, vibratR ); /*Q15 */ } - alp_tmp = s_max( 3277, alp_tmp ); + alp_tmp = s_max( 3277, alp_tmp ); /* 0.1 in Q15 */ IF( GT_16( alp_tmp, hBPF->psf_att_fx ) ) { @@ -242,11 +242,11 @@ void bass_psfilter_fx( } move16(); set16_fx( T_sf, 0, 5 ); - syn_fx = &syn_buf_fx[add( nbpsf_pit_max, L_frame )]; - sigPtr = syn_fx - T_update; + syn_fx = &syn_buf_fx[nbpsf_pit_max + L_frame]; /* Q_syn2 - 1 */ + sigPtr = syn_fx - T_update; /* Q_syn2 - 1 */ FOR( i = 0; i < nbpsf_pit_max; i++ ) { - syn_fx[i] = sigPtr[i]; + syn_fx[i] = sigPtr[i]; /* Q_syn2 - 1 */ move16(); } } @@ -257,10 +257,10 @@ void bass_psfilter_fx( { /* copy subframe pitch values [1,2,3,4] of the current frame */ /*T_sf[i] = (short)(pitch_buf_fx[i] + 0.5f); */ - tmp = add( pitch_buf_fx[i], 32 ); + tmp = add( pitch_buf_fx[i], 32 ); /*0.5 in Q6*/ IF( EQ_16( L_frame, L_FRAME8k ) ) { - tmp = add( shr( pitch_buf_fx[i], 1 ), 32 ); + tmp = add( shr( pitch_buf_fx[i], 1 ), 32 ); /*0.5 in Q6*/ } T_sf[i] = shr( tmp, 6 ); move16(); @@ -279,11 +279,11 @@ void bass_psfilter_fx( T = T_sf[i - 1]; move16(); - syn_fx = &syn_buf_fx[add( nbpsf_pit_max, L_frame )]; + syn_fx = &syn_buf_fx[nbpsf_pit_max + L_frame]; /* Q_syn2 - 1 */ sigPtr = syn_fx - T; FOR( i = 0; i < nbpsf_pit_max; i++ ) { - syn_fx[i] = sigPtr[i]; + syn_fx[i] = sigPtr[i]; /* Q_syn2 - 1 */ move16(); } } @@ -296,7 +296,7 @@ void bass_psfilter_fx( T = T_sf[subfr_pos]; move16(); - syn_fx = &syn_buf_fx[add( nbpsf_pit_max, i_subfr )]; + syn_fx = &syn_buf_fx[nbpsf_pit_max + i_subfr]; /* Q_syn2 - 1 */ syn2_fx = &syn2_buf_fx[i_subfr]; IF( T ) @@ -319,7 +319,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { /* syn2_fx[i] = 0.5f*(syn_fx[i-T] + syn_fx[i+T]) */ - syn2_fx[i] = mac_r( L_mult( sigPtr[i], 16384 ), sigPtr1[i], 16384 ); + syn2_fx[i] = mac_r( L_mult( sigPtr[i], 16384 ), sigPtr1[i], 16384 ); /* Q15 */ move16(); } @@ -333,11 +333,11 @@ void bass_psfilter_fx( because it is a signed sum. */ FOR( j = 0; j < subfr_len; j += 2 ) { - Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); - Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); + Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ + Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ #ifdef BASOP_NOGLOB - Lcorr0 = L_mac0_sat( Lcorr0, syn_fx[j + 1], syn2_fx[j + 1] ); - Lener0 = L_mac0_sat( Lener0, syn2_fx[j + 1], syn2_fx[j + 1] ); + Lcorr0 = L_mac0_sat( Lcorr0, syn_fx[j + 1], syn2_fx[j + 1] ); /* Q31 */ + Lener0 = L_mac0_sat( Lener0, syn2_fx[j + 1], syn2_fx[j + 1] ); /* Q31 */ Lcorr = L_add_sat( Lcorr, L_shr( Lcorr0, 4 ) ); Lener = L_add_sat( Lener, L_shr( Lener0, 4 ) ); @@ -387,7 +387,7 @@ void bass_psfilter_fx( { /* err[i] = syn_fx[i] - gain*syn2_fx[i] */ #ifdef BASOP_NOGLOB - err[i] = msu_r_sat( L_shr_sat( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); + err[i] = msu_r_sat( L_shr_sat( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); /* Q15 */ #else err[i] = msu_r( L_shr( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); #endif @@ -438,19 +438,17 @@ void bass_psfilter_fx( alpha = s_min( alpha, 16384 ); /*Q15 */ - alpha = mult_r( alpha, hBPF->psf_att_fx ); - test(); - test(); + alpha = mult_r( alpha, hBPF->psf_att_fx ); /* Q15 */ test(); test(); IF( GT_16( alpha, 9830 ) && Track_on ) { - alpha = 9830; + alpha = 9830; /* 0.3 in Q15 */ move16(); } ELSE IF( GT_16( alpha, 13107 ) && vibrato ) { - alpha = 13107; + alpha = 13107; /* 0.4 in Q15 */ move16(); } @@ -498,7 +496,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { #ifdef BASOP_NOGLOB - Lener = L_mac0_sat( Lener, err[i], err[i] ); + Lener = L_mac0_sat( Lener, err[i], err[i] ); /* Q31 */ #else Lener = L_mac0( Lener, err[i], err[i] ); #endif @@ -512,7 +510,7 @@ void bass_psfilter_fx( sigPtr = err + shr( subfr_len, 1 ); FOR( i = 0; i < shr( subfr_len, 1 ); i++ ) { - Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); + Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); /* Q31 */ #ifdef BASOP_NOGLOB Lener = L_add( Lener, L_shr( L_mac0_sat( Lener0, err[i], err[i] ), 5 ) ); #else @@ -534,11 +532,11 @@ void bass_psfilter_fx( Lener = L_Comp( tmp, exp ); Lener = Mpy_32_16_1( Lener, 31565 ); /* 31565 = Log10(2) x 0.1 x 2^15 x 32 (*32 to utilize all 15 bits) */ Lener = L_shl( Lener, 3 ); - hBPF->pst_lp_ener_fx = mac_r( Lener, hBPF->pst_lp_ener_fx, 32440 ); + hBPF->pst_lp_ener_fx = mac_r( Lener, hBPF->pst_lp_ener_fx, 32440 ); /* 0.99 in Q15 */ move16(); /* just write out the error signal */ - Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); + Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); /* Q_syn2 */ } ELSE { @@ -546,7 +544,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { /*syn2_fx[i] = 0.5f*(syn_fx[i-T_update]+syn_fx[i+T_update]); */ - syn2_fx[i] = mac_r( L_mult( syn_fx[i - T_update], 16384 ), syn_fx[i + T_update], 16384 ); + syn2_fx[i] = mac_r( L_mult( syn_fx[i - T_update], 16384 ), syn_fx[i + T_update], 16384 ); /* Q15*/ move16(); } @@ -570,11 +568,11 @@ void bass_psfilter_fx( sigPtr1 = syn2_fx + 1; FOR( j = 0; j < subfr_len; j += 2 ) { - Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); - Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); + Lcorr0 = L_mult0( syn_fx[j], syn2_fx[j] ); /* Q31 */ + Lener0 = L_mult0( syn2_fx[j], syn2_fx[j] ); /* Q31 */ #ifdef BASOP_NOGLOB - Lcorr0 = L_mac0_sat( Lcorr0, sigPtr[j], sigPtr1[j] ); - Lener0 = L_mac0_sat( Lener0, sigPtr1[j], sigPtr1[j] ); + Lcorr0 = L_mac0_sat( Lcorr0, sigPtr[j], sigPtr1[j] ); /* Q31 */ + Lener0 = L_mac0_sat( Lener0, sigPtr1[j], sigPtr1[j] ); /* Q31 */ Lcorr = L_add_sat( Lcorr, L_shr( Lcorr0, 4 ) ); Lener = L_add_sat( Lener, L_shr( Lener0, 4 ) ); @@ -621,7 +619,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { /* err[i] = syn_fx[i] - gain*syn2_fx[i] */ - err[i] = msu_r( L_shr( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); + err[i] = msu_r( L_shr( L_mult0( gain, syn2_fx[i] ), exp2 ), syn_fx[i], 16384 ); /* Q15 */ move16(); /* the sign is inverted but it is not important because we calculate energy with 'err[i]' x 'err[i]' @@ -683,7 +681,7 @@ void bass_psfilter_fx( FOR( i = 0; i < subfr_len; i++ ) { #ifdef BASOP_NOGLOB - Lener = L_mac0_sat( Lener, err[i], err[i] ); + Lener = L_mac0_sat( Lener, err[i], err[i] ); /* Q31 */ #else Lener = L_mac0( Lener, err[i], err[i] ); #endif @@ -697,7 +695,7 @@ void bass_psfilter_fx( sigPtr = err + subfr_len / 2; FOR( i = 0; i < subfr_len / 2; i++ ) { - Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); + Lener0 = L_mult0( sigPtr[i], sigPtr[i] ); /* Q31 */ #ifdef BASOP_NOGLOB Lener = L_add_sat( Lener, L_shr( L_mac0_sat( Lener0, err[i], err[i] ), 5 ) ); #else @@ -719,11 +717,11 @@ void bass_psfilter_fx( Lener = L_Comp( tmp, exp ); Lener = Mpy_32_16_1( Lener, 31565 ); /* 31565 = Log10(2) x 0.1 x 2^15 x 32 (*32 to utilize all 15 bits) */ Lener = L_shl( Lener, 3 ); - hBPF->pst_lp_ener_fx = mac_r( Lener, hBPF->pst_lp_ener_fx, 32440 ); + hBPF->pst_lp_ener_fx = mac_r( Lener, hBPF->pst_lp_ener_fx, 32440 ); /* Q8 */ move16(); /* just write out the error signal */ - Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); + Copy( syn2_fx, bpf_noise_buf + i_subfr, subfr_len ); /* Q_syn2 */ } subfr_pos = add( subfr_pos, 1 ); @@ -746,7 +744,7 @@ void bass_psfilter_fx( hBPF->vibrato_hist[i] = vibrato; move16(); - Copy( syn_buf_fx + L_frame, hBPF->pst_old_syn_fx, nbpsf_pit_max ); + Copy( syn_buf_fx + L_frame, hBPF->pst_old_syn_fx, nbpsf_pit_max ); /* Q_syn2 - 1 */ return; @@ -769,9 +767,9 @@ void bass_psfilter_fx( /*==============================================================================*/ #ifdef IVAS_FLOAT_FIXED -static Word16 Pit_track_fx( /* o : Pitch */ - Word16 syn[], /* i : synthesis [-PIT_MAX..L_SUBFR] */ - Word16 T /* i : pitch period (>= PIT_MIN) */ +static Word16 Pit_track_fx( /* o : Pitch */ + Word16 syn[], /* i : synthesis [-PIT_MAX..L_SUBFR] st_fx->Q_syn2 */ + Word16 T /* i : pitch period (>= PIT_MIN) Q0 */ ) { Word16 T2; @@ -788,8 +786,8 @@ static Word16 Pit_track_fx( /* o : Pitch T2 = shr( T, 1 ); - v1 = &syn[-NBPSF_L_EXTRA]; - v2 = &syn[add( -T2, -NBPSF_L_EXTRA )]; + v1 = &syn[-NBPSF_L_EXTRA]; /* Q_syn2 */ + v2 = &syn[-T2 - NBPSF_L_EXTRA]; /* Q_syn2 */ Lener = L_deposit_h( -32768 ); Ltmp = L_deposit_h( -32768 ); @@ -802,15 +800,15 @@ static Word16 Pit_track_fx( /* o : Pitch FOR( j = 0; j < 14; j++ ) { BASOP_SATURATE_WARNING_OFF_EVS - Lener0 = L_mult0( *v1, *v1 ); - Ltmp0 = L_mult0( *v2, *v2 ); - Lcorr0 = L_mult0( *v1++, *v2++ ); + Lener0 = L_mult0( *v1, *v1 ); /* Q31 */ + Ltmp0 = L_mult0( *v2, *v2 ); /* Q31 */ + Lcorr0 = L_mult0( *v1++, *v2++ ); /* Q31 */ FOR( i = 1; i < ( ( L_HALFR16k + NBPSF_L_EXTRA ) / 14 ); i++ ) { #ifdef BASOP_NOGLOB - Lener0 = L_mac0_sat( Lener0, *v1, *v1 ); - Ltmp0 = L_mac0_sat( Ltmp0, *v2, *v2 ); - Lcorr0 = L_mac0_sat( Lcorr0, *v1++, *v2++ ); + Lener0 = L_mac0_sat( Lener0, *v1, *v1 ); /* Q31 */ + Ltmp0 = L_mac0_sat( Ltmp0, *v2, *v2 ); /* Q31 */ + Lcorr0 = L_mac0_sat( Lcorr0, *v1++, *v2++ ); /* Q31 */ #else Lener0 = L_mac0( Lener0, *v1, *v1 ); Ltmp0 = L_mac0( Ltmp0, *v2, *v2 ); @@ -823,7 +821,7 @@ static Word16 Pit_track_fx( /* o : Pitch test(); IF( EQ_32( Lener0, 2147483647L ) || EQ_32( Ltmp0, 2147483647L ) || - EQ_32( Lcorr0, 2147483647L ) || EQ_32( Lcorr0, ( -2147483647 - 1L ) ) ) + EQ_32( Lcorr0, 2147483647L ) || EQ_32( Lcorr0, ( -2147483647 - 1L ) ) ) /*Q31*/ { v1 -= i; move16(); @@ -831,16 +829,16 @@ static Word16 Pit_track_fx( /* o : Pitch move16(); FOR( i = 0; i < ( L_HALFR16k + NBPSF_L_EXTRA ) / 14; i++ ) { - Lener = L_add( Lener, L_shr( L_mult0( *v1, *v1 ), 6 ) ); - Ltmp = L_add( Ltmp, L_shr( L_mult0( *v2, *v2 ), 6 ) ); - Lcorr = L_add( Lcorr, L_shr( L_mult0( *v1++, *v2++ ), 6 ) ); + Lener = L_add( Lener, L_shr( L_mult0( *v1, *v1 ), 6 ) ); /* Q31 */ + Ltmp = L_add( Ltmp, L_shr( L_mult0( *v2, *v2 ), 6 ) ); /* Q31 */ + Lcorr = L_add( Lcorr, L_shr( L_mult0( *v1++, *v2++ ), 6 ) ); /* Q31 */ } } ELSE { - Lener = L_add( Lener, L_shr( Lener0, 6 ) ); - Ltmp = L_add( Ltmp, L_shr( Ltmp0, 6 ) ); - Lcorr = L_add( Lcorr, L_shr( Lcorr0, 6 ) ); + Lener = L_add( Lener, L_shr( Lener0, 6 ) ); /* Q31 */ + Ltmp = L_add( Ltmp, L_shr( Ltmp0, 6 ) ); /* Q31 */ + Lcorr = L_add( Lcorr, L_shr( Lcorr0, 6 ) ); /* Q31 */ } } @@ -856,7 +854,7 @@ static Word16 Pit_track_fx( /* o : Pitch exp2 = norm_l( Ltmp ); /* Multiply the Most Significant 16 bits */ #ifdef BASOP_NOGLOB - Ltmp = L_mult0( round_fx_sat( L_shl_sat( Lener, exp1 ) ), round_fx_sat( L_shl_sat( Ltmp, exp2 ) ) ); + Ltmp = L_mult0( round_fx_sat( L_shl_sat( Lener, exp1 ) ), round_fx_sat( L_shl_sat( Ltmp, exp2 ) ) ); /* Q31 */ #else Ltmp = L_mult0( round_fx( L_shl( Lener, exp1 ) ), round_fx( L_shl( Ltmp, exp2 ) ) ); #endif @@ -901,15 +899,15 @@ static Word16 Pit_track_fx( /* o : Pitch #ifdef IVAS_FLOAT_FIXED void addBassPostFilter_fx( - const Word16 *harm_timeIn_Fx, - Word32 **rAnalysis_Fx, - Word32 **iAnalysis_Fx, + const Word16 *harm_timeIn_Fx, /* timeIn_e */ + Word32 **rAnalysis_Fx, /* Qx - 5 */ + Word32 **iAnalysis_Fx, /* Qx - 5 */ HANDLE_CLDFB_FILTER_BANK cldfbBank_bpf_Fx, - Word32 *workBuffer, + Word32 *workBuffer, /* Qx */ const Word16 timeIn_e, - const Word16 nTimeSlots, - const Word16 nTimeSlotsTotal, - const Word16 nBandsTotal, + const Word16 nTimeSlots, /* Q0 */ + const Word16 nTimeSlotsTotal, /* Q0 */ + const Word16 nBandsTotal, /* Q0 */ CLDFB_SCALE_FACTOR *cldfb_scale ) { Word16 i, scale1, scale2; @@ -929,7 +927,7 @@ void addBassPostFilter_fx( move16(); move16(); - weights_Fx = bpf_weights_16_Fx; + weights_Fx = bpf_weights_16_Fx; /* Q15 */ maxBand = s_min( nChan, BPF_STOP_STOPBAND_16 ); assert( nChan <= 20 ); @@ -963,31 +961,31 @@ void addBassPostFilter_fx( /* Rescale time slots which do not have BPF contribution. */ FOR( i = nTimeSlots; i < nTimeSlotsTotal; i++ ) { - Scale_sig32( rAnalysis_Fx[i], nBandsTotal, scale1 ); - Scale_sig32( iAnalysis_Fx[i], nBandsTotal, scale1 ); + Scale_sig32( rAnalysis_Fx[i], nBandsTotal, scale1 ); /* Qx - 5 + scale1 */ + Scale_sig32( iAnalysis_Fx[i], nBandsTotal, scale1 ); /* Qx - 5 + scale1 */ } } FOR( i = 0; i < nTimeSlots; i++ ) { /* Compensate first bpf_weights coefficient which is scaled by 0.5 */ - rAnalysis_Fx[i][0] = L_sub( L_shl( rAnalysis_Fx[i][0], scale1 ), L_shl( Mpy_32_16_1( tmp_R_Fx[i][0], weights_Fx[0] ), add( 1, scale2 ) ) ); + rAnalysis_Fx[i][0] = L_sub( L_shl( rAnalysis_Fx[i][0], scale1 ), L_shl( Mpy_32_16_1( tmp_R_Fx[i][0], weights_Fx[0] ), add( 1, scale2 ) ) ); /* Qx -5 */ move32(); - iAnalysis_Fx[i][0] = L_sub( L_shl( iAnalysis_Fx[i][0], scale1 ), L_shl( Mpy_32_16_1( tmp_I_Fx[i][0], weights_Fx[0] ), add( 1, scale2 ) ) ); + iAnalysis_Fx[i][0] = L_sub( L_shl( iAnalysis_Fx[i][0], scale1 ), L_shl( Mpy_32_16_1( tmp_I_Fx[i][0], weights_Fx[0] ), add( 1, scale2 ) ) ); /* Qx - 5 */ move32(); /* loop over remaining low frequency bands */ FOR( b = 1; b < maxBand; b++ ) { - rAnalysis_Fx[i][b] = L_sub( L_shl( rAnalysis_Fx[i][b], scale1 ), L_shr( Mpy_32_16_1( tmp_R_Fx[i][b], weights_Fx[b] ), scale2 ) ); + rAnalysis_Fx[i][b] = L_sub( L_shl( rAnalysis_Fx[i][b], scale1 ), L_shr( Mpy_32_16_1( tmp_R_Fx[i][b], weights_Fx[b] ), scale2 ) ); /* Qx - 5 */ move32(); - iAnalysis_Fx[i][b] = L_sub( L_shl( iAnalysis_Fx[i][b], scale1 ), L_shr( Mpy_32_16_1( tmp_I_Fx[i][b], weights_Fx[b] ), scale2 ) ); + iAnalysis_Fx[i][b] = L_sub( L_shl( iAnalysis_Fx[i][b], scale1 ), L_shr( Mpy_32_16_1( tmp_I_Fx[i][b], weights_Fx[b] ), scale2 ) ); /* Qx - 5 */ move32(); } /* Rescale Bands with no BPF contribution. */ - Scale_sig32( rAnalysis_Fx[i] + maxBand, sub( nBandsTotal, maxBand ), scale1 ); - Scale_sig32( iAnalysis_Fx[i] + maxBand, sub( nBandsTotal, maxBand ), scale1 ); + Scale_sig32( rAnalysis_Fx[i] + maxBand, sub( nBandsTotal, maxBand ), scale1 ); /* Qx-5 + scale1 */ + Scale_sig32( iAnalysis_Fx[i] + maxBand, sub( nBandsTotal, maxBand ), scale1 ); /* Qx-5 + scale1 */ } return; diff --git a/lib_enc/dtx_fx.c b/lib_enc/dtx_fx.c index c94ff10c2a4e80d69b0ecadf70b51f816c6b9891..d0ebfddf310f156a4e65f30a59070b3dcb0dd5dd 100644 --- a/lib_enc/dtx_fx.c +++ b/lib_enc/dtx_fx.c @@ -67,16 +67,20 @@ void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 ivas_total_brate, /* i : IVAS total bitrate */ const Word16 vad, /* i : vad flag for DTX */ - const Word16 speech[] /* i : Pointer to the speech frame */ - + const Word16 speech[], /* i : Pointer to the speech frame */ + Word16 Q_speech /* i : Q factor for speech */ ) { - Word16 alpha; + Word16 alpha, i, j, Q_speech2; Word32 L_tmp; DTX_ENC_HANDLE hDtxEnc = st_fx->hDtxEnc; TD_CNG_ENC_HANDLE hTdCngEnc = st_fx->hTdCngEnc; Word16 last_br_cng_flag, last_br_flag, br_dtx_flag; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif IF( st_fx->dtx_sce_sba != 0 ) { @@ -442,10 +446,10 @@ void dtx_ivas_fx( IF( hDtxEnc != NULL ) { hDtxEnc->frame_ener_fx = L_deposit_l( 0 ); + move32(); IF( st_fx->Opt_DTX_ON ) { -#if 0 Q_speech2 = add( shl( Q_speech, 1 ), 7 ); FOR( j = 0; j < 16; j++ ) { @@ -460,15 +464,9 @@ void dtx_ivas_fx( #endif /* BASOP_NOGLOB */ speech++; } - hDtxEnc->frame_ener_fx = L_add( hDtxEnc->frame_ener_fx, L_shr( L_tmp, Q_speech2 ) ); /*Q(-7) */ - + hDtxEnc->frame_ener_fx = L_add( hDtxEnc->frame_ener_fx, L_shr( L_tmp, Q_speech2 ) ); /* Q(-7) */ + move32(); } -#endif - // hDtxEnc->frame_ener = sum2_f( speech, L_FRAME ); - Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); - // Word16 Q_frame_ener = 2 * Q_speech; - hDtxEnc->frame_ener_fx = sum2_f_16_gb_fx( speech, L_FRAME, guard_bits ); // 2*Q_speech-guard_bits - move32(); /* Active speech (voiced) */ @@ -485,7 +483,7 @@ void dtx_ivas_fx( /*st_fx->lt_ener_voiced_fx = alpha * st_fx->lt_ener_voiced_fx + (1.0f-alpha) * st_fx->frame_ener_fx;*/ L_tmp = L_sub( hDtxEnc->lt_ener_voiced_fx, hDtxEnc->frame_ener_fx ); L_tmp = Mult_32_16( L_tmp, alpha ); - hDtxEnc->lt_ener_voiced_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); /*2*Q_speech-guard_bits */ + hDtxEnc->lt_ener_voiced_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); /* Q(-7) */ move32(); hDtxEnc->VarDTX_cnt_voiced = add( hDtxEnc->VarDTX_cnt_voiced, 1 ); @@ -508,8 +506,8 @@ void dtx_ivas_fx( /*st_fx->lt_ener_noise_fx = alpha * st_fx->lt_ener_noise_fx + (1.0f-alpha) * st_fx->frame_ener_fx;*/ L_tmp = L_sub( hDtxEnc->lt_ener_noise_fx, hDtxEnc->frame_ener_fx ); L_tmp = Mult_32_16( L_tmp, alpha ); - hDtxEnc->lt_ener_noise_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); - move32(); /*2*Q_speech-guard_bits */ + hDtxEnc->lt_ener_noise_fx = L_add( L_tmp, hDtxEnc->frame_ener_fx ); /* Q(-7) */ + move32(); hDtxEnc->VarDTX_cnt_noise = add( hDtxEnc->VarDTX_cnt_noise, 1 ); move16(); @@ -584,6 +582,7 @@ void dtx_ivas_fx( assert( !"Bitrate not supported: not part of EVS" ); } tmpbandwidthMin = FrameSizeConfig[n].bandwidth_min; + move16(); if ( EQ_16( st_fx->rf_mode, 1 ) ) { tmpbandwidthMin = WB; diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index e50b53cda3004b1dc67d240a7a9753d19840c673..d661fe7bca5d5172c3feec6cb8445709b5d4ca21 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1983,13 +1983,11 @@ ivas_error pre_proc_front_ivas_fx( // Q_lp_noise = Q_factor( st->lp_noise ); st->lp_noise_fx = float_to_fix16( st->lp_noise, Q8 ); #endif - dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx ); + dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx, Q_inp_12k8 ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); - IF( st->Opt_DTX_ON ) { - st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, 2 * Q_inp_12k8 - guard_bits ); // 2*Q_speech + st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, -7 ); } #endif #endif diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 93d5725f99388030a3dae5918d0eebd708720f11..de77118532ad2e1e098f8d019067732496eeb7e2 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -961,15 +961,14 @@ ivas_error front_vad_spar( corr_shift_fx = correlation_shift_fx( hFrontVad->hNoiseEst->totalNoise_fx ); corr_shift = fixedToFloat( corr_shift_fx, Q15 ); #if 1 - Q_inp_12k8 = Q9; // Q_factor_arr( inp_12k8, 3 * L_FRAME / 2 ); + Q_inp_12k8 = Q_factor_arr( inp_12k8, 3 * L_FRAME / 2 ); floatToFixed_arr( inp_12k8, inp_12k8_fx, Q_inp_12k8, 3 * L_FRAME / 2 ); // Q_lp_noise = Q_factor( st->lp_noise ); st->lp_noise_fx = float_to_fix16( st->lp_noise, Q8 ); - dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx ); - Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); + dtx_ivas_fx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8_fx, Q_inp_12k8 ); IF( st->Opt_DTX_ON ) { - st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, 2 * Q_inp_12k8 - guard_bits ); // 2*Q_speech + st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, -7 ); } #else dtx( st, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8 ); diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 1d268b40debe6b2fcc592a0125997696bc6d3f50..2f0326232b506e2b4fb48dc63238c94a27d407a8 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -52,7 +52,11 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void combine_freqbands_and_subframes_fx( MASA_ENCODER_HANDLE hMasa ); +#else static void combine_freqbands_and_subframes( MASA_ENCODER_HANDLE hMasa ); +#endif static void find_n_largest( const float *input, int16_t *largestIndices, const int16_t numElements, const int16_t numLargest ); @@ -60,7 +64,11 @@ static void move_metadata_to_qmetadata( const MASA_ENCODER_HANDLE hMasa, IVAS_QM static void detect_metadata_composition( const MASA_ENCODER_HANDLE hMasa, uint8_t *joinedSubframes, uint8_t *coherencePresent, uint8_t *isTwoDir ); +#ifdef IVAS_FLOAT_FIXED +static void compensate_energy_ratios_fx( MASA_ENCODER_HANDLE hMasa ); +#else static void compensate_energy_ratios( MASA_ENCODER_HANDLE hMasa ); +#endif static int16_t encode_lfe_to_total_energy_ratio( MASA_ENCODER_HANDLE hMasa, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate ); @@ -296,7 +304,35 @@ ivas_error ivas_masa_encode( } /* Validate and compensate ratios as necessary */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 sf, dir; + MASA_METADATA_HANDLE hMeta = &( hMasa->masaMetadata ); + Word16 numDirs = hMeta->descriptive_meta.numberOfDirections + 1; + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + floatToFixed_arrL32( hMeta->common_meta.remainder_to_total_ratio[sf], hMeta->common_meta.remainder_to_total_ratio_fx[sf], Q30, MASA_FREQUENCY_BANDS ); + FOR( dir = 0; dir < numDirs; dir++ ) + { + floatToFixed_arrL32( hMeta->directional_meta[dir].energy_ratio[sf], hMeta->directional_meta[dir].energy_ratio_fx[sf], Q30, MASA_FREQUENCY_BANDS ); + } + floatToFixed_arrL32( hMeta->common_meta.diffuse_to_total_ratio[sf], hMeta->common_meta.diffuse_to_total_ratio_fx[sf], Q30, MASA_FREQUENCY_BANDS ); + } +#endif + compensate_energy_ratios_fx( hMasa ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR( dir = 0; dir < numDirs; dir++ ) + { + fixedToFloat_arrL32( hMeta->directional_meta[dir].energy_ratio_fx[sf], hMeta->directional_meta[dir].energy_ratio[sf], Q30, MASA_FREQUENCY_BANDS ); + } + fixedToFloat_arrL32( hMeta->common_meta.diffuse_to_total_ratio_fx[sf], hMeta->common_meta.diffuse_to_total_ratio[sf], Q30, MASA_FREQUENCY_BANDS ); + } +#endif +#else compensate_energy_ratios( hMasa ); +#endif if ( Opt_DTX_ON ) { @@ -323,7 +359,117 @@ ivas_error ivas_masa_encode( } /* Combine frequency bands and sub-frames */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 numSf = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES; + hMasa->data.q_energy = Q31; + Word16 guard_bits = find_guarded_bits_fx( 9 ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hMasa->data.q_energy = s_min( hMasa->data.q_energy, L_get_q_buf1( hMasa->data.energy[i], MASA_FREQUENCY_BANDS ) ); + } + hMasa->data.q_energy -= guard_bits; + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + floatToFixed_arrL32( hMasa->data.energy[i], hMasa->data.energy_fx[i], hMasa->data.q_energy, MASA_FREQUENCY_BANDS ); + } + if ( hMasa->config.numCodingBands <= MAX_REDUCED_NBANDS ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arrL32( hMeta->directional_meta[i].azimuth[j], hMeta->directional_meta[i].azimuth_fx[j], Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arrL32( hMeta->directional_meta[i].elevation[j], hMeta->directional_meta[i].elevation_fx[j], Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arrL32( hMeta->directional_meta[i].energy_ratio[j], hMeta->directional_meta[i].energy_ratio_fx[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arr( hMeta->directional_meta[i].spread_coherence[j], hMeta->directional_meta[i].spread_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + if ( i == 0 ) + { + floatToFixed_arr( hMeta->common_meta.surround_coherence[j], hMeta->common_meta.surround_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + } + } + } + if ( hMasa->config.mergeRatiosOverSubframes ) + { + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arr( hMeta->common_meta.surround_coherence[j], hMeta->common_meta.surround_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arrL32( hMeta->directional_meta[i].energy_ratio[j], hMeta->directional_meta[i].energy_ratio_fx[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + } +#endif + combine_freqbands_and_subframes_fx( hMasa ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + fixedToFloat_arrL32( hMasa->data.energy_fx[i], hMasa->data.energy[i], hMasa->data.q_energy, MASA_FREQUENCY_BANDS ); + } + if ( hMasa->config.numCodingBands <= MAX_REDUCED_NBANDS ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arrL32( hMeta->directional_meta[i].azimuth_fx[j], hMeta->directional_meta[i].azimuth[j], Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL32( hMeta->directional_meta[i].elevation_fx[j], hMeta->directional_meta[i].elevation[j], Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL32( hMeta->directional_meta[i].energy_ratio_fx[j], hMeta->directional_meta[i].energy_ratio[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arr( hMeta->directional_meta[i].spread_coherence_fx[j], hMeta->directional_meta[i].spread_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + if ( i == 0 ) + { + fixedToFloat_arr( hMeta->common_meta.surround_coherence_fx[j], hMeta->common_meta.surround_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + } + } + } + if ( hMasa->config.mergeRatiosOverSubframes ) + { + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arr( hMeta->common_meta.surround_coherence_fx[j], hMeta->common_meta.surround_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arrL32( hMeta->directional_meta[i].energy_ratio_fx[j], hMeta->directional_meta[i].energy_ratio[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + } +#endif +#else combine_freqbands_and_subframes( hMasa ); +#endif } if ( hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands < hMasa->config.numCodingBands && ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) ) @@ -522,8 +668,68 @@ ivas_error ivas_masa_encode( } #endif - if ( masa_total_brate >= IVAS_384k ) + IF( GE_32( masa_total_brate, IVAS_384k ) ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int16_t d = 0; d < hQMetaData->no_directions; d++ ) + { + for ( i = hQMetaData->q_direction[d].cfg.start_band; i < hQMetaData->q_direction[d].cfg.nbands; i++ ) + { + for ( j = 0; j < hQMetaData->q_direction[d].cfg.nblocks; j++ ) + { + hQMetaData->q_direction[d].band_data[i].elevation_fx[j] = float_to_fix( hQMetaData->q_direction[d].band_data[i].elevation[j], Q22 ); + hQMetaData->q_direction[d].band_data[i].azimuth_fx[j] = float_to_fix( hQMetaData->q_direction[d].band_data[i].azimuth[j], Q22 ); + hQMetaData->q_direction[d].band_data[i].energy_ratio_fx[j] = floatToFixed( hQMetaData->q_direction[d].band_data[i].energy_ratio[j], Q30 ); + } + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + IF( GE_32( masa_total_brate, IVAS_512k ) ) + { + IF( NE_32( ( error = ivas_qmetadata_enc_encode_hr_384_512_fx( hMetaData, hQMetaData, 16, 4 ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + ELSE + { + IF( NE_32( ( error = ivas_qmetadata_enc_encode_hr_384_512_fx( hMetaData, hQMetaData, 11, 3 ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int16_t d = 0; d < hQMetaData->no_directions; d++ ) + { + for ( i = hQMetaData->q_direction[d].cfg.start_band; i < hQMetaData->q_direction[d].cfg.nbands; i++ ) + { + for ( j = 0; j < hQMetaData->q_direction[d].cfg.nblocks; j++ ) + { + hQMetaData->q_direction[d].band_data[i].elevation[j] = fix_to_float( hQMetaData->q_direction[d].band_data[i].elevation_fx[j], Q22 ); + hQMetaData->q_direction[d].band_data[i].azimuth[j] = fix_to_float( hQMetaData->q_direction[d].band_data[i].azimuth_fx[j], Q22 ); + hQMetaData->q_direction[d].band_data[i].energy_ratio[j] = fixedToFloat( hQMetaData->q_direction[d].band_data[i].energy_ratio_fx[j], Q30 ); + } + } + } + if ( masa_total_brate >= IVAS_512k ) + { + for ( int16_t d = 0; d < hQMetaData->no_directions; d++ ) + { + for ( i = hQMetaData->q_direction[d].cfg.start_band; i < hQMetaData->q_direction[d].cfg.nbands; i++ ) + { + for ( j = 0; j < hQMetaData->q_direction[d].cfg.nblocks; j++ ) + { + hQMetaData->q_direction[d].band_data[i].q_elevation[j] = fix_to_float( hQMetaData->q_direction[d].band_data[i].q_elevation_fx[j], Q22 ); + hQMetaData->q_direction[d].band_data[i].q_azimuth[j] = fix_to_float( hQMetaData->q_direction[d].band_data[i].q_azimuth_fx[j], Q22 ); + } + } + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + +#else if ( masa_total_brate >= IVAS_512k ) { if ( ( error = ivas_qmetadata_enc_encode_hr_384_512( hMetaData, hQMetaData, 16, 4 ) ) != IVAS_ERR_OK ) @@ -538,6 +744,7 @@ ivas_error ivas_masa_encode( return error; } } +#endif } else { @@ -644,7 +851,118 @@ ivas_error ivas_masa_encode( /* Force to have 5 bands and 1 direction */ hMasa->config.numCodingBands = 5; hMasa->config.numTwoDirBands = 0; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + MASA_METADATA_HANDLE hMeta = &( hMasa->masaMetadata ); + Word16 numSf = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES; + hMasa->data.q_energy = Q31; + Word16 guard_bits = find_guarded_bits_fx( 9 ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hMasa->data.q_energy = s_min( hMasa->data.q_energy, L_get_q_buf1( hMasa->data.energy[i], MASA_FREQUENCY_BANDS ) ); + } + hMasa->data.q_energy -= guard_bits; + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + floatToFixed_arrL32( hMasa->data.energy[i], hMasa->data.energy_fx[i], hMasa->data.q_energy, MASA_FREQUENCY_BANDS ); + } + if ( hMasa->config.numCodingBands <= MAX_REDUCED_NBANDS ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arrL32( hMeta->directional_meta[i].azimuth[j], hMeta->directional_meta[i].azimuth_fx[j], Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arrL32( hMeta->directional_meta[i].elevation[j], hMeta->directional_meta[i].elevation_fx[j], Q22, MASA_FREQUENCY_BANDS ); + floatToFixed_arrL32( hMeta->directional_meta[i].energy_ratio[j], hMeta->directional_meta[i].energy_ratio_fx[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arr( hMeta->directional_meta[i].spread_coherence[j], hMeta->directional_meta[i].spread_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + if ( i == 0 ) + { + floatToFixed_arr( hMeta->common_meta.surround_coherence[j], hMeta->common_meta.surround_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + } + } + } + if ( hMasa->config.mergeRatiosOverSubframes ) + { + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arr( hMeta->common_meta.surround_coherence[j], hMeta->common_meta.surround_coherence_fx[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + floatToFixed_arrL32( hMeta->directional_meta[i].energy_ratio[j], hMeta->directional_meta[i].energy_ratio_fx[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + } +#endif + combine_freqbands_and_subframes_fx( hMasa ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + fixedToFloat_arrL32( hMasa->data.energy_fx[i], hMasa->data.energy[i], hMasa->data.q_energy, MASA_FREQUENCY_BANDS ); + } + if ( hMasa->config.numCodingBands <= MAX_REDUCED_NBANDS ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arrL32( hMeta->directional_meta[i].azimuth_fx[j], hMeta->directional_meta[i].azimuth[j], Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL32( hMeta->directional_meta[i].elevation_fx[j], hMeta->directional_meta[i].elevation[j], Q22, MASA_FREQUENCY_BANDS ); + fixedToFloat_arrL32( hMeta->directional_meta[i].energy_ratio_fx[j], hMeta->directional_meta[i].energy_ratio[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arr( hMeta->directional_meta[i].spread_coherence_fx[j], hMeta->directional_meta[i].spread_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + if ( i == 0 ) + { + fixedToFloat_arr( hMeta->common_meta.surround_coherence_fx[j], hMeta->common_meta.surround_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + } + } + } + if ( hMasa->config.mergeRatiosOverSubframes ) + { + if ( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arr( hMeta->common_meta.surround_coherence_fx[j], hMeta->common_meta.surround_coherence[j], Q15, MASA_FREQUENCY_BANDS ); + } + } + for ( i = 0; i < hMasa->config.numberOfDirections; i++ ) + { + for ( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + fixedToFloat_arrL32( hMeta->directional_meta[i].energy_ratio_fx[j], hMeta->directional_meta[i].energy_ratio[j], Q30, MASA_FREQUENCY_BANDS ); + } + } + } +#endif +#else combine_freqbands_and_subframes( hMasa ); +#endif hQMetaData->q_direction[0].cfg.nbands = 5; if ( hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands < hMasa->config.numCodingBands ) @@ -1531,6 +1849,271 @@ uint8_t ivas_masa_surrcoh_signicant( * Local functions *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void combine_freqbands_and_subframes_fx( + MASA_ENCODER_HANDLE hMasa ) +{ + Word16 i, j, k, m; + Word16 aziRad, eleRad; + Word32 x[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 y[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 z[MASA_MAXIMUM_DIRECTIONS][MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 vecLen; + Word16 vecLen_e; + Word32 xSum, ySum, zSum; + Word64 xSum_sq, ySum_sq, zSum_sq; + Word32 energySum; + Word32 spreadCohSum; + Word32 surrCohSum; + Word32 energyRatioSum; + Word16 surrCohTemp; + Word32 energyRatioTemp; + Word32 energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 brange[2]; + UWord8 numCodingBands; + UWord8 numSf; + UWord8 numDirections; + MASA_METADATA_HANDLE hMeta; + UWord8 mergeRatiosOverSubframes; + UWord8 computeCoherence; + Word16 exp_diff; + Word32 L_tmp; + Word16 guard_bits; + Word64 W_tmp; + Word16 q_shift; + + numCodingBands = hMasa->config.numCodingBands; + move16(); + numDirections = hMasa->config.numberOfDirections; + move16(); + IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) ) + { + numSf = 1; + move16(); + } + ELSE + { + numSf = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + } + hMeta = &( hMasa->masaMetadata ); + + mergeRatiosOverSubframes = hMasa->config.mergeRatiosOverSubframes; + move16(); + test(); + IF( hMasa->config.useCoherence && hMasa->config.coherencePresent ) + { + computeCoherence = 1; + move16(); + } + ELSE + { + computeCoherence = 0; + move16(); + } + + /* If metadata subframes are joined then we need all energy to be in the first subframe for combining. + * This optimizes following computations a bit. + * Note: If energy is used elsewhere, then this can cause problems and local energy should be used. */ + IF( EQ_16( numSf, 1 ) ) + { + FOR( j = 1; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + FOR( k = 0; k < MASA_FREQUENCY_BANDS; k++ ) + { + hMasa->data.energy_fx[0][k] = L_add( hMasa->data.energy_fx[0][k], hMasa->data.energy_fx[j][k] ); // hMasa->data.q_energy + move32(); + } + } + } + + IF( LE_16( numCodingBands, MAX_REDUCED_NBANDS ) ) + { + /* reduce metadata *frequency* resolution. time resolution is not touched */ + FOR( i = 0; i < numDirections; i++ ) + { + FOR( j = 0; j < numSf; j++ ) /* NB: for numSf==1, operates only on first sub-frame */ + { + FOR( k = 0; k < MASA_FREQUENCY_BANDS; k++ ) + { + aziRad = extract_l( L_shl( Mpy_32_32( hMeta->directional_meta[i].azimuth_fx[j][k], PI_OVER_180_FX ), Q13 - Q22 ) ); // ((Q22, Q31) -> Q22) >> Q9 -> Q13 + eleRad = extract_l( L_shl( Mpy_32_32( hMeta->directional_meta[i].elevation_fx[j][k], PI_OVER_180_FX ), Q13 - Q22 ) ); // ((Q22, Q31) -> Q22) >> Q9 -> Q13 + vecLen = Mpy_32_32( hMeta->directional_meta[i].energy_ratio_fx[j][k], hMasa->data.energy_fx[j][k] ); // (Q30, hMasa->data.q_energy) -> hMasa->data.q_energy - Q1 + + x[i][j][k] = Mpy_32_32( L_mult( getCosWord16( aziRad ), getCosWord16( eleRad ) ), vecLen ); // (Q29, hMasa->data.q_energy - Q1) -> hMasa->data.q_energy - Q3 + move32(); + y[i][j][k] = Mpy_32_32( L_mult0( getSinWord16( aziRad ), getCosWord16( eleRad ) ), vecLen ); // (Q29, hMasa->data.q_energy - Q1) -> hMasa->data.q_energy - Q3 + move32(); + z[i][j][k] = Mpy_32_32( L_mult0( getSinWord16( eleRad ), ONE_IN_Q14 ), vecLen ); // (Q29, hMasa->data.q_energy - Q1) -> hMasa->data.q_energy - Q3 + move32(); + } + } + } + + FOR( i = 0; i < numDirections; i++ ) + { + FOR( j = 0; j < numSf; j++ ) + { + FOR( k = 0; k < numCodingBands; k++ ) + { + brange[0] = hMasa->data.band_mapping[k]; + move16(); + brange[1] = hMasa->data.band_mapping[k + 1]; + move16(); + + xSum = 0; + ySum = 0; + zSum = 0; + energySum = 0; + spreadCohSum = 0; + move32(); + move32(); + move32(); + move32(); + move32(); + + FOR( m = brange[0]; m < brange[1]; m++ ) + { + xSum = L_add( xSum, x[i][j][m] ); // hMasa->data.q_energy - Q3 + ySum = L_add( ySum, y[i][j][m] ); // hMasa->data.q_energy - Q3 + zSum = L_add( zSum, z[i][j][m] ); // hMasa->data.q_energy - Q3 + energySum = L_add( energySum, hMasa->data.energy_fx[j][m] ); // hMasa->data.q_energy + } + + aziRad = BASOP_util_atan2( ySum, xSum, 0 ); // Q13 + xSum_sq = W_mult0_32_32( xSum, xSum ); // 2 * hMasa->data.q_energy - Q6 + ySum_sq = W_mult0_32_32( ySum, ySum ); // 2 * hMasa->data.q_energy - Q6 + zSum_sq = W_mult0_32_32( zSum, zSum ); // 2 * hMasa->data.q_energy - Q6 + W_tmp = W_add( xSum_sq, ySum_sq ); // 2 * hMasa->data.q_energy - Q6 + q_shift = W_norm( W_tmp ); + L_tmp = W_extract_h( W_shl( W_tmp, q_shift ) ); // 2 * hMasa->data.q_energy - Q6 + (q_shift -32) + exp_diff = sub( Q31, add( sub( imult1616( 2, hMasa->data.q_energy ), Q6 ), sub( q_shift, 32 ) ) ); + L_tmp = Sqrt32( L_tmp, &exp_diff ); + eleRad = BASOP_util_atan2( zSum, L_tmp, sub( sub( 34, hMasa->data.q_energy ), exp_diff ) ); // Q13 + + hMeta->directional_meta[i].azimuth_fx[j][k] = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, aziRad ), Q1 ); // ((Q25, Q13) -> Q23) >> Q1 -> Q22 + move32(); + hMeta->directional_meta[i].elevation_fx[j][k] = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, eleRad ), Q1 ); // ((Q25, Q13) -> Q23) >> Q1 -> Q22 + move32(); + + W_tmp = W_add( xSum_sq, ySum_sq ); // 2 * hMasa->data.q_energy - Q6 + W_tmp = W_add( W_tmp, zSum_sq ); // 2 * hMasa->data.q_energy - Q6 + q_shift = W_norm( W_tmp ); + vecLen = W_extract_h( W_shl( W_tmp, q_shift ) ); // 2 * hMasa->data.q_energy - Q6 + (q_shift -32) + exp_diff = sub( Q31, add( sub( imult1616( 2, hMasa->data.q_energy ), Q6 ), sub( q_shift, 32 ) ) ); + vecLen = Sqrt32( vecLen, &exp_diff ); + vecLen_e = exp_diff; + move16(); + + hMeta->directional_meta[i].energy_ratio_fx[j][k] = + BASOP_Util_Divide3232_Scale_cadence( vecLen, L_add( energySum, EPSILON_FX ), &exp_diff ); + move32(); + exp_diff = add( exp_diff, sub( vecLen_e, sub( Q31, hMasa->data.q_energy ) ) ); + hMeta->directional_meta[i].energy_ratio_fx[j][k] = + L_shl( hMeta->directional_meta[i].energy_ratio_fx[j][k], sub( exp_diff, Q1 ) ); // (Q31 - exp_diff ) -> Q30 + move32(); + + IF( computeCoherence ) + { + FOR( m = brange[0]; m < brange[1]; m++ ) + { + spreadCohSum = L_add( spreadCohSum, Mpy_32_16_1( hMasa->data.energy_fx[j][m], hMeta->directional_meta[i].spread_coherence_fx[j][m] ) ); // hMasa->data.q_energy + } + hMeta->directional_meta[i].spread_coherence_fx[j][k] = BASOP_Util_Divide3232_Scale( spreadCohSum, L_add( energySum, EPSILON_FX ), &exp_diff ); + move16(); + hMeta->directional_meta[i].spread_coherence_fx[j][k] = shl( hMeta->directional_meta[i].spread_coherence_fx[j][k], exp_diff ); // Q15 + move16(); + + IF( i == 0 ) + { + surrCohSum = 0; + move32(); + FOR( m = brange[0]; m < brange[1]; m++ ) + { + surrCohSum = L_add( surrCohSum, Mpy_32_16_1( hMasa->data.energy_fx[j][m], hMeta->common_meta.surround_coherence_fx[j][m] ) ); // hMasa->data.q_energy + } + hMeta->common_meta.surround_coherence_fx[j][k] = BASOP_Util_Divide3232_Scale( surrCohSum, L_add( energySum, EPSILON_FX ), &exp_diff ); + move16(); + hMeta->common_meta.surround_coherence_fx[j][k] = shl( hMeta->common_meta.surround_coherence_fx[j][k], exp_diff ); // Q15 + move16(); + } + } + + if ( i == 0 ) + { + energy[j][k] = energySum; // hMasa->data.q_energy + move32(); + } + } + } + } + } + ELSE IF( mergeRatiosOverSubframes ) /* keep frequency resolution */ + { + FOR( j = 0; j < numSf; j++ ) + { + FOR( k = 0; k < numCodingBands; k++ ) + { + energy[j][k] = hMasa->data.energy_fx[j][k]; // hMasa->data.q_energy + move32(); + } + } + } + + IF( mergeRatiosOverSubframes ) + { + FOR( k = 0; k < numCodingBands; k++ ) + { + guard_bits = 0; + move16(); + energySum = 0; + move32(); + FOR( j = 0; j < numSf; j++ ) + { + energySum = L_add( energySum, L_shr( energy[j][k], guard_bits ) ); // hMasa->data.q_energy - guard_bits + } + + IF( computeCoherence ) + { + surrCohSum = 0; + move32(); + FOR( j = 0; j < numSf; j++ ) + { + surrCohSum = L_add( surrCohSum, Mpy_32_16_1( L_shr( energy[j][k], guard_bits ), hMeta->common_meta.surround_coherence_fx[j][k] ) ); // hMasa->data.q_energy - guard_bits + } + surrCohTemp = BASOP_Util_Divide3232_Scale( surrCohSum, L_add( energySum, EPSILON_FX ), &exp_diff ); + surrCohTemp = shl( surrCohTemp, exp_diff ); // Q15 + + FOR( j = 0; j < numSf; j++ ) + { + hMeta->common_meta.surround_coherence_fx[j][k] = surrCohTemp; // Q15 + move16(); + } + } + + FOR( i = 0; i < numDirections; i++ ) + { + energyRatioSum = 0; + move32(); + FOR( j = 0; j < numSf; j++ ) + { + energyRatioSum = L_add( energyRatioSum, Mpy_32_32( L_shr( energy[j][k], guard_bits ), hMeta->directional_meta[i].energy_ratio_fx[j][k] ) ); // hMasa->data.q_energy - guard_bits - Q1 + } + energyRatioTemp = BASOP_Util_Divide3232_Scale_cadence( energyRatioSum, L_add( energySum, EPSILON_FX ), &exp_diff ); + energyRatioTemp = L_shl( energyRatioTemp, exp_diff ); // (exp_diff + ((hMasa->data.q_energy - guard_bits) - (hMasa->data.q_energy - guard_bits - Q1))) -> Q30 + + FOR( j = 0; j < numSf; j++ ) + { + hMeta->directional_meta[i].energy_ratio_fx[j][k] = energyRatioTemp; // Q30 + move32(); + } + } + } + } + + return; +} +#else static void combine_freqbands_and_subframes( MASA_ENCODER_HANDLE hMasa ) { @@ -1712,6 +2295,7 @@ static void combine_freqbands_and_subframes( return; } +#endif /*-------------------------------------------------------------------* @@ -2092,6 +2676,69 @@ static void detect_metadata_composition( /* Check and compensate energy ratios. This function verifies that energy ratios follow the principle of summing to one. * In addition, it implements simple remainder-to-total handling where remainder energy is proportionally added to other * ratios. */ +#ifdef IVAS_FLOAT_FIXED +static void compensate_energy_ratios_fx( + MASA_ENCODER_HANDLE hMasa ) +{ + Word16 sf, band, dir; + Word32 ratioSum; + MASA_METADATA_HANDLE hMeta; + UWord8 numDirs; + + hMeta = &( hMasa->masaMetadata ); + numDirs = (UWord8) add( hMeta->descriptive_meta.numberOfDirections, 1 ); + + FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + /* Remainder is always set to zero and energy removal is compensated in following steps + * to other ratios. */ + hMeta->common_meta.remainder_to_total_ratio_fx[sf][band] = 0; // Q30 + move32(); + + ratioSum = 0; + move32(); + FOR( dir = 0; dir < numDirs; dir++ ) + { + ratioSum = L_add( ratioSum, hMeta->directional_meta[dir].energy_ratio_fx[sf][band] ); // Q30 + } + ratioSum = L_add( ratioSum, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); // Q30 + + IF( ratioSum == 0 ) + { + FOR( dir = 0; dir < numDirs; dir++ ) + { + hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = 0; // Q30 + move32(); + } + hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = ONE_IN_Q30; // Q30 + move32(); + } + // ELSE IF( NE_32( ratioSum, ONE_IN_Q30 ) ) + ELSE /* Removing the check against 1 works well!!! */ + { + Word16 exp_diff; + FOR( dir = 0; dir < numDirs; dir++ ) + { + hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = + BASOP_Util_Divide3232_Scale_cadence( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], ratioSum, &exp_diff ); + move32(); + hMeta->directional_meta[dir].energy_ratio_fx[sf][band] = L_shl( hMeta->directional_meta[dir].energy_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 + move32(); + } + hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = + BASOP_Util_Divide3232_Scale_cadence( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], ratioSum, &exp_diff ); + move32(); + hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_shl( hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band], sub( exp_diff, Q1 ) ); // Q30 + move32(); + } + } + } + + return; +} +#else static void compensate_energy_ratios( MASA_ENCODER_HANDLE hMasa ) { @@ -2139,6 +2786,7 @@ static void compensate_energy_ratios( return; } +#endif /* If the bit budget is very low, reduce metadata further to either 1 subframe and 5 bands, or 1 band and 4 subframes, based on which works better */ @@ -3187,6 +3835,197 @@ static void masa_metadata_direction_alignment( * * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_merge_masa_metadata_fx( + MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */ + OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */ +) +{ + Word16 sf, band; + UWord8 numCodingBands; + UWord8 numDirections; + UWord8 numSf; + MASA_METADATA_HANDLE hMeta; + Word16 energyTimesRatioMASA_e[2]; + Word16 total_diff_nrg_e; + Word16 energyMerged_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 energyTimesRatioISM_fx; /*energyTimesRatioISM_e*/ + Word16 energyTimesRatioISM_e; + Word32 energyTimesRatioMASA_fx[2]; /*energyTimesRatioMASA_e*/ + Word32 total_diff_nrg_fx; + Word32 eneBand_fx; /*eneBand_e*/ + Word16 eneBand_e; + Word32 energyMerged_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /*energyMerged_e*/ + Word32 temp1 /*temp1_e*/, temp2 /*temp2_e*/; + Word16 temp1_e, temp2_e; + + numCodingBands = hMasa->config.numCodingBands; + numDirections = hMasa->config.numberOfDirections; + IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) ) + { + numSf = 1; + } + ELSE + { + numSf = 4; + } + move16(); + move16(); + move16(); + hMeta = &( hMasa->masaMetadata ); + + FOR( sf = 0; sf < numSf; sf++ ) + { + FOR( band = 0; band < numCodingBands; band++ ) + { + Word16 merge_dest; + Word32 dir_sum_fx; /*dir_sum_e*/ + Word16 dir_sum_e; + UWord8 band_n_dirs; + test(); + test(); + IF( EQ_16( numDirections, 1 ) || ( EQ_16( numDirections, 2 ) && hMasa->data.twoDirBands[band] == 0 ) ) + { + band_n_dirs = 1; + } + ELSE + { + band_n_dirs = 2; + } + move16(); + + /* Compute energies */ + eneBand_fx = hMasa->data.energy_fx[sf][band]; + eneBand_e = hMasa->data.energy_e[sf][band]; + move32(); + move16(); + energyMerged_fx[sf][band] = BASOP_Util_Add_Mant32Exp( eneBand_fx, eneBand_e, hMasa->data.hOmasaData->energy_ism_fx[sf][band], hMasa->data.hOmasaData->energy_ism_fx_e[sf][band], &energyMerged_e[sf][band] ); + move32(); + + /* Compute weights */ + energyTimesRatioMASA_fx[0] = Mpy_32_32( eneBand_fx, hMeta->directional_meta[0].energy_ratio_fx[sf][band] ); + energyTimesRatioMASA_e[0] = add( eneBand_e, 1 ); + move32(); + move16(); + IF( EQ_16( band_n_dirs, 2 ) ) + { + energyTimesRatioMASA_fx[1] = Mpy_32_32( eneBand_fx, hMeta->directional_meta[1].energy_ratio_fx[sf][band] ); + energyTimesRatioMASA_e[1] = add( eneBand_e, 1 ); + } + ELSE + { + energyTimesRatioMASA_fx[1] = 0; + energyTimesRatioMASA_e[1] = 0; + } + move32(); + move16(); + + /* target is original MASA diffuseness */ + total_diff_nrg_fx = Mpy_32_32( eneBand_fx, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); + total_diff_nrg_e = add( eneBand_e, 1 ); + + /* criterion is mean of ISM ratio and new ratio */ + temp1 = BASOP_Util_Add_Mant32Exp( L_add( EPSILON_FX, eneBand_fx ), eneBand_e, hMasa->data.hOmasaData->energy_ism_fx[sf][band], hMasa->data.hOmasaData->energy_ism_fx_e[sf][band], &temp1_e ); /* EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band]*/ + temp2 = L_deposit_h( BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, temp1, &temp2_e ) ); /*temp2_e*/ /*total_diff_nrg / ( EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band] )*/ + temp2_e = add( temp2_e, sub( total_diff_nrg_e, temp1_e ) ); + IF( temp2_e < 0 ) + { + temp2 = L_shl( temp2, temp2_e ); + temp2_e = 0; + move16(); + } + temp2 = L_sub( L_shl_sat( 1, sub( 31, temp2_e ) ), temp2 ); /*( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band] ) )*/ + temp2 = BASOP_Util_Add_Mant32Exp( hOMasaMeta->directional_meta[0].energy_ratio_fx[sf][band], 1, temp2, temp2_e, &temp2_e ); /*( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band] ) )*/ + energyTimesRatioISM_fx = Mpy_32_32( L_shr( temp2, 1 ), hMasa->data.hOmasaData->energy_ism_fx[sf][band] ); /*energyTimesRatioISM_e*/ + energyTimesRatioISM_e = add( temp2_e, hMasa->data.hOmasaData->energy_ism_fx_e[sf][band] ); + /*energyTimesRatioISM = ( hOMasaMeta->directional_meta[0].energy_ratio[sf][band] + ( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band] ) ) ) / 2.0f * hMasa->data.hOmasaData->energy_ism[sf][band];*/ + + /* Determine combined metadata based on the weights */ + merge_dest = -1; + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( band_n_dirs, 1 ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioMASA_fx[0], energyTimesRatioMASA_e[0], energyTimesRatioISM_fx, energyTimesRatioISM_e ), -1 ) ) || + ( EQ_16( band_n_dirs, 2 ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioMASA_fx[0], energyTimesRatioMASA_e[0], energyTimesRatioMASA_fx[1], energyTimesRatioMASA_e[1] ), -1 ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioMASA_fx[0], energyTimesRatioMASA_e[0], energyTimesRatioISM_fx, energyTimesRatioISM_e ), -1 ) ) ) + { + /* 1dir and ISM the most energetic, or 2dir and ISM the more energetic than MASA1 */ + merge_dest = 0; + } + ELSE IF( EQ_16( band_n_dirs, 2 ) && NE_16( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioMASA_fx[1], energyTimesRatioMASA_e[1], energyTimesRatioMASA_fx[0], energyTimesRatioMASA_e[0] ), 1 ) && EQ_16( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioMASA_fx[1], energyTimesRatioMASA_e[1], energyTimesRatioISM_fx, energyTimesRatioISM_e ), -1 ) ) + { + /* 2dir and ISM the most energetic and MASA2 the least energetic */ + merge_dest = 1; + } + move16(); + + IF( merge_dest >= 0 ) /* replace one MASA with ISM */ + { + hMeta->directional_meta[merge_dest].azimuth_fx[sf][band] = hOMasaMeta->directional_meta[0].azimuth_fx[sf][band]; /*q22*/ + hMeta->directional_meta[merge_dest].elevation_fx[sf][band] = hOMasaMeta->directional_meta[0].elevation_fx[sf][band]; /*q22*/ + move32(); + move32(); + /* limit with the earlier direct-energy ratio */ + dir_sum_fx = temp2; /* new dir ratio */ + dir_sum_e = temp2_e; + move32(); + move16(); + /*dir_sum = 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.hOmasaData->energy_ism[sf][band] )*/ + hMeta->directional_meta[merge_dest].energy_ratio_fx[sf][band] = L_min( L_shl( dir_sum_fx, sub( dir_sum_e, 1 ) ), hOMasaMeta->directional_meta[0].energy_ratio_fx[sf][band] ); /* clip with original ISM dir */ /*q30*/ + hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] = L_sub( ONE_IN_Q30, hMeta->directional_meta[merge_dest].energy_ratio_fx[sf][band] ); /*q30*/ + move32(); + move32(); + + IF( hMasa->config.useCoherence ) + { + hMeta->directional_meta[merge_dest].spread_coherence_fx[sf][band] = hOMasaMeta->directional_meta[0].spread_coherence_fx[sf][band]; /*q15*/ + hMeta->common_meta.surround_coherence_fx[sf][band] = hOMasaMeta->common_meta.surround_coherence_fx[sf][band]; /*q15*/ + move16(); + move16(); + } + + /* recompute direct energy ratios to match the diffuse ratio */ + Word32 direct_quota_fx, direct_scaler_fx; + Word16 direct_scaler_e; + direct_quota_fx = L_sub( ONE_IN_Q30, hMeta->common_meta.diffuse_to_total_ratio_fx[sf][band] ); + IF( EQ_16( band_n_dirs, 1 ) ) + { + hMeta->directional_meta[0].energy_ratio_fx[sf][band] = direct_quota_fx; /*q30*/ + move32(); + } + ELSE + { + dir_sum_fx = L_add( hMeta->directional_meta[0].energy_ratio_fx[sf][band], hMeta->directional_meta[1].energy_ratio_fx[sf][band] ); /*q30*/ + direct_scaler_fx = BASOP_Util_Divide3232_Scale( direct_quota_fx, L_add( EPSILON_FX, dir_sum_fx ), &direct_scaler_e ); + direct_scaler_fx = L_shl( direct_scaler_fx, direct_scaler_e ); /*q31*/ + direct_scaler_e = 0; + move16(); + hMeta->directional_meta[0].energy_ratio_fx[sf][band] = Mpy_32_32( direct_scaler_fx, hMeta->directional_meta[0].energy_ratio_fx[sf][band] ); /*q30*/ + hMeta->directional_meta[1].energy_ratio_fx[sf][band] = Mpy_32_32( direct_scaler_fx, hMeta->directional_meta[0].energy_ratio_fx[sf][band] ); /*q30*/ + move32(); + move32(); + } + } + } + } + + FOR( sf = 0; sf < numSf; sf++ ) + { + FOR( band = 0; band < numCodingBands; band++ ) + { + hMasa->data.energy_fx[sf][band] = energyMerged_fx[sf][band]; + hMasa->data.energy_e[sf][band] = energyMerged_e[sf][band]; + move32(); + move16(); + } + } + + return; +} +#endif // IVAS_FLOAT_FIXED void ivas_merge_masa_metadata( MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */ diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 67542e0307c71e3c6bbc3565de8778c03b06a8f8..9083a5a08a6689a224a5902d10d44b5d922e815e 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -70,7 +70,20 @@ static void ivas_omasa_param_est_enc_fx( static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, ISM_METADATA_HANDLE hIsmMeta[], float *data_f[], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MASA_FREQUENCY_BANDS], float diffuseness_m[MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp ); #endif // IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED +static void ivas_omasa_energy_and_ratio_est_fx( + OMASA_ENC_HANDLE hOMasa, + OMASA_ENCODER_DATA_HANDLE hOmasaData, + Word32 *data_fx[], +#if 0 + float *data_f[], +#endif + const Word16 input_frame, + const Word16 nchan_ism, + const Word16 q_data ); +#else static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, float *data_f[], const int16_t input_frame, const int16_t nchan_inp ); +#endif // IVAS_FLOAT_FIXED #ifndef IVAS_FLOAT_FIXED static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] ); @@ -704,6 +717,33 @@ void ivas_omasa_enc( } } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < nchan_ism; i++ ) + { + hIsmMeta[i]->azimuth_fx = float_to_fix( hIsmMeta[i]->azimuth, Q22 ); + hIsmMeta[i]->elevation_fx = float_to_fix( hIsmMeta[i]->elevation, Q22 ); + } + Word16 norm_data_in = MAX16B; + + for ( j = 0; j < nchan_ism; j++ ) + { + for ( int k = 0; k < input_frame; k++ ) + { + data_in[j][k] = float_to_fix( data_in_f[j][k], q_data ); + } + norm_data_in = s_min( norm_data_in, L_norm_arr( data_in[j], input_frame ) ); + } + norm_data_in -= 6; /*guard bit is 3->to handle overflow in cldfbAnalysis*/ + for ( j = 0; j < nchan_ism; j++ ) + { + Scale_sig32( data_in[j], input_frame, norm_data_in ); + } + q_data = q_data + norm_data_in; + for ( i = 0; i < nchan_ism; i++ ) + { + floatToFixed_arr32( hOMasa->cldfbAnaEnc[i]->cldfb_state, hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, q_data, hOMasa->cldfbAnaEnc[i]->cldfb_state_length ); + } +#endif /* Analysis */ if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) { @@ -734,33 +774,6 @@ void ivas_omasa_enc( /* Estimate MASA parameters from the objects */ /* NB: only first direction is populated */ /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( i = 0; i < nchan_ism; i++ ) - { - hIsmMeta[i]->azimuth_fx = float_to_fix( hIsmMeta[i]->azimuth, Q22 ); - hIsmMeta[i]->elevation_fx = float_to_fix( hIsmMeta[i]->elevation, Q22 ); - } - Word16 norm_data_in = MAX16B; - - for ( j = 0; j < nchan_ism; j++ ) - { - for ( int k = 0; k < input_frame; k++ ) - { - data_in[j][k] = float_to_fix( data_in_f[j][k], q_data ); - } - norm_data_in = s_min( norm_data_in, L_norm_arr( data_in[j], input_frame ) ); - } - norm_data_in -= 6; /*guard bit is 3->to handle overflow in cldfbAnalysis*/ - for ( j = 0; j < nchan_ism; j++ ) - { - Scale_sig32( data_in[j], input_frame, norm_data_in ); - } - q_data = q_data + norm_data_in; - for ( i = 0; i < nchan_ism; i++ ) - { - floatToFixed_arr32( hOMasa->cldfbAnaEnc[i]->cldfb_state, hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, q_data, hOMasa->cldfbAnaEnc[i]->cldfb_state_length ); - } -#endif ivas_omasa_param_est_enc_fx( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in, hOMasaMeta->directional_meta[0].elevation_fx, hOMasaMeta->directional_meta[0].azimuth_fx, hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].spread_coherence_fx, hOMasaMeta->common_meta.surround_coherence_fx[0], hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], input_frame, nchan_ism, q_data ); #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED @@ -795,9 +808,9 @@ void ivas_omasa_enc( } for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) { - fixedToFloat_arrL( hMasa->data.hOmasaData->energy_ism_fx[block_m_idx], hMasa->data.hOmasaData->energy_ism[block_m_idx], sub( 31, hMasa->data.hOmasaData->energy_ism_e[block_m_idx] ), hOMasa->nbands ); for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { + hMasa->data.hOmasaData->energy_ism[block_m_idx][band_m_idx] = me2f( hMasa->data.hOmasaData->energy_ism_fx[block_m_idx][band_m_idx], hMasa->data.hOmasaData->energy_ism_fx_e[block_m_idx][band_m_idx] ); hOMasaMeta->directional_meta[0].spread_coherence[block_m_idx][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].spread_coherence_fx[block_m_idx][band_m_idx], Q15 ); hOMasaMeta->common_meta.surround_coherence[0][band_m_idx] = fixedToFloat( hOMasaMeta->common_meta.surround_coherence_fx[0][band_m_idx], Q15 ); hOMasaMeta->directional_meta[0].azimuth[block_m_idx][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].azimuth_fx[block_m_idx][band_m_idx], Q22 ); @@ -817,6 +830,11 @@ void ivas_omasa_enc( /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */ for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { +#ifdef IVAS_FLOAT_FIXED + Copy32( hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].energy_ratio_fx[i], MASA_FREQUENCY_BANDS ); + Copy( hOMasaMeta->common_meta.surround_coherence_fx[0], hOMasaMeta->common_meta.surround_coherence_fx[i], MASA_FREQUENCY_BANDS ); + Copy32( hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[i], MASA_FREQUENCY_BANDS ); +#endif // IVAS_FLOAT_FIXED mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS ); mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS ); mvr2r( hOMasaMeta->common_meta.diffuse_to_total_ratio[0], hOMasaMeta->common_meta.diffuse_to_total_ratio[i], MASA_FREQUENCY_BANDS ); @@ -832,7 +850,46 @@ void ivas_omasa_enc( hMasa->config.numCodingBands = hOMasa->nbands; hMasa->config.joinedSubframes = 0; +#if 1 + int16_t numSf = hMasa->config.joinedSubframes == TRUE ? 1 : 4; + for ( i = 0; i < numSf; i++ ) + { + for ( j = 0; j < hMasa->config.numCodingBands; j++ ) + { + f2me( hMasa->data.energy[i][j], &hMasa->data.energy_fx[i][j], &hMasa->data.energy_e[i][j] ); + hMasa->masaMetadata.directional_meta[0].energy_ratio_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].energy_ratio[i][j], 30 ); + hMasa->masaMetadata.directional_meta[1].energy_ratio_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].energy_ratio[i][j], 30 ); + hMasa->masaMetadata.directional_meta[1].azimuth_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].azimuth[i][j], 22 ); + hMasa->masaMetadata.directional_meta[1].elevation_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[1].elevation[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].azimuth_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].azimuth[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].elevation_fx[i][j] = float_to_fix( hMasa->masaMetadata.directional_meta[0].elevation[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].spread_coherence_fx[i][j] = float_to_fix16( hMasa->masaMetadata.directional_meta[0].spread_coherence[i][j], 15 ); + hMasa->masaMetadata.directional_meta[1].spread_coherence_fx[i][j] = float_to_fix16( hMasa->masaMetadata.directional_meta[1].spread_coherence[i][j], 15 ); + hMasa->masaMetadata.common_meta.surround_coherence_fx[i][j] = float_to_fix16( hMasa->masaMetadata.common_meta.surround_coherence[i][j], 15 ); + hMasa->masaMetadata.common_meta.diffuse_to_total_ratio_fx[i][j] = float_to_fix( hMasa->masaMetadata.common_meta.diffuse_to_total_ratio[i][j], 30 ); + } + } + ivas_merge_masa_metadata_fx( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */ + for ( i = 0; i < numSf; i++ ) + { + for ( j = 0; j < hMasa->config.numCodingBands; j++ ) + { + hMasa->data.energy[i][j] = me2f( hMasa->data.energy_fx[i][j], hMasa->data.energy_e[i][j] ); + hMasa->masaMetadata.directional_meta[0].energy_ratio[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[0].energy_ratio_fx[i][j], 30 ); + hMasa->masaMetadata.directional_meta[1].energy_ratio[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[1].energy_ratio_fx[i][j], 30 ); + hMasa->masaMetadata.directional_meta[1].azimuth[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[1].azimuth_fx[i][j], 22 ); + hMasa->masaMetadata.directional_meta[1].elevation[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[1].elevation_fx[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].azimuth[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[0].azimuth_fx[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].elevation[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[0].elevation_fx[i][j], 22 ); + hMasa->masaMetadata.directional_meta[0].spread_coherence[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[0].spread_coherence_fx[i][j], 15 ); + hMasa->masaMetadata.directional_meta[1].spread_coherence[i][j] = fix_to_float( hMasa->masaMetadata.directional_meta[1].spread_coherence_fx[i][j], 15 ); + hMasa->masaMetadata.common_meta.surround_coherence[i][j] = fix_to_float( hMasa->masaMetadata.common_meta.surround_coherence_fx[i][j], 15 ); + hMasa->masaMetadata.common_meta.diffuse_to_total_ratio[i][j] = fix_to_float( hMasa->masaMetadata.common_meta.diffuse_to_total_ratio_fx[i][j], 30 ); + } + } +#else ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */ +#endif hMasa->config.numCodingBands = numCodingBands_orig; hMasa->config.joinedSubframes = joinedSubframes_orig; @@ -840,7 +897,28 @@ void ivas_omasa_enc( else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { /* Estimate energies and ratios */ +#ifdef IVAS_FLOAT_FIXED + ivas_omasa_energy_and_ratio_est_fx( hOMasa, hMasa->data.hOmasaData, data_in, input_frame, nchan_ism, q_data ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + for ( i = 0; i < nchan_ism; i++ ) + { + fixedToFloat_arrL( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state, q_data, hOMasa->cldfbAnaEnc[i]->cldfb_state_length ); + } + for ( int block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) + { + for ( i = 0; i < hOMasa->nbands; i++ ) + { + for ( int k = 0; k < nchan_ism; k++ ) + { + hMasa->data.hOmasaData->energy_ratio_ism[block_m_idx][i][k] = me2f( hMasa->data.hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k], 1 ); + } + hMasa->data.hOmasaData->energy_ism[block_m_idx][i] = me2f( hMasa->data.hOmasaData->energy_ism_fx[block_m_idx][i], hMasa->data.hOmasaData->energy_ism_fx_e[block_m_idx][i] ); + } + } +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED +#else ivas_omasa_energy_and_ratio_est( hOMasa, hMasa->data.hOmasaData, data_in_f, input_frame, nchan_ism ); +#endif // IVAS_FLOAT_FIXED } /* Downmix */ @@ -1503,6 +1581,8 @@ static void ivas_omasa_param_est_enc_fx( Word16 azimuth_16, elevation_16; Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff; Word16 q; /*stores q for cldfb buffers*/ + Word32 temp; + Word16 temp_e; ref_exp = 0; norm_buff = MAX16B; @@ -1562,8 +1642,7 @@ static void ivas_omasa_param_est_enc_fx( move16(); } set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands ); - hOmasaData->energy_ism_e[block_m_idx] = 0; - move16(); + set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands ); FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { norm_buff = MAX16B; @@ -1583,7 +1662,7 @@ static void ivas_omasa_param_est_enc_fx( move16(); } maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff ); - guard_bits = find_guarded_bits_fx( L_mult0( max_band_grouping_diff, nchan_ism ) ); + guard_bits = find_guarded_bits_fx( num_freq_bins ); norm_buff = sub( norm_buff, guard_bits ); FOR( i = 0; i < nchan_ism; i++ ) { @@ -1591,24 +1670,6 @@ static void ivas_omasa_param_est_enc_fx( scale_sig32( Chnl_ImagBuffer_fx[i], 60, norm_buff ); } q = add( q, norm_buff ); - IF( GT_16( hOmasaData->energy_ism_e[block_m_idx], sub( 62, shl( q, 1 ) ) ) ) - { - norm_buff = sub( q, shr( sub( 62, hOmasaData->energy_ism_e[block_m_idx] ), 1 ) ); - } - ELSE - { - norm_buff = 0; - norm_buff = 0; - move16(); - move16(); - FOR( i = 0; i < num_freq_bands; i++ ) - { - hOmasaData->energy_ism_fx[block_m_idx][i] = L_shr( hOmasaData->energy_ism_fx[block_m_idx][i], sub( sub( 62, shl( q, 1 ) ), hOmasaData->energy_ism_e[block_m_idx] ) ); - move32(); - } - hOmasaData->energy_ism_e[block_m_idx] = sub( 62, shl( q, 1 ) ); - move16(); - } FOR( i = 0; i < num_freq_bands; i++ ) { brange[0] = hOMasa->band_grouping[i]; @@ -1619,9 +1680,9 @@ static void ivas_omasa_param_est_enc_fx( { FOR( j = brange[0]; j < brange[1]; j++ ) { - Word32 scaled_real_buffer = L_shr( Chnl_RealBuffer_fx[k][j], norm_buff ); /*scaling the real and imaginary buffers to match the scale factor of hOmasaData->energy_ism_fx*/ - Word32 scaled_imag_buffer = L_shr( Chnl_ImagBuffer_fx[k][j], norm_buff ); - hOmasaData->energy_ism_fx[block_m_idx][i] = L_add( hOmasaData->energy_ism_fx[block_m_idx][i], L_add( Mpy_32_32( scaled_real_buffer, scaled_real_buffer ), Mpy_32_32( scaled_imag_buffer, scaled_imag_buffer ) ) ); /*2q-31*/ + temp = Mpy_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ); + temp_e = sub( 62, shl( q, 1 ) ); + hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], temp, temp_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] ); /*2q-31*/ move32(); } } @@ -1745,7 +1806,6 @@ static void ivas_omasa_param_est_enc_fx( /* Determine energy ratios */ FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - Word16 temp_e; IF( GT_32( BASOP_Util_Log10( renormalization_factor_diff_fx[band_m_idx], ref_exp ), -( 15 << 25 ) ) ) { diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &temp_e ); @@ -1958,6 +2018,126 @@ static void ivas_omasa_param_est_enc( /* Estimate energies and ratios */ +#ifdef IVAS_FLOAT_FIXED +static void ivas_omasa_energy_and_ratio_est_fx( + OMASA_ENC_HANDLE hOMasa, + OMASA_ENCODER_DATA_HANDLE hOmasaData, + Word32 *data_fx[], /*i: q_data*/ + const Word16 input_frame, + const Word16 nchan_ism, + const Word16 q_data /*i: stoes the q for data_fx*/ +) +{ + Word16 ts, i, j, k; + Word16 num_freq_bands; + Word16 l_ts; + Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; + Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX]; + Word16 block_m_idx; + Word16 mrange[2], brange[2]; + Word32 tftile_energy_fx; + Word16 tftile_energy_e; + Word64 ism_ratio_sum_fx; + Word16 q_cldfb; + Word16 norm_Chnl; + Word16 temp_e; /* to store temporary exp*/ + Word16 energy_ratio_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/ + num_freq_bands = hOMasa->nbands; + l_ts = shr( input_frame, 4 ); /*input_frame / CLDFB_NO_COL_MAX*/ + q_cldfb = q_data; + move16(); /*num_freq_bands*/ + move16(); /*q_cldfb*/ + set_zero_fx( &Chnl_RealBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX ); + set_zero_fx( &Chnl_ImagBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX ); + /* do processing over all CLDFB time slots */ + FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) + { + mrange[0] = hOMasa->block_grouping[block_m_idx]; + mrange[1] = hOMasa->block_grouping[block_m_idx + 1]; + move16(); + move16(); + + /* Reset variable */ + FOR( i = 0; i < hOMasa->nbands; i++ ) + { + set_zero_fx( hOmasaData->energy_ratio_ism_fx[block_m_idx][i], nchan_ism ); + set16_fx( energy_ratio_ism_e[block_m_idx][i], 0, nchan_ism ); + } + set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands ); + set16_fx( hOmasaData->energy_ism_fx_e[block_m_idx], 0, num_freq_bands ); + /* Compute CLDFB */ + FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) + { + norm_Chnl = MAX_16; + move16(); + FOR( i = 0; i < nchan_ism; i++ ) + { + q_cldfb = q_data; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q_cldfb ); + norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) ); + norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) ); + } + norm_Chnl = sub( norm_Chnl, 1 ); + /*scaling cldfb buffers to avoid loss of values in Mpy_32_32*/ + FOR( i = 0; i < nchan_ism; i++ ) + { + scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl ); + scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl ); + } + q_cldfb = add( q_cldfb, norm_Chnl ); + /* Compute energy */ + FOR( i = 0; i < num_freq_bands; i++ ) + { + brange[0] = hOMasa->band_grouping[i]; + brange[1] = hOMasa->band_grouping[i + 1]; + move16(); + move16(); + FOR( j = brange[0]; j < brange[1]; j++ ) + { + FOR( k = 0; k < nchan_ism; k++ ) + { + tftile_energy_fx = L_add( Mpy_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) ); /*2*q_cldfb-31*/ + tftile_energy_e = sub( 62, shl( q_cldfb, 1 ) ); + hOmasaData->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ism_fx[block_m_idx][i], hOmasaData->energy_ism_fx_e[block_m_idx][i], tftile_energy_fx, tftile_energy_e, &hOmasaData->energy_ism_fx_e[block_m_idx][i] ); + hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k] = BASOP_Util_Add_Mant32Exp( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][k], energy_ratio_ism_e[block_m_idx][i][k], tftile_energy_fx, tftile_energy_e, &energy_ratio_ism_e[block_m_idx][i][k] ); + move32(); + move32(); + } + } + } + } + + /* Compute ISM energy ratios */ + FOR( i = 0; i < num_freq_bands; i++ ) + { + ism_ratio_sum_fx = 0; + move64(); + FOR( j = 0; j < nchan_ism; j++ ) + { + hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = BASOP_Util_Divide3232_Scale( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], L_add( hOmasaData->energy_ism_fx[block_m_idx][i], EPSILON_FX ), &temp_e ); + temp_e = add( temp_e, sub( energy_ratio_ism_e[block_m_idx][i][j], hOmasaData->energy_ism_fx_e[block_m_idx][i] ) ); + move32(); + + hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_min( ONE_IN_Q30, L_shl( hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j], add( 15, temp_e ) ) ); /* scaling to q30*/ + move32(); + ism_ratio_sum_fx = W_add( ism_ratio_sum_fx, hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] ); + } + IF( ism_ratio_sum_fx == 0 ) + { + Word16 temp_ism_ratio = BASOP_Util_Divide1616_Scale( 1, nchan_ism, &temp_e ); + FOR( j = 0; j < nchan_ism; j++ ) + { + hOmasaData->energy_ratio_ism_fx[block_m_idx][i][j] = L_min( ONE_IN_Q30, L_shl( temp_ism_ratio, add( 15, temp_e ) ) ); /*scaling to q30*/ + move32(); + } + } + } + } + + return; +} +#else static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, @@ -2039,6 +2219,7 @@ static void ivas_omasa_energy_and_ratio_est( return; } +#endif /* Compute downmix */ diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 5421f1809935496849f6517ac2ccae44927a7308..bdea2aeb65d9b7663995d8185b21a886d5e0c3cc 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -234,15 +234,17 @@ static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t d static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, const int16_t bits_dir_hr, BSTR_ENC_HANDLE hMetaData ); static int16_t ivas_qmetadata_quantize_coherence_hr_512( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t bits_coh ); + +static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); #else static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( IVAS_QMETADATA *hQMetaData, const Word16 idx_d, const Word16 all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const Word16 bits_coh ); static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 *needed_bits, const Word16 bits_dir_hr, BSTR_ENC_HANDLE hMetaData ); static Word16 calc_var_azi_fx( const IVAS_QDIRECTION *q_direction, const Word16 diffuseness_index_max_ec_frame, const Word32 avg_azimuth, Word32 *avg_azimuth_out ); -#endif -static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); +static Word16 encode_surround_coherence_hr_fx( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); +#endif static int16_t write_stream_dct_coeffs_omasa( int16_t *q_idx, const int16_t len_stream, BSTR_ENC_HANDLE hMetaData, const int16_t first_line, const int16_t low_bitrate_mode ); @@ -508,8 +510,36 @@ ivas_error ivas_qmetadata_enc_encode( } ELSE { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ ) + { + for ( Word16 j = 0; j < q_direction->cfg.nblocks; j++ ) + { + q_direction->band_data[i].elevation_fx[j] = float_to_fix( q_direction->band_data[i].elevation[j], Q22 ); + q_direction->band_data[i].azimuth_fx[j] = float_to_fix( q_direction->band_data[i].azimuth[j], Q22 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + /* Quantize directions*/ + quantize_direction_frame_fx( q_direction, azimuth_orig, elevation_orig, 0 ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ ) + { + for ( Word16 j = 0; j < q_direction->cfg.nblocks; j++ ) + { + azimuth_orig_flt[i][j] = fix_to_float( azimuth_orig[i][j], Q22 ); + elevation_orig_flt[i][j] = fix_to_float( elevation_orig[i][j], Q22 ); + q_direction->band_data[i].elevation[j] = fix_to_float( q_direction->band_data[i].elevation_fx[j], Q22 ); + q_direction->band_data[i].azimuth[j] = fix_to_float( q_direction->band_data[i].azimuth_fx[j], Q22 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS +#else /* Quantize directions*/ quantize_direction_frame( q_direction, azimuth_orig_flt, elevation_orig_flt, 0 ); +#endif // IVAS_FLOAT_FIXED } /* Signalling 2D*/ @@ -1089,6 +1119,7 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( int16_t all_coherence_zero; int16_t bits_ec; float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; ivas_error error; error = IVAS_ERR_OK; @@ -1195,7 +1226,7 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( /* Encode surround coherence */ if ( all_coherence_zero == 0 ) { - encode_surround_coherence_hr( hQMetaData, hMetaData ); + encode_surround_coherence_hr_fx( hQMetaData, hMetaData ); } else { @@ -1234,12 +1265,44 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( #endif /* write the spherical indexes */ bits_ec = hMetaData->nb_bits_tot; + +#ifdef IVAS_FLOAT_FIXED + IF( EQ_16( bits_sph_idx, 11 ) ) + { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ ) + { + for ( j = 0; j < q_direction->cfg.nblocks; j++ ) + { + q_direction->band_data[i].elevation_fx[j] = float_to_fix( q_direction->band_data[i].elevation[j], Q22 ); + q_direction->band_data[i].azimuth_fx[j] = float_to_fix( q_direction->band_data[i].azimuth[j], Q22 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + + /* do the quantization */ + quantize_direction_frame_fx( q_direction, azimuth_orig_fx, elevation_orig_fx, 1 ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ ) + { + for ( j = 0; j < q_direction->cfg.nblocks; j++ ) + { + azimuth_orig[i][j] = fix_to_float( azimuth_orig_fx[i][j], Q22 ); + elevation_orig[i][j] = fix_to_float( elevation_orig_fx[i][j], Q22 ); + q_direction->band_data[i].elevation[j] = fix_to_float( q_direction->band_data[i].elevation_fx[j], Q22 ); + q_direction->band_data[i].azimuth[j] = fix_to_float( q_direction->band_data[i].azimuth_fx[j], Q22 ); + } + } +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + } +#else if ( bits_sph_idx == 11 ) { /* do the quantization */ quantize_direction_frame( q_direction, azimuth_orig, elevation_orig, 1 ); } - +#endif for ( i = start_band; i < nbands; i++ ) { for ( j = 0; j < nblocks; j++ ) @@ -1280,6 +1343,176 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( return error; } +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_qmetadata_enc_encode_hr_384_512_fx( + BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ + IVAS_QMETADATA *hQMetaData, /* i/o: metadata handle */ + const Word16 bits_sph_idx, + const Word16 bits_sp_coh ) +{ + Word16 i, j; + Word16 bits_diff[QMETADATA_MAX_NO_DIRECTIONS]; + IVAS_QDIRECTION *q_direction; + Word16 nbands, nblocks, start_band; + Word16 ndirections, d; + Word16 all_coherence_zero; + Word16 bits_ec; + Word32 azimuth_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + ivas_error error; + + error = IVAS_ERR_OK; + move32(); + + + ndirections = hQMetaData->no_directions; + move16(); + + /* Check if coherence should be encoded */ + all_coherence_zero = 1; + move16(); + IF( hQMetaData->q_direction->cfg.inactiveBands > 0 ) + { + push_next_indice( hMetaData, 1, 1 ); + /* write the number of inactive higher bands */ + ivas_qmetadata_encode_extended_gr( hMetaData, sub( hQMetaData->q_direction->cfg.inactiveBands, 1 ), MASA_MAXIMUM_CODING_SUBBANDS, 1 ); + } + ELSE + { + /* no change */ + push_next_indice( hMetaData, 0, 1 ); + } + IF( hQMetaData->coherence_flag ) + { + all_coherence_zero = hQMetaData->all_coherence_zero; + move16(); + push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */ + } + + /* encode 2 direction subbands position */ + test(); + IF( EQ_16( ndirections, 2 ) && EQ_16( bits_sph_idx, 11 ) ) + { + write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands ); + d = 0; + move16(); + FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) + { + IF( hQMetaData->twoDirBands[i] == 1 ) + { + Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); + + IF( hQMetaData->coherence_flag ) + { + mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks ); + } + d = add( d, 1 ); + } + } + FOR( i = hQMetaData->numTwoDirBands; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) + { + set32_fx( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, 0, hQMetaData->q_direction[1].cfg.nblocks ); + } + + hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; + move16(); + } + + /*Quantization and encoding of the Diffuseness */ + ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( hQMetaData, bits_diff, bits_sph_idx, hMetaData ); + + + /* Encode surround coherence */ + IF( all_coherence_zero == 0 ) + { + encode_surround_coherence_hr_fx( hQMetaData, hMetaData ); + } + ELSE + { + FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) + { + IF( hQMetaData->surcoh_band_data != NULL ) + { + set8_fx( (Word8 *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks ); + } + } + } + + /* Loop over number of directions*/ + FOR( d = 0; d < ndirections; d++ ) + { + q_direction = &( hQMetaData->q_direction[d] ); + + nbands = q_direction->cfg.nbands; + nblocks = q_direction->cfg.nblocks; + start_band = q_direction->cfg.start_band; + move16(); + move16(); + move16(); + + q_direction->not_in_2D = 0; + move16(); + + /*Coherence */ + IF( all_coherence_zero == 0 ) + { + ivas_qmetadata_quantize_coherence_hr_512_fx( hQMetaData, d, all_coherence_zero, hMetaData, bits_sp_coh ); + } + + /* write the spherical indexes */ + bits_ec = hMetaData->nb_bits_tot; + move16(); + + IF( EQ_16( bits_sph_idx, 11 ) ) + { + /* do the quantization */ + quantize_direction_frame_fx( q_direction, azimuth_orig_fx, elevation_orig_fx, 1 ); + } + + FOR( i = start_band; i < nbands; i++ ) + { + FOR( j = 0; j < nblocks; j++ ) + { + push_next_indice( hMetaData, q_direction->band_data[i].spherical_index[j], bits_sph_idx ); + } + } + bits_ec = sub( hMetaData->nb_bits_tot, bits_ec ); + + + /* Save quantized DOAs */ + IF( EQ_16( bits_sph_idx, 11 ) ) + { + FOR( i = start_band; i < nbands; i++ ) + { + Copy32( azimuth_orig_fx[i], q_direction->band_data[i].azimuth_fx, nblocks ); + Copy32( elevation_orig_fx[i], q_direction->band_data[i].elevation_fx, nblocks ); + } + } + ELSE + { + FOR( i = start_band; i < nbands; i++ ) + { + Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks ); + Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks ); + } + } + } + + IF( hQMetaData->q_direction->cfg.inactiveBands > 0 ) + { + hQMetaData->q_direction[0].cfg.nbands = add( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction->cfg.inactiveBands ); + move16(); + IF( GT_16( ndirections, 1 ) ) + { + hQMetaData->q_direction[1].cfg.nbands = add( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction->cfg.inactiveBands ); + move16(); + } + } + + return error; +} +#endif /*-----------------------------------------------------------------------* @@ -7582,7 +7815,239 @@ static int16_t encode_surround_coherence( } #endif +#ifdef IVAS_FLOAT_FIXED +static Word16 encode_surround_coherence_hr_fx( + IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ + BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */ +) +{ + Word16 i, j, k, sf; + Word16 nbits, nbits_fr, nbits_sf; + UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 GR_ord, bits_GR; + UWord64 idx, idx1; + Word16 no_idx16; + Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; + Word32 error_ratio_surr; + IVAS_QDIRECTION *q_direction; + Word16 half_coding_subbands, nbits_fr1, coding_subbands; + Word16 all_coherence_zero; + UWord16 idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord8 idx_shift; + Word16 max_val = 0, nbits_max; + Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; + Word16 idx16; + move16(); + + coding_subbands = hQMetaData->q_direction[0].cfg.nbands; + all_coherence_zero = hQMetaData->all_coherence_zero; + q_direction = &( hQMetaData->q_direction[0] ); + nbits = 0; + move16(); + move16(); + move16(); + + IF( EQ_16( all_coherence_zero, 1 ) ) + { + nbits = 0; + move16(); + } + ELSE + { + FOR( sf = 0; sf < hQMetaData->q_direction[0].cfg.nblocks; sf++ ) + { + GR_ord = 1; + k = 0; + idx_shift = 0; + move16(); + move16(); + move16(); + FOR( j = 0; j < coding_subbands; j++ ) + { + IF( EQ_16( hQMetaData->no_directions, 2 ) ) + { + k = add( k, hQMetaData->twoDirBands[j] ); + idx16 = s_max( sub( k, 1 ), 0 ); + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); + IF( hQMetaData->twoDirBands[j] ) + { + error_ratio_surr = L_sub( error_ratio_surr, q_direction[1].band_data[idx16].energy_ratio_fx[sf] ); + } + } + ELSE + { + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[sf] ); + } + +#ifndef NON_BE_FIX_1048_THRESHOLD_COH_BASOP + IF( error_ratio_surr <= 0 ) +#else + /* if ( error_ratio_surr <= 0 ) Restricting precision to 7 decimal places */ + IF( LE_32( error_ratio_surr, 107 /* 1e-7 in Q30 */ ) ) +#endif + { + error_ratio_surr = 0; + idx_sur_coh[j] = 0; + no_cv[j] = 1; + hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */ + move32(); + move16(); + move16(); + move16(); + } + ELSE + { + idx_sur_coh[j] = squant_int_fx( hQMetaData->surcoh_band_data[j].surround_coherence[sf], &hQMetaData->surcoh_band_data[j].surround_coherence[sf], + &sur_coherence_cb_masa[idx_cb_sur_coh_masa[7] * MASA_MAX_NO_CV_SUR_COH], idx_cb_sur_coh_masa[7] + 2 ); + no_cv[j] = add( idx_cb_sur_coh_masa[7], 2 ); + no_cv_shift[idx_shift] = no_cv[j]; + idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j]; + move16(); + move16(); + move16(); + move16(); + } + } + + IF( NE_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) ) + { + nbits_max = 0; + move16(); + IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) + { + j = maximum_s( (Word16 *) idx_sur_coh, coding_subbands, &max_val ); + FOR( j = 0; j < coding_subbands; j++ ) + { + IF( GT_16( no_cv[j], add( max_val, 1 ) ) ) + { + no_cv[j] = add( max_val, 1 ); + move16(); + } + } + nbits_max = sub( MASA_MAX_NO_CV_SUR_COH, max_val ); /* encoded with GR0 as max_no_vals - no_vals*/ + } + IF( max_val == 0 ) + { + FOR( j = 0; j < coding_subbands; j++ ) + { + hQMetaData->surcoh_band_data[j].surround_coherence[sf] = 0; + move16(); + } + } + nbits_sf = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv, + mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 ); + half_coding_subbands = shr( coding_subbands, 1 ); + idx1 = 0; + move16(); + + /* should check how to encode the average - check distribution */ + IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits_sf ) ) + { + /* write flag*/ + push_next_indice( hMetaData, 0, 1 ); + + /* create combined index */ + nbits = add( nbits, add( nbits_fr, add( nbits_fr1, 1 ) ) ); + IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) + { + /* write max value*/ + bits_GR = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, sub( MASA_MAX_NO_CV_SUR_COH - 1, max_val ), MASA_MAX_NO_CV_SUR_COH, 0 ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); + } + + IF( nbits_fr1 > 0 ) + { + idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv ); + idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); + } + ELSE + { + idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv ); + } + + IF( nbits_fr % 16 == 0 ) + { + no_idx16 = shr( nbits_fr, 4 ); + } + ELSE + { + no_idx16 = shr_r( nbits_fr, 4 ); + } + /* write combined index */ + k = nbits_fr; + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) + { + k = sub( k, 16 ); + push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */ + } + + push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k ); + + IF( nbits_fr1 > 0 ) + { + IF( nbits_fr1 % 16 == 0 ) + { + no_idx16 = shr( nbits_fr1, 4 ); + } + ELSE + { + no_idx16 = shr_r( nbits_fr1, 4 ); + } + + assert( no_idx16 <= 4 ); + + k = nbits_fr1; + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) + { + k = sub( k, 16 ); + push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */ + } + + push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k ); + } + } + ELSE + { + /* write flag */ + nbits = add( nbits, 1 ); + + /* write flag*/ + push_next_indice( hMetaData, 1, 1 ); + + /* write GR_ord */ + push_next_indice( hMetaData, GR_ord, 1 ); + nbits = add( nbits, 1 ); + + /* write the min */ + bits_GR = hMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); + + /* write GR data */ + FOR( j = 0; j < idx_shift; j++ ) + { + bits_GR = hMetaData->nb_bits_tot; + move16(); + + ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); + + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); + } + } + } + } + } + + return nbits; +} +#else static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */ @@ -7787,6 +8252,7 @@ static int16_t encode_surround_coherence_hr( return nbits; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_qspherical_enc.c b/lib_enc/ivas_qspherical_enc.c index 2c5294e3166eba5f800373fb8973814425ce0c2e..ccfda56b606ed96e7b984dc628c71453c202a70a 100644 --- a/lib_enc/ivas_qspherical_enc.c +++ b/lib_enc/ivas_qspherical_enc.c @@ -41,7 +41,9 @@ #include "wmc_auto.h" #include "prot.h" #ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" #include "ivas_prot_fx.h" +#include "ivas_rom_com_fx.h" #endif @@ -53,6 +55,12 @@ static float quantize_theta_phi( float *theta_cb, const int16_t no_th, const int static float direction_distance_cp( float theta, float theta_hat, float theta_hat1, const float phi, const float phi_hat, const float phi_hat1, float *d1 ); +#ifdef IVAS_FLOAT_FIXED +static Word32 quantize_theta_phi_fx( Word32 *theta_cb, const Word16 no_th, const Word16 *no_phi_loc, const Word32 abs_theta, Word16 *id_phi, Word16 *id_phi_remap, Word32 *phi_hat, const Word32 phi, const Word16 no_bits, Word16 *id_theta, Word32 *phi_q, const Word16 remap, const MC_LS_SETUP mc_format ); + +static Word16 direction_distance_cp_fx( Word32 theta, Word32 theta_hat, Word32 theta_hat1, const Word32 phi, const Word32 phi_hat, const Word32 phi_hat1, Word16 *d1 ); +#endif + /*-------------------------------------------------------------------* * quantize_direction_frame() * @@ -158,6 +166,122 @@ void quantize_direction_frame( return; } +#ifdef IVAS_FLOAT_FIXED +void quantize_direction_frame_fx( + IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */ + Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* o : Q22 */ + Word32 elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], /* o : Q22 */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +) +{ + Word16 i, j; + UWord16 idx; + + /* Quantize directions */ + q_direction->not_in_2D = 0; + move16(); + FOR( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ ) + { + idx = q_direction->band_data[i].energy_ratio_index_mod[0]; + move16(); + FOR( j = 0; j < q_direction->cfg.nblocks; j++ ) + { + if ( azimuth_orig != NULL ) + { + azimuth_orig[i][j] = q_direction->band_data[i].azimuth_fx[j]; + move32(); + } + + if ( elevation_orig != NULL ) + { + elevation_orig[i][j] = q_direction->band_data[i].elevation_fx[j]; + move32(); + } + + /* requantize the direction */ + q_direction->band_data[i].spherical_index[j] = quantize_direction_fx( q_direction->band_data[i].elevation_fx[j], + q_direction->band_data[i].azimuth_fx[j], + q_direction->band_data[i].bits_sph_idx[j], + &q_direction->band_data[i].elevation_fx[j], + &q_direction->band_data[i].azimuth_fx[j], &q_direction->band_data[i].elevation_index[j], + &q_direction->band_data[i].azimuth_index[j], + q_direction->cfg.mc_ls_setup ); + + q_direction->not_in_2D = add( q_direction->not_in_2D, q_direction->band_data[i].elevation_index[j] ); + move16(); + + IF( hrmasa_flag ) + { + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3]; + q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][q_direction->band_data[i].elevation_index[j]]; + } + ELSE + { + q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3] * 2 - 1; + q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1]; + } + } + ELSE + { + IF( NE_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3]; + q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][q_direction->band_data[i].elevation_index[j]]; + move16(); + move16(); + } + ELSE + { + q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3] * 2 - 1; + q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1]; + move16(); + move16(); + } + } + + if ( EQ_16( q_direction->band_data[i].azimuth_index[j], MASA_NO_INDEX ) ) + { + q_direction->band_data[i].azimuth_index[j] = 0; + move16(); + } + + IF( LE_16( q_direction->band_data[i].bits_sph_idx[j], 2 ) ) + { + q_direction->band_data[i].elevation_index[j] = 0; + move16(); + } + ELSE + { + IF( EQ_32( q_direction->cfg.mc_ls_setup, MC_LS_SETUP_INVALID ) ) + { + /*deorder elevation indexing*/ + IF( s_and( q_direction->band_data[i].elevation_index[j], 1 ) != 0 ) + { + q_direction->band_data[i].elevation_index[j] = add( shr( add( q_direction->band_data[i].elevation_index[j], 1 ), 1 ), shr( q_direction->band_data[i].elevation_m_alphabet[j], 1 ) ); + move16(); + } + ELSE + { + // q_direction->band_data[i].elevation_index[j] = -( ( q_direction->band_data[i].elevation_index[j] ) >> 1 ) + ( q_direction->band_data[i].elevation_m_alphabet[j] >> 1 ); + q_direction->band_data[i].elevation_index[j] = sub( shr( q_direction->band_data[i].elevation_m_alphabet[j], 1 ), shr( ( q_direction->band_data[i].elevation_index[j] ), 1 ) ); + move16(); + } + } + } + } + } + + if ( q_direction->not_in_2D > 0 ) + { + q_direction->not_in_2D = 1 + MASA_LIMIT_2D; + move16(); + } + + return; +} +#endif /*-------------------------------------------------------------------* @@ -493,7 +617,276 @@ uint16_t quantize_direction( return idx_sph; } +#ifdef IVAS_FLOAT_FIXED +/*! r: quantized spherical index */ +UWord16 quantize_direction_fx( + const Word32 theta, /* i : input elevation value, Q22 */ + Word32 phi, /* i : input azimuth value, Q22 */ + const Word16 no_bits, /* i : number of bits */ + Word32 *theta_q, /* o : quantized elevation, Q22 */ + Word32 *phi_q, /* o : quantized azimuth, Q22 */ + UWord16 *index_theta, /* o : quantized elevation index */ + UWord16 *index_phi, /* o : quantized azimuth index */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +) +{ + Word32 abs_theta, theta_hat, phi_hat; + Word16 i, sign_th; + Word16 cum_n[500]; + Word16 id_th, id_phi; + Word32 theta_cb[MAX_NO_THETA]; + Word16 no_th; + UWord16 idx_sph; + Word16 id_phi_remap; + + set32_fx( theta_cb, 0, MAX_NO_THETA ); + + IF( no_bits == 0 ) + { + *theta_q = 0; + *phi_q = 0; + *index_theta = MASA_NO_INDEX; + *index_phi = MASA_NO_INDEX; + move32(); + move32(); + move16(); + move16(); + + return 0; + } + + IF( EQ_16( no_bits, 1 ) ) + { + *theta_q = 0; + *index_theta = MASA_NO_INDEX; + move32(); + move16(); + + test(); + IF( LT_32( phi, ( -DEGREE_90_Q_22 ) ) || GT_32( phi, DEGREE_90_Q_22 ) ) + { + *phi_q = -DEGREE_180_Q_22; + *index_phi = 1; + move32(); + move16(); + + return 1; + } + ELSE + { + *phi_q = 0; + *index_phi = 0; + move32(); + move16(); + + return 0; + } + } + + IF( EQ_16( no_bits, 2 ) ) + { + *theta_q = 0; + *index_theta = MASA_NO_INDEX; + move32(); + move16(); + IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + id_phi = quantize_phi_chan_lbr_fx( phi, &phi_hat, no_phi_masa[no_bits - 1][0] ); + phi_hat = L_add( phi_hat, DEGREE_180_Q_22 ); + idx_sph = id_phi; + *phi_q = L_sub( phi_hat, DEGREE_180_Q_22 ); + id_phi_remap = id_phi; + *index_phi = id_phi_remap; + move16(); + move32(); + move16(); + move16(); + } + ELSE + { + id_phi = quantize_phi_fx( L_add( phi, DEGREE_180_Q_22 ), 0, &phi_hat, no_phi_masa[no_bits - 1][0] ); + idx_sph = id_phi; + *phi_q = L_sub( phi_hat, DEGREE_180_Q_22 ); + id_phi_remap = ivas_qmetadata_reorder_generic( sub( id_phi, shr( no_phi_masa[no_bits - 1][0], 1 ) ) ); + *index_phi = id_phi_remap; + move16(); + move32(); + move16(); + } + + return idx_sph; + } + + no_th = no_theta_masa[no_bits - 3]; + move16(); + + FOR( i = 0; i < no_th; i++ ) + { + theta_cb[i] = imult3216( delta_theta_masa_fx[no_bits - 3], i ); + move32(); + } + + if ( GT_32( theta_cb[i - 1], DEGREE_90_Q_22 ) ) + { + theta_cb[i - 1] = DEGREE_90_Q_22; + move32(); + } + + phi = L_add( phi, DEGREE_180_Q_22 ); + + IF( theta < 0 ) + { + abs_theta = L_negate( theta ); + sign_th = -1; + move16(); + } + ELSE + { + abs_theta = theta; + sign_th = 1; + move32(); + move16(); + } + + theta_hat = quantize_theta_phi_fx( theta_cb, no_th, no_phi_masa[no_bits - 1], abs_theta, &id_phi, + &id_phi_remap, &phi_hat, phi, no_bits, &id_th, phi_q, 1, mc_format ); + + IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + /* indexing only for upper hemisphere */ + cum_n[0] = no_phi_masa[no_bits - 1][0]; + move16(); + FOR( i = 1; i < no_th; i++ ) + { + cum_n[i] = add( cum_n[i - 1], no_phi_masa[no_bits - 1][i] ); + move16(); + } + + IF( LT_16( id_phi, MASA_NO_INDEX ) ) + { + IF( id_th == 0 ) + { + idx_sph = id_phi; + move16(); + } + ELSE + { + idx_sph = add( cum_n[id_th - 1], id_phi ); + } + } + ELSE{ + IF( id_th == 0 ){ + idx_sph = 0; + move16(); + } + ELSE + { + idx_sph = cum_n[id_th - 1]; + move16(); + } +} +*theta_q = theta_hat; +move32(); +IF( EQ_32( theta_hat, DEGREE_90_Q_22 ) ) +{ + *phi_q = 0; + id_phi = MASA_NO_INDEX; + move32(); + move16(); +} +ELSE +{ + *phi_q = L_sub( phi_hat, DEGREE_180_Q_22 ); + move32(); +} +*index_theta = id_th; +*index_phi = id_phi_remap; +move16(); +move16(); +} +ELSE +{ + /* Starting from Equator, alternating positive and negative */ + cum_n[0] = no_phi_masa[no_bits - 1][0]; + move16(); + FOR( i = 1; i < no_th; i++ ) + { + cum_n[2 * i - 1] = add( cum_n[2 * i - 2], no_phi_masa[no_bits - 1][i] ); + cum_n[2 * i] = add( cum_n[2 * i - 1], no_phi_masa[no_bits - 1][i] ); + move16(); + move16(); + } + + if ( no_th > 0 ) + { + assert( abs( cum_n[2 * ( no_th - 1 )] ) < 32768 ); + } + + IF( id_th == 0 ) + { + IF( LT_16( id_phi, MASA_NO_INDEX ) ) + { + idx_sph = id_phi; + move16(); + } + ELSE + { + idx_sph = 0; + move16(); + } + } + ELSE{ + IF( sign_th > 0 ){ + IF( LT_16( id_phi, MASA_NO_INDEX ) ){ + idx_sph = add( cum_n[2 * id_th - 2], id_phi ); +} +ELSE +{ + idx_sph = cum_n[2 * id_th - 2]; + move16(); +} + +id_th = sub( shl( id_th, 1 ), 1 ); +} +ELSE +{ + IF( LT_16( id_phi, MASA_NO_INDEX ) ) + { + idx_sph = add( cum_n[2 * id_th - 1], id_phi ); + } + ELSE + { + idx_sph = cum_n[2 * id_th - 1]; + move16(); + } + id_th = shl( id_th, 1 ); +} +} + +*theta_q = imult3216( theta_hat, sign_th ); +move32(); +IF( EQ_32( theta_hat, DEGREE_90_Q_22 ) ) +{ + *phi_q = 0; + id_phi = MASA_NO_INDEX; + move32(); + move16(); +} +ELSE +{ + *phi_q = L_sub( phi_hat, DEGREE_180_Q_22 ); + move32(); +} + +*index_theta = id_th; +*index_phi = id_phi_remap; +move16(); +move16(); +} +return idx_sph; +} +#endif /*-------------------------------------------------------------------* * direction_distance_cp() @@ -526,7 +919,70 @@ static float direction_distance_cp( return d; } +#ifdef IVAS_FLOAT_FIXED +/*! r: distortion value */ +static Word16 direction_distance_cp_fx( // Q14 + Word32 theta, /* i : elevation absolute value, Q22 */ + Word32 theta_hat, /* i : quantized elevation value in absolute value, Q22 */ + Word32 theta_hat1, /* i : quantized elevation value in absolute value, Q22 */ + const Word32 phi, /* i : azimuth value, Q22 */ + const Word32 phi_hat, /* i : quantized azimuth value, Q22 */ + const Word32 phi_hat1, /* i : quantized azimuth value, Q22 */ + Word16 *d1 /* o : Q14 */ +) +{ + Word16 d, ct, st, st1, st2; + Word16 theta16, theta_hat16, theta_hat1_16; + Word16 tmp, tmp_e, tmp_phi; + + theta16 = extract_l( Mpy_32_32( theta, PI_OVER_180_Q22 ) ); // (Q22 + Q22 - 31) = Q13 + theta_hat16 = extract_l( Mpy_32_32( theta_hat, PI_OVER_180_Q22 ) ); // (Q22 + Q22 - 31) = Q13 + theta_hat1_16 = extract_l( Mpy_32_32( theta_hat1, PI_OVER_180_Q22 ) ); // (Q22 + Q22 - 31) = Q13 + + st = getSinWord16( theta16 ); // Q15 + ct = getCosWord16( theta16 ); // Q14 + st1 = getSinWord16( theta_hat16 ); // Q15 + st2 = getSinWord16( theta_hat1_16 ); // Q15 + + // d = st * st1 + ct * ( sqrtf( 1 - st1 * st1 ) ) * cosf( ( phi - phi_hat ) * PI_OVER_180 ); + + /*( phi - phi_hat ) * PI_OVER_180 */ + tmp_phi = extract_l( Mpy_32_32( L_sub( phi, phi_hat ), PI_OVER_180_Q22 ) ); // (Q22 + Q22 - 31) = Q13 + + tmp_e = 0; + move16(); + tmp = Sqrt16( sub( MAX16B, mult( st1, st1 ) ), &tmp_e ); + tmp = shl_sat( tmp, tmp_e ); // Q15 + + tmp = mult( tmp, shl_sat( getCosWord16( tmp_phi ), 1 ) /* Q15 */ ); // Q15 + tmp = mult( tmp, ct /* Q14 */ ); // Q14 + + tmp = add_sat( tmp, shr( mult( st, st1 ), 1 ) /* Q14 */ ); // Q14 + + d = tmp; // Q15 + move16(); + // *d1 = st * st2 + ct * ( sqrtf( 1 - st2 * st2 ) ) * cosf( ( phi - phi_hat1 ) * PI_OVER_180 ); + + /*( phi - phi_hat1 ) * PI_OVER_180 */ + tmp_phi = extract_l( Mpy_32_32( L_sub( phi, phi_hat1 ), PI_OVER_180_Q22 ) ); // (Q22 + Q22 - 31) = Q13 + + tmp_e = 0; + move16(); + tmp = Sqrt16( sub( MAX16B, mult( st2, st2 ) ), &tmp_e ); + tmp = shl_sat( tmp, tmp_e ); // Q15 + + tmp = mult( tmp, shl_sat( getCosWord16( tmp_phi ), 1 ) /* Q15 */ ); // Q15 + tmp = mult( tmp, ct /* Q14 */ ); // Q14 + + tmp = add_sat( tmp, shr( mult( st, st2 ), 1 ) /* Q14 */ ); // Q14 + + *d1 = tmp; + move16(); + + return d; +} +#endif /*-------------------------------------------------------------------* * quantize_theta_phi() @@ -662,3 +1118,166 @@ static float quantize_theta_phi( return theta_hat; } +#ifdef IVAS_FLOAT_FIXED +/*! r: quantized elevation value */ +static Word32 quantize_theta_phi_fx( // Q22 + Word32 *theta_cb, /* i : elevation codebook, Q22 */ + const Word16 no_th, /* i : elevation codebook size */ + const Word16 *no_phi_loc, /* i : number of azimuth values for each elevation codeword */ + const Word32 abs_theta, /* i : absolute value of elevation to be quantized, Q22 */ + Word16 *id_phi, /* o : azimuth index */ + Word16 *id_phi_remap, /* o : remapped azimuth index */ + Word32 *phi_hat, /* o : quantized azimuth value, Q22 */ + const Word32 phi, /* i : input azimuth value; to be quantized, Q22 */ + const Word16 no_bits, /* i : number of bits used for quantization */ + Word16 *id_theta, /* o : elevation index */ + Word32 *phi_q, /* o : rotated quantized azimuth, Q22 */ + const Word16 remap, /* i : flag for remapping */ + const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */ +) +{ + Word32 theta_hat, theta_hat1, phi_hat1; + Word16 theta_hat16, theta_cb16[MAX_NO_THETA]; + Word16 id_th, id_th1, id_th2, id_ph, id_ph1, s; + Word16 d_fx, d1_fx; + + set16_fx( theta_cb16, 0, MAX_NO_THETA ); + + id_th = BASOP_Util_Divide3232_Scale( abs_theta, delta_theta_masa_fx[no_bits - 3], &s ); + id_th = shr( id_th, sub( 15, s ) ); // Q0 + + IF( GE_16( id_th, no_th ) ) + { + id_th = sub( no_th, 1 ); + } + theta_hat = theta_cb[id_th]; + move32(); + + IF( LT_16( id_th, sub( no_th, 1 ) ) ) + { + Copy_Scale_sig32_16( theta_cb, theta_cb16, MAX_NO_THETA, -( Q22 - Q16 ) ); + + id_th = add( id_th, squant_fx( extract_l( L_shr( abs_theta, Q22 ) ), &theta_hat16, &theta_cb16[id_th], 2 ) ); + + theta_hat = L_shl( L_deposit_l( theta_hat16 ), Q22 ); // Q0 -> Q22 + } + + IF( GT_16( no_th, 1 ) ) + { + test(); + IF( LT_16( no_th, 6 ) && EQ_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + IF( id_th == 0 ) + { + id_th1 = 1; + move16(); + } + ELSE IF( EQ_16( id_th, sub( no_th, 1 ) ) ) + { + id_th1 = sub( no_th, 2 ); + } + ELSE + { + id_th1 = sub( id_th, 1 ); + id_th2 = add( id_th, 1 ); + + if ( GT_32( L_abs( L_sub( abs_theta, theta_cb[id_th1] ) ), L_abs( L_sub( abs_theta, theta_cb[id_th2] ) ) ) ) + { + id_th1 = id_th2; + move16(); + } + } + } + ELSE + { + id_th1 = id_th; + move16(); + } + + IF( GT_16( no_phi_loc[id_th], 1 ) ) + { + /* Note: (id_th % 2 == 1) must be equal to id_th % 2 */ + IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + id_ph = quantize_phi_chan_compand_fx( phi, phi_hat, no_phi_loc[id_th], (Word16) GT_32( theta_cb[id_th], MC_MASA_THR_ELEVATION ), mc_format ); + *id_phi_remap = id_ph; + move16(); + } + ELSE + { + id_ph = quantize_phi_fx( phi, s_and( id_th, 1 ), phi_hat, no_phi_loc[id_th] ); + } + } + ELSE + { + id_ph = MASA_NO_INDEX; + *id_phi_remap = MASA_NO_INDEX; + *phi_hat = DEGREE_180_Q_22; + *phi_q = 0; + move16(); + move16(); + move32(); + move32(); + } + + test(); + test(); + test(); + IF( GT_16( no_phi_loc[id_th1], 1 ) && LT_16( id_ph, MASA_NO_INDEX ) && LT_16( no_th, 6 ) && EQ_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + theta_hat1 = theta_cb[id_th1]; + move32(); + + id_ph1 = quantize_phi_fx( phi, s_and( id_th1, 1 ), &phi_hat1, no_phi_loc[id_th1] ); + + d_fx = direction_distance_cp_fx( abs_theta, theta_hat, theta_hat1, phi, *phi_hat, phi_hat1, &d1_fx ); + + IF( GT_16( d1_fx, d_fx ) ) + { + *phi_hat = phi_hat1; + id_ph = id_ph1; + theta_hat = theta_cb[id_th1]; + id_th = id_th1; + move16(); + move16(); + move32(); + move32(); + } + } + } + ELSE + { + IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) ) + { + id_ph = quantize_phi_chan_compand_fx( phi, phi_hat, no_phi_loc[id_th], 0, mc_format ); + *id_phi_remap = id_ph; + move16(); + } + ELSE + { + id_ph = quantize_phi_fx( phi, s_and( id_th, 1 ), phi_hat, no_phi_loc[id_th] ); + } + } + + IF( remap ) + { + IF( LT_16( id_ph, MASA_NO_INDEX ) ) + { + *id_phi_remap = ivas_qmetadata_reorder_generic( sub( id_ph, shr( no_phi_loc[id_th], 1 ) ) ); + move16(); + } + } + ELSE + { + *id_phi_remap = id_ph; + move16(); + } + + *id_phi = id_ph; + *id_theta = id_th; + move16(); + move16(); + + return theta_hat; +} +#endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index c4b1565a7a1f337834eda486b93d93cab521ec18..c17621b8f0e7698f32d55c086d620fe337ab164f 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1185,7 +1185,8 @@ typedef struct ivas_omasa_encoder_one_data_struct float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; #ifdef IVAS_FLOAT_FIXED Word32 energy_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word16 energy_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 energy_ism_fx_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word32 energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/ Word32 q_energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /* Q30 */ Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ #endif @@ -1227,6 +1228,7 @@ typedef struct ivas_masa_encoder_data_struct #ifdef IVAS_FLOAT_FIXED Word32 energy_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; Word16 energy_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 q_energy; // Common Q for all energy_fx elements #endif int16_t num_Cldfb_instances; HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_ENC_CLDFB_INSTANCES]; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 7e32966289a88a8bd574e053a82a1f818dc0fd99..83ab7cc1e5807a14dea184a01032905c8ee12e9e 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -146,15 +146,14 @@ void dtx_fx( const Word16 vad, /* i : vad flag */ const Word16 speech[], /* i : Pointer to the speech frame */ Word16 Q_speech /* i : Q factor for speech */ - ); void dtx_ivas_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word32 ivas_total_brate, /* i : IVAS total bitrate */ const Word16 vad, /* i : vad flag for DTX */ - const Word16 speech[] /* i : Pointer to the speech frame */ - + const Word16 speech[], /* i : Pointer to the speech frame */ + Word16 Q_speech /* i : Q factor for speech */ ); Word16 dtx_hangover_addition_fx( diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index d6263872e39493d0a178aff399fb5a1c34a21e19..97c5a2ec10d70930da9d2044f2dc98acdf54d41a 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -644,10 +644,10 @@ typedef struct dtx_enc_structure float lt_ener_voiced; /* CNG and DTX - long-term energy of signal (measured on voiced parts) */ float lt_ener_noise; /* CNG and DTX - long-term energy of background noise */ float frame_ener; - Word32 lt_ener_voiced_fx; /* CNG and DTX - long-term energy of signal (measured on voiced parts) */ - Word32 lt_ener_noise_fx; /* CNG and DTX - long-term energy of background noise */ + Word32 lt_ener_voiced_fx; /* CNG and DTX - long-term energy of signal (measured on voiced parts) Q(-7) */ + Word32 lt_ener_noise_fx; /* CNG and DTX - long-term energy of background noise Q(-7) */ - Word32 frame_ener_fx; + Word32 frame_ener_fx; /* Q(-7) */ int16_t cng_hist_size; /* CNG and DTX - size of CNG history buffer for averaging, <0,DTX_HIST_SIZE> */ float lt_ener_last_SID; /* CNG and DTX - long-term energy of last SID frame */ Word32 lt_ener_last_SID_fx; /* CNG and DTX - long-term energy of last SID frame */