diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 2c95079442f03bed83e4b8443f67339b5d261bc1..94abc3b85967e021de192e0834378452549c2917 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -317,11 +317,6 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { Word16 override; Word16 nBands; /* Number of frequency bands for which reverb properties are provided, integer, range [2..256] */ - float pFc_input[IVAS_CLDFB_NO_CHANNELS_MAX]; /* Center frequencies for which following values are provided: */ - float pAcoustic_rt60[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's T60 per center frequency */ - float pAcoustic_dsr[IVAS_CLDFB_NO_CHANNELS_MAX]; /* - The room's Diffuse to Source Ratio per center frequency */ - float acousticPreDelay; /* Time elapsed between input signal and late reverberation start, float, range [0.001..10] */ - float inputPreDelay; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ Word32 pFc_input_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q16 Center frequencies for which following values are provided: */ Word32 pAcoustic_rt60_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q26 - The room's T60 per center frequency */ Word32 pAcoustic_dsr_fx[IVAS_CLDFB_NO_CHANNELS_MAX]; /*Q30 - The room's Diffuse to Source Ratio per center frequency */ diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 3a7c42aae62ee0ac5573346858eea6add52dd460..7ed8780cf24f3eb21512baaa72779b532175895c 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1114,35 +1114,21 @@ void ivas_reverb_calc_color_levels_fx( const Word32 *pT60_filter_coeff, //input in Q31 Word32 *pTarget_color_L, //output in Q30 Word32 *pTarget_color_R); //output in Q30 + ivas_error ivas_reverb_prepare_cldfb_params( const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, const HRTFS_STATISTICS_HANDLE hHrtfStatistics, - const int32_t output_Fs, - float *pOutput_t60, - float *pOutput_ene ); -void ivas_reverb_interpolate_acoustic_data_fx( - const Word16 input_table_size, - const Word32 *pInput_fc, //input in Q16 - const Word32 *pInput_t60, //input in Q26 - const Word32 *pInput_dsr, //input in Q30 - const Word16 output_table_size, - const Word32 *pOutput_fc, - Word32 *pOutput_t60, - Word32 *pOutput_dsr, - Word16 *pOutput_t60_e, //output e - Word16 *pOutput_dsr_e //output e -); -void ivas_reverb_interpolate_energies_fx( + const Word32 output_Fs, + Word32 *pOutput_t60, + Word32 *pOutput_ene ); + +void ivas_reverb_interp_on_freq_grid_fx( const Word16 input_table_size, - const Word32 *pInput_fc, //input in Q16 - const Word32 *pInput_ene_l, //input in Q28 - const Word32 *pInput_ene_r, //input in Q28 + const Word32 *pInput_fc, //input center frequencies in Q16 + const Word32 *pInput_grid, //input data vector in an arbitrary Q-format const Word16 output_table_size, const Word32 *pOutput_fc, - Word32 *pOutput_ene_l_m, // output m - Word32 *pOutput_ene_r_m, // output m - Word16 *pOutput_ene_l_e, //output e - Word16 *pOutput_ene_r_e //output e + Word32 *pOutput_grid //output in the same Q-format as input ); /*---------------------------------------------------------------------------------* * Shoebox Prototypes diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 900a90dcaa41a3177652676449edd938f391c03a..e826596ba7b686df5683cee85499ded94bbf2265 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -671,7 +671,7 @@ void ivas_reverb_calc_color_levels_fx( const Word32 output_Fs, const Word16 freq_count, const Word16 loop_count, - const Word32 *pFc, // input in Q14 + const Word32 *pFc, // input in Q16 const Word32 *pAcoustic_dsr, // input in Q31 const Word32 *pHrtf_avg_pwr_L, // input in Q28 const Word32 *pHrtf_avg_pwr_R, // input in Q28 @@ -689,8 +689,8 @@ void ivas_reverb_calc_color_levels_fx( /* Pre-computing inverse values for optimisation (to avoid divisions in inner loops) */ Word16 fs_inverted_q; - const Word32 fs_inverted = BASOP_Util_Divide3232_Scale( ONE_IN_Q11, L_shl( output_Fs, 11 ), &fs_inverted_q ); // q= 15 - fs_inverted_q = 29 - const Word32 loop_count_inverted = divide3232( ONE_IN_Q27, L_shl( loop_count, 27 ) ); // q= 15; + const Word32 fs_inverted = BASOP_Util_Divide3232_Scale( ONE_IN_Q11, L_shl( output_Fs, 11 ), &fs_inverted_q ); // q= 15 - fs_inverted_q = 29//Q29 + const Word32 loop_count_inverted = divide3232( ONE_IN_Q27, L_shl( loop_count, 27 ) ); // q= 15;Q15 const Word32 log__0_001 = -1854286438; // logf( 0.001f ) in q28 move32(); @@ -740,7 +740,7 @@ void ivas_reverb_calc_color_levels_fx( Word16 temp = 0, result_e = 0; move16(); move16(); - cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 + cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 1 ) ) ); // q = 15 H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28 H_filter = BASOP_Util_Divide3232_Scale_newton( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp ); H_filter = Sqrt32( H_filter, &temp ); @@ -839,135 +839,49 @@ void ivas_reverb_calc_color_levels_fx( } /*-------------------------------------------------------------------* - * ivas_reverb_interpolate_acoustic_data_fx() + * ivas_reverb_interp_on_freq_grid_fx() * - * Interpolates data from the input T60 and DSR tables to the FFT pFilter uniform grid + * Interpolates data from an input grid of center frequencies to an output grid of center frequencies * Note: the fc frequencies both for the input and the output must be in the ascending order *-------------------------------------------------------------------*/ - - -void ivas_reverb_interpolate_acoustic_data_fx( - const Word16 input_table_size, - const Word32 *pInput_fc, // input in Q16 - const Word32 *pInput_t60, // input in Q26 - const Word32 *pInput_dsr, // input in Q30 - const Word16 output_table_size, - const Word32 *pOutput_fc, // Q16 - Word32 *pOutput_t60, // pOutput_t60_e - Word32 *pOutput_dsr, // pOutput_dsr_e - Word16 *pOutput_t60_e, // output e - Word16 *pOutput_dsr_e // output e +void ivas_reverb_interp_on_freq_grid_fx( + const Word16 input_grid_size, + const Word32 *pInput_fc, // input center frequencies in Q16 + const Word32 *pInput_data, // input data vector in an arbitrary Q-format + const Word16 output_grid_size, + const Word32 *pOutput_fc, + Word32 *pOutput_data // output data vector in the same Q-format as input ) { - Word16 input_idx, output_idx; + Word16 input_idx, input_idx_next, output_idx; Word32 rel_offset; Word16 rel_offset_e; input_idx = 0; + input_idx_next = 0; move16(); - - FOR( output_idx = 0; output_idx < output_table_size; output_idx++ ) - { - /* if the bin frequency is lower than the 1st frequency point in the input table, take this 1st point */ - IF( LT_32( pOutput_fc[output_idx], pInput_fc[0] ) ) - { - input_idx = 0; - move16(); - rel_offset = 0; - move32(); - rel_offset_e = 0; - move16(); - } - ELSE - { - /* if the bin frequency is higher than the last frequency point in the input table, take this last point */ - IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_table_size - 1] ) ) - { - input_idx = sub( input_table_size, 2 ); - rel_offset = ONE_IN_Q30; // Q30; - move32(); - rel_offset_e = 1; - move16(); - } - /* otherwise use linear interpolation between 2 consecutive points in the input table */ - ELSE - { - WHILE( GT_32( pOutput_fc[output_idx], pInput_fc[input_idx + 1] ) ) - { - input_idx = add( input_idx, 1 ); - } - rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx + 1], pInput_fc[input_idx] ), &rel_offset_e ); // q15 - rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) ); - rel_offset_e = 0; - move16(); - } - } - Word32 mult1; - Word16 mult_e = 0; - move16(); - mult1 = Mpy_32_32( rel_offset, L_sub( pInput_t60[input_idx + 1], pInput_t60[input_idx] ) ); - pOutput_t60[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_t60[input_idx], 5, mult1, add( 5, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 26 - 31) - move32(); - pOutput_t60_e[output_idx] = mult_e; - move16(); - - mult1 = Mpy_32_32( rel_offset, L_sub( pInput_dsr[input_idx + 1], pInput_dsr[input_idx] ) ); - pOutput_dsr[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_dsr[input_idx], 1, mult1, add( 1, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 26 - 31) - move32(); - pOutput_dsr_e[output_idx] = mult_e; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * ivas_reverb_interpolate_energies_fx() - * - * Interpolates data from the input average energy to the FFT pFilter uniform grid - * Note: the fc frequencies both for the input and the output must be in the ascending order - *-------------------------------------------------------------------*/ - - -void ivas_reverb_interpolate_energies_fx( - const Word16 input_table_size, - const Word32 *pInput_fc, // input in Q16 - const Word32 *pInput_ene_l, // input in Q28 - const Word32 *pInput_ene_r, // input in Q28 - const Word16 output_table_size, - const Word32 *pOutput_fc, // Q16 - Word32 *pOutput_ene_l_m, - Word32 *pOutput_ene_r_m, - Word16 *pOutput_ene_l_e, - Word16 *pOutput_ene_r_e ) -{ - Word16 input_idx, output_idx; - Word32 rel_offset; - Word16 rel_offset_e; - input_idx = 0; move16(); - FOR( output_idx = 0; output_idx < output_table_size; output_idx++ ) + FOR( output_idx = 0; output_idx < output_grid_size; output_idx++ ) { /* if the bin frequency is lower than the 1st frequency point in the input table, take this 1st point */ IF( LT_32( pOutput_fc[output_idx], pInput_fc[0] ) ) { input_idx = 0; move16(); + input_idx_next = 0; + move16(); rel_offset = 0; move32(); - rel_offset_e = 0; - move16(); } ELSE { /* if the bin frequency is higher than the last frequency point in the input table, take this last point */ - IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_table_size - 1] ) ) + IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_grid_size - 1] ) ) { - input_idx = sub( input_table_size, 2 ); - rel_offset = ONE_IN_Q30; // Q30; + input_idx = sub( input_grid_size, 2 ); + input_idx_next = add( input_idx, 1 ); + rel_offset = ONE_IN_Q31; move32(); - rel_offset_e = 1; - move16(); } /* otherwise use linear interpolation between 2 consecutive points in the input table */ ELSE @@ -976,26 +890,13 @@ void ivas_reverb_interpolate_energies_fx( { input_idx = add( input_idx, 1 ); } - rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx + 1], pInput_fc[input_idx] ), &rel_offset_e ); // q15 - rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) ); - rel_offset_e = 0; - move16(); + input_idx_next = add( input_idx, 1 ); + rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx_next], pInput_fc[input_idx] ), &rel_offset_e ); // Q15 + rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) ); // Q31 } } - Word32 mult1; - Word16 mult_e = 0; - move16(); - mult1 = Mpy_32_32( rel_offset, L_sub( pInput_ene_l[input_idx + 1], pInput_ene_l[input_idx] ) ); - pOutput_ene_l_m[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_ene_l[input_idx], 3, mult1, add( 3, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 28 - 31) - move32(); - pOutput_ene_l_e[output_idx] = mult_e; - move16(); - mult1 = Mpy_32_32( rel_offset, L_sub( pInput_ene_r[input_idx + 1], pInput_ene_r[input_idx] ) ); - pOutput_ene_r_m[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_ene_r[input_idx], 3, mult1, add( 3, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 28 - 31) - move32(); - pOutput_ene_r_e[output_idx] = mult_e; - move16(); + pOutput_data[output_idx] = L_add( pInput_data[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_data[input_idx_next], pInput_data[input_idx] ) ) ); } return; diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 31141a1efd531d55a4fbb07ab0449852c9e31933..8d54c39ff5d930c93089e3143c167a6c59f188f9 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -40,9 +40,6 @@ #include #include "wmc_auto.h" #include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) static Word16 wrap_rad_fixed( Word32 angle /* Q13 */ ) @@ -123,24 +120,14 @@ typedef struct ivas_reverb_params_t /* Currently this is fixed to 2. */ /* Mix [S][L] matrix from feedback loops to outputs. */ Word16 pLoop_extract_matrix_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES]; /* Mix [S][L] matrix from feedback loops to outputs. */ /* In Matlab: [S x L] - Currently S=2, later may be more than 2 for speaker playback. */ Word16 t60_filter_order; /* Filter order (length of vector) */ - // float pT60_filter_coeff[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH]; /* Filters [][] in feedback loops, controlling T60. */ Word16 pT60_filter_coeff_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH]; /* In Matlab: IIR: [(2 * L) x ( + 1)] (odd: b-vector, even: a-vector) */ /* In Matlab: FIR: [L x ] */ - // float *pFc; /* Center frequencies for FFT filter design */ - // float *pRt60; /* RT60 values at these frequencies */ - // float *pDsr; /* DSR values at these frequencies */ Word32 *pFc_fx; /* Center frequencies for FFT filter design */ Word32 *pRt60_fx; /* RT60 values at these frequencies */ Word16 *pRt60_e; /* exponents for RT60 values at these frequencies */ Word32 *pDsr_fx; /* DSR values at these frequencies */ Word16 *pDsr_e; /* DSR values at these frequencies */ - // float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */ - // float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */ - // float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */ - // const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */ - // const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */ - // const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */ #ifndef FIX_1053_REVERB_RECONFIGURATION Word32 *pHrtf_avg_pwr_response_l_fx; /* The HRTF set's average left ear power response */ Word32 *pHrtf_avg_pwr_response_r_fx; /* The HRTF set's average right ear power response */ @@ -585,7 +572,7 @@ static ivas_error set_base_config_fx( *-----------------------------------------------------------------------------------------*/ static Word32 calc_dmx_gain_fx( void ) { - const Word32 gain = DMX_GAIN; // Q25 + const Word32 gain = DMX_GAIN; // Q23 move32(); return gain; } @@ -639,55 +626,58 @@ static ivas_error compute_t60_coeffs_fx( Word16 bin_idx, loop_idx, tf_T60_len, len; ivas_error error; - Word16 loop_delay_sec_fx, norm_f_e, tmp; + Word16 loop_delay_sec_fx, tmp; Word32 freq_Nyquist_fx = L_shr( output_Fs, 1 ); - Word16 target_gains_db_fx[RV_LENGTH_NR_FC]; + Word16 target_gains_db_fx[RV_LENGTH_NR_FC]; // Q8 Word16 norm_f_fx[RV_LENGTH_NR_FC]; - Word32 *targetT60_fx, *pFc_fx; - Word16 *pCoeffs_a_fx, *pCoeffs_b_fx, *targetT60_e; - Word16 target_gains_db_exp[RV_LENGTH_NR_FC]; + Word16 *pCoeffs_a_fx, *pCoeffs_b_fx; + Word16 e; + const Word16 min120q8 = -30720; // -120 in Q8 + error = IVAS_ERR_OK; move32(); tf_T60_len = nr_fc_fft_filter; move16(); len = add( pParams->t60_filter_order, 1 ); - pFc_fx = pParams->pFc_fx; - targetT60_fx = pParams->pRt60_fx; - targetT60_e = pParams->pRt60_e; - move16(); - FOR( bin_idx = 0; bin_idx < tf_T60_len; bin_idx++ ) { - norm_f_fx[bin_idx] = BASOP_Util_Divide3232_Scale( pFc_fx[bin_idx], freq_Nyquist_fx, &norm_f_e ); + norm_f_fx[bin_idx] = BASOP_Util_Divide3232_Scale( pParams->pFc_fx[bin_idx], freq_Nyquist_fx, &e ); move16(); - norm_f_e = add( norm_f_e, sub( 17, 31 ) ); - norm_f_fx[bin_idx] = shl( norm_f_fx[bin_idx], sub( norm_f_e, 1 ) ); // making Q14 + e = add( e, sub( 15, 31 ) ); + norm_f_fx[bin_idx] = shl( norm_f_fx[bin_idx], sub( e, 1 ) ); // making Q14 move16(); } FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ ) { - - Word16 loop_delay_sec_fx_exp; - loop_delay_sec_fx = BASOP_Util_Divide3232_Scale( pParams->pLoop_delays[loop_idx], output_Fs, &loop_delay_sec_fx_exp ); + loop_delay_sec_fx = BASOP_Util_Divide3232_Scale( pParams->pLoop_delays[loop_idx], output_Fs, &e ); + loop_delay_sec_fx = shl( loop_delay_sec_fx, e ); // Q15 FOR( bin_idx = 0; bin_idx < tf_T60_len; bin_idx++ ) { - tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), targetT60_fx[bin_idx], &target_gains_db_exp[bin_idx] ); - target_gains_db_exp[bin_idx] = add( target_gains_db_exp[bin_idx], sub( loop_delay_sec_fx_exp, targetT60_e[bin_idx] ) ); - move16(); - target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720 - move16(); - target_gains_db_exp[bin_idx] = add( target_gains_db_exp[bin_idx], 6 ); // Q9 -> e6 - move16(); - - tmp = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( target_gains_db_fx[bin_idx] ), target_gains_db_exp[bin_idx], -2013265920, 7 ); - IF( tmp < 0 ) + IF( EQ_32( pParams->pRt60_fx[bin_idx], 0 ) ) { - target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720 - move16(); - target_gains_db_exp[bin_idx] = 7; + // If RT60 is 0, target gain is -120dB + target_gains_db_fx[bin_idx] = min120q8; + } + ELSE + { + tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), pParams->pRt60_fx[bin_idx], &e ); + IF( LT_16( e, -1 ) ) + { + target_gains_db_fx[bin_idx] = min120q8; + } + ELSE + { + tmp = shr( tmp, sub( 5, e ) ); // scaling tmp to Q15 + target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 + } + } + // gain < - 120 ? -120: gain + IF( LT_16( target_gains_db_fx[bin_idx], -30720 ) ) + { + target_gains_db_fx[bin_idx] = -30720; move16(); } } @@ -695,19 +685,9 @@ static ivas_error compute_t60_coeffs_fx( pCoeffs_a_fx = &pParams->pT60_filter_coeff_fx[add( shl( i_mult( len, loop_idx ), 1 ), len )]; // Q14 pCoeffs_b_fx = &pParams->pT60_filter_coeff_fx[shl( i_mult( len, loop_idx ), 1 )]; // Q14 - Word16 val = target_gains_db_exp[0]; move16(); - FOR( Word16 i = 1; i < nr_fc_fft_filter; i++ ) - { - val = s_max( val, target_gains_db_exp[i] ); - } - - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) - { - target_gains_db_fx[i] = shr( target_gains_db_fx[i], sub( val, target_gains_db_exp[i] ) ); - move16(); - } + Word16 val = 7; IF( NE_32( ( error = calc_jot_t60_coeffs_fx( target_gains_db_fx, val, tf_T60_len, norm_f_fx, pCoeffs_a_fx, pCoeffs_b_fx, extract_l( freq_Nyquist_fx ) ) ), IVAS_ERR_OK ) ) { @@ -1270,10 +1250,10 @@ static void set_reverb_acoustic_data_fx( const Word16 nr_fc_input, const Word16 nr_fc_fft_filter ) { - int16_t bin_idx; + Word16 bin_idx; Word32 ln_1e6_inverted_fx, delay_diff_fx, L_tmp; - Word16 exp_argument_fx, tmp, tmp_flag, exp_argument_e; - Word16 pow_exp; + Word32 exp_argument_fx, tmp; + Word16 pow_exp, exp_argument_e; Word32 *pFc_input_fx = pRoomAcoustics->pFc_input_fx; Word32 *pAcoustic_rt60_fx = pRoomAcoustics->pAcoustic_rt60_fx; @@ -1281,63 +1261,45 @@ static void set_reverb_acoustic_data_fx( Word32 *pFc_fx = pParams->pFc_fx; Word32 *pRt60_fx = pParams->pRt60_fx; - Word16 *pRt60_e = pParams->pRt60_e; Word32 *pDsr_fx = pParams->pDsr_fx; - Word16 *pDsr_e = pParams->pDsr_e; /* interpolate input table data for T60 and DSR to the FFT filter grid */ - ivas_reverb_interpolate_acoustic_data_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, pAcoustic_dsr_fx, - nr_fc_fft_filter, pFc_fx, pRt60_fx, pDsr_fx, pRt60_e, pDsr_e ); - /* adjust DSR for the delay difference */ + ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, nr_fc_fft_filter, pFc_fx, pRt60_fx ); // Q26 + ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_dsr_fx, nr_fc_fft_filter, pFc_fx, pDsr_fx ); // Q30 + + ///* adjust DSR for the delay difference */ - delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); + delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); // Q27 ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ move32(); FOR( bin_idx = 0; bin_idx < nr_fc_fft_filter; bin_idx++ ) { - L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // exp = pRt60_e[bin_idx] + 0 - exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e ); - exp_argument_e = add( exp_argument_e, sub( 4, pRt60_e[bin_idx] ) ); // Q27 -> e4 - /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ + L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // Q26 - // 23 in Q26 - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 1543503872, 5 ); - IF( tmp_flag > 0 ) + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &exp_argument_e ); + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, exp_argument_e ) ); // Q26 + + /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ + IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 { - exp_argument_fx = 23552; - move16(); - exp_argument_e = 5; - move16(); + exp_argument_fx = 1543503872; } - - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); - IF( tmp_flag < 0 ) + IF( LT_32( exp_argument_fx, -1543503872 ) ) // 23 in Q26 { - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( negate( exp_argument_fx ) ), exp_argument_e, 1543503872, 5 ); - IF( tmp_flag < 0 ) - { - exp_argument_fx = -23552; - move16(); - exp_argument_e = 5; - move16(); - } + exp_argument_fx = -1543503872; } - Word16 tmp_exp; - /* expf(exp_argument) -> pow(2, log2(e) * exp_argument) */ - tmp = mult( 23637, exp_argument_fx ); // exp_argument_e + 1 - tmp_exp = add( exp_argument_e, 1 ); - L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp ); + tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 + + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); - tmp_exp = add( pow_exp, pDsr_e[bin_idx] ); + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31 pDsr_fx[bin_idx] = L_tmp; move32(); - pDsr_e[bin_idx] = tmp_exp; - move16(); } return; } @@ -1429,7 +1391,7 @@ ivas_error ivas_reverb_open_fx( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ RENDER_CONFIG_HANDLE hRenderConfig, /* i : Renderer configuration handle */ - const int32_t output_Fs ) + const Word32 output_Fs ) { ivas_error error; #ifdef FIX_1053_REVERB_RECONFIGURATION @@ -1537,28 +1499,15 @@ ivas_error ivas_reverb_open_fx( freq_step_fx = L_mult0( extract_l( L_shr( output_Fs, 2 ) ), div_s( 1, ( nr_fc_fft_filter - 1 ) ) ); /*Q14:0.5f * output_Fs / ( nr_fc_fft_filter - 1 )*/ FOR( bin_idx = 0; bin_idx < nr_fc_fft_filter; bin_idx++ ) { - params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q14*/ + params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q16*/ } test(); /* set up reverb acoustic data on the basis of HRTF data and renderer config */ Scale_sig32( params.pFc_fx, nr_fc_fft_filter, 2 ); - Word16 *pRt60_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter ); - Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter ); - - params.pRt60_e = pRt60_e; - params.pDsr_e = pDsr_e; set_reverb_acoustic_data_fx( ¶ms, &hRenderConfig->roomAcoustics, nr_fc_input, nr_fc_fft_filter ); - Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 ); - FOR( i = 0; i < nr_fc_fft_filter; i++ ) - { - params.pRt60_fx[i] = L_abs( params.pRt60_fx[i] ); - move32(); - params.pDsr_fx[i] = L_abs( params.pDsr_fx[i] ); - move32(); - } params.pHrtf_avg_pwr_response_l_const_fx = hHrtfStatistics->average_energy_l; params.pHrtf_avg_pwr_response_r_const_fx = hHrtfStatistics->average_energy_r; @@ -1608,8 +1557,6 @@ ivas_error ivas_reverb_open_fx( FOR( i = 0; i < nr_fc_fft_filter; i++ ) { - params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] ); - move32(); pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ move32(); pHrtf_avg_pwr_response_r_const[i] = params.pHrtf_avg_pwr_response_r_const_fx[i]; /*Q23+5*/ @@ -1681,7 +1628,7 @@ ivas_error ivas_reverb_open_fx( Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) ); FOR( i = 0; i < nr_fc_fft_filter; i++ ) { - pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 3 ); /*Scaling up to Q30*/ + pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 4 ); /*Scaling up to Q30*/ move32(); } ivas_reverb_calc_correl_filters_fx( pHrtf_inter_aural_coherence_const, pTime_window_fx, pState->fft_size, pFft_wf_filter_ch0_fx, pFft_wf_filter_ch1_fx, &q_pFft_wf_filter_ch0_fx, &q_pFft_wf_filter_ch1_fx ); @@ -1690,16 +1637,16 @@ ivas_error ivas_reverb_open_fx( FOR( i = 0; i < nr_fc_fft_filter; i++ ) { - pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); + pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); // Scale to Q31 move32(); - pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); + pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); // Scale to Q31 move32(); } FOR( i = 0; i < nr_fc_fft_filter; i++ ) { - pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); + pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); // Scale to Q31 move32(); - pFft_wf_filter_ch1_fx[i][1] = L_shl( pFft_wf_filter_ch1_fx[i][1], sub( 31, q_pFft_wf_filter_ch1_fx ) ); + pFft_wf_filter_ch1_fx[i][1] = L_shl( pFft_wf_filter_ch1_fx[i][1], sub( 31, q_pFft_wf_filter_ch1_fx ) ); // Scale to Q31 move32(); } /* Copying the computed FFT correlation filters to the fft_filter components */ @@ -2524,21 +2471,16 @@ ivas_error ivas_binaural_reverb_init( if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) { - float t60_temp[CLDFB_NO_CHANNELS_MAX]; - float ene_temp[CLDFB_NO_CHANNELS_MAX]; - revTimes = t60; revEne = ene; - if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60_temp, ene_temp ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) { return error; } temp32 = Mult_32_16( roomAcoustics->acousticPreDelay_fx, ( ( IVAS_48k / CLDFB_NO_CHANNELS_MAX ) >> 1 ) ); // Q11 preDelay = extract_l( L_shr( L_add( temp32, L_shl( 1, 10 ) ), 11 ) ); // Q0 - floatToFixed_arrL( t60_temp, t60, Q26, CLDFB_NO_CHANNELS_MAX ); - floatToFixed_arrL( ene_temp, ene, Q31, CLDFB_NO_CHANNELS_MAX ); } else { diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index c20e0b6701f8658a8a654e9ebd27bc8e377340df..553dbdb0a4409e137550bc7cbeee67f655ac39a6 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -43,28 +43,13 @@ * Local constants *-----------------------------------------------------------------------------------------*/ -#define DEFAULT_SRC_DIST ( 1.5f ) /* default source distance [m] for reverb dmx factor computing */ -#define MAX_SAMPLING_RATE ( 48000 ) -#define CLDFB_CONVOLVER_NTAPS_MAX ( 16 ) -#define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) ) - -#define N_INITIAL_IGNORED_FRAMES 4 +#define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) ) /*-----------------------------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------------------------*/ -typedef struct cldfb_convolver_state -{ - const float *filter_taps_left_re[CLDFB_NO_CHANNELS_MAX]; - const float *filter_taps_left_im[CLDFB_NO_CHANNELS_MAX]; - const float *filter_taps_right_re[CLDFB_NO_CHANNELS_MAX]; - const float *filter_taps_right_im[CLDFB_NO_CHANNELS_MAX]; - float filter_states_re[BINAURAL_CONVBANDS][CLDFB_CONVOLVER_NTAPS_MAX]; - float filter_states_im[BINAURAL_CONVBANDS][CLDFB_CONVOLVER_NTAPS_MAX]; -} cldfb_convolver_state; - -static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, const int32_t sampling_rate, float *avg_pwr_l_out, float *avg_pwr_r_out ); +static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, const Word32 sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out ); /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_prepare_cldfb_params() @@ -72,59 +57,80 @@ static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg * Prepares reverb parameters for CLDFB-based reverberator *-----------------------------------------------------------------------------------------*/ - ivas_error ivas_reverb_prepare_cldfb_params( const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, const HRTFS_STATISTICS_HANDLE hHrtfStatistics, - const int32_t output_Fs, - float *pOutput_t60, - float *pOutput_ene ) + const Word32 output_Fs, + Word32 *pOutput_t60, + Word32 *pOutput_ene ) { - int16_t idx; - float avg_pwr_left[CLDFB_NO_CHANNELS_MAX]; - float avg_pwr_right[CLDFB_NO_CHANNELS_MAX]; - float delay_diff, ln_1e6_inverted, exp_argument; - const float dist = DEFAULT_SRC_DIST; - const float dmx_gain_2 = 4.0f * EVS_PI * dist * dist / 0.001f; + Word16 idx; + Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 output_t60_e[CLDFB_NO_CHANNELS_MAX]; Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 output_ene_e[CLDFB_NO_CHANNELS_MAX]; - Word32 delay_diff_fx; - for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp; + const Word32 dmx_gain_2_fx = 1852986624; // Q16 + const Word32 cldfb_band_width = 26214400; // 400 in Q16 + Word16 pow_exp, tmp_exp; + Word32 tmp, exp_argument_fx; + + Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; + + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - output_fc_fx[idx] = (Word32) ( ( idx + 0.5f ) * ( MAX_SAMPLING_RATE / ( 2 * CLDFB_NO_CHANNELS_MAX ) ) ) * ONE_IN_Q16; + output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) ); } - ivas_reverb_interpolate_acoustic_data_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, pInput_params->pAcoustic_dsr_fx, - CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx, output_ene_fx, output_t60_e, output_ene_e ); + ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx ); // Q26 + ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_ene_fx ); // Q30 /* adjust DSR for the delay difference */ - delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); + delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); // Q27 - delay_diff = (float) delay_diff_fx / ONE_IN_Q27; - for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) ); - pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) ); - } + ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ - ln_1e6_inverted = 1.0f / logf( 1e06f ); - for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - exp_argument = delay_diff / ( pOutput_t60[idx] * ln_1e6_inverted ); + L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // Q26 + + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp ); + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); // Q26 + /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ - exp_argument = min( exp_argument, 23.0f ); - exp_argument = max( exp_argument, -23.0f ); - pOutput_ene[idx] *= expf( exp_argument ); + IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 + { + exp_argument_fx = 1543503872; + } + IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26 + { + exp_argument_fx = -1543503872; + } + + tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 + + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); + L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31 + + pOutput_ene[idx] = L_tmp; // Q31 + move32(); + + pOutput_t60[idx] = output_t60_fx[idx]; // Q26 } - ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left, avg_pwr_right ); - for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); // Q28 + + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - pOutput_ene[idx] *= 0.5f * ( avg_pwr_left[idx] + avg_pwr_right[idx] ) * dmx_gain_2; + Word32 tmp_ene; + + tmp_ene = L_shr( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ), 1 ); // Q28 + tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Q13 + pOutput_ene[idx] = Mpy_32_32( pOutput_ene[idx], tmp_ene ); // Q13 + pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); // Q31 } return IVAS_ERR_OK; @@ -141,41 +147,40 @@ ivas_error ivas_reverb_prepare_cldfb_params( static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, - const int32_t sampling_rate, - float *avg_pwr_left, - float *avg_pwr_right ) + const Word32 sampling_rate, + Word32 *avg_pwr_left, + Word32 *avg_pwr_right ) { - int16_t freq_idx; - float input_fc[FFT_SPECTRUM_SIZE]; + Word16 freq_idx; Word32 input_fc_fx[FFT_SPECTRUM_SIZE]; Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; - Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 avg_pwr_left_e[CLDFB_NO_CHANNELS_MAX]; - Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; - Word16 avg_pwr_right_e[CLDFB_NO_CHANNELS_MAX]; - const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); + Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; // Q28 + Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; // Q28 + const Word32 cldfb_band_width = 26214400; // 400 in Q16 + Word16 s; + Word16 temp; + const Word16 avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; + temp = BASOP_Util_Divide3216_Scale( sampling_rate, sub( avg_pwr_len, 1 ), &s ); - const int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; - - for ( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ ) + FOR( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ ) { - input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); - input_fc_fx[freq_idx] = (Word16) ( input_fc[freq_idx] * ONE_IN_Q16 + 0.5f ); + input_fc_fx[freq_idx] = L_shl( L_mult( temp, freq_idx ), add( 15, s ) ); } - for ( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) + FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) { - output_fc_fx[freq_idx] = ( ( freq_idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; + output_fc_fx[freq_idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, freq_idx ), 15 ) ); } + // Avg Energy Left + ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_l, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx ); + // Avg Energy Right + ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_r, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_right_fx ); - ivas_reverb_interpolate_energies_fx( avg_pwr_len, input_fc_fx, avg_pwr_l, avg_pwr_r, - CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx, avg_pwr_right_fx, avg_pwr_left_e, avg_pwr_right_e ); - - for ( int i = 0; i < 60; i++ ) + FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) { - avg_pwr_left[i] = (float) fabs( me2f( avg_pwr_left_fx[i], avg_pwr_left_e[i] ) ); - avg_pwr_right[i] = (float) fabs( me2f( avg_pwr_right_fx[i], avg_pwr_right_e[i] ) ); + avg_pwr_left[freq_idx] = avg_pwr_left_fx[freq_idx]; + avg_pwr_right[freq_idx] = avg_pwr_right_fx[freq_idx]; } } diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 304190f07842d6467c0d149b1f4cb165b7f0b09e..db4d22b6373804bbfd9a38a4e9c13fa9e2ee4359 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1216,46 +1216,21 @@ ivas_error RenderConfigReader_checkValues( return IVAS_ERR_WRONG_PARAMS; } - /* Verify input pre-delay value */ - if ( ( pRoom_acoustics->inputPreDelay > INPUTPREDELAY_MAX ) || ( pRoom_acoustics->inputPreDelay < INPUTPREDELAY_MIN ) ) - { - return IVAS_ERR_WRONG_PARAMS; - } - /* Verify data per band in the acoustic properties table */ for ( band_idx = 0; band_idx < pRoom_acoustics->nBands; band_idx++ ) { /* Verify if the frequencies are in the ascending order (required for interpolation) */ if ( band_idx != 0 ) { - if ( pRoom_acoustics->pFc_input[band_idx] <= pRoom_acoustics->pFc_input[band_idx - 1] ) + if ( pRoom_acoustics->pFc_input_fx[band_idx] <= pRoom_acoustics->pFc_input_fx[band_idx - 1] ) { tab_value_err_count++; } } - /* Check the input frequencies */ - if ( ( pRoom_acoustics->pFc_input[band_idx] > FC_INPUT_MAX ) || ( pRoom_acoustics->pFc_input[band_idx] < FC_INPUT_MIN ) ) - { - tab_value_err_count++; - } - - /* Check the input RT60 values */ - if ( ( pRoom_acoustics->pAcoustic_rt60[band_idx] > ACOUSTIC_RT60_MAX ) || ( pRoom_acoustics->pAcoustic_rt60[band_idx] < ACOUSTIC_RT60_MIN ) ) - { - tab_value_err_count++; - } - - /* Check the input DSR values */ - if ( ( pRoom_acoustics->pAcoustic_dsr[band_idx] > ACOUSTIC_DSR_MAX ) || ( pRoom_acoustics->pAcoustic_dsr[band_idx] < ACOUSTIC_DSR_MIN ) ) - { - tab_value_err_count++; - } - /* Replace zero DSR values with very small positive values, to avoid issues with coloration filter design */ - if ( pRoom_acoustics->pAcoustic_dsr[band_idx] <= 0.0f ) + if ( pRoom_acoustics->pAcoustic_dsr_fx[band_idx] == 0 ) { - pRoom_acoustics->pAcoustic_dsr[band_idx] = ACOUSTIC_DSR_EPSILON; pRoom_acoustics->pAcoustic_dsr_fx[band_idx] = ACOUSTIC_DSR_EPSILON_FX; } } @@ -2354,11 +2329,12 @@ ivas_error RenderConfigReader_read( /* Acoustic pre-delay */ else if ( strcmp( item, "ACOUSTICPREDELAY" ) == 0 ) { - if ( !sscanf( pValue, "%f", &hRenderConfig->roomAcoustics.acousticPreDelay ) ) + float f; + if ( !sscanf( pValue, "%f", &f ) ) { errorHandler( item, ERROR_VALUE_INVALID ); } - hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( hRenderConfig->roomAcoustics.acousticPreDelay * ONE_IN_Q27 ); + hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( f * ONE_IN_Q27 ); } /* Pre-delay */ else if ( strcmp( item, "PREDELAY" ) == 0 ) @@ -2828,13 +2804,24 @@ ivas_error RenderConfigReader_getAcousticEnvironment( if ( id == pRenderConfigReader->pAE[n].id ) { pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands; - pAcEnv->inputPreDelay = pRenderConfigReader->pAE[n].preDelay; pAcEnv->inputPreDelay_fx = (Word32) ( pRenderConfigReader->pAE[n].preDelay * ONE_IN_Q27 ); + if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || + pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } for ( m = 0; m < pAcEnv->nBands; m++ ) { - pAcEnv->pFc_input[m] = pRenderConfigReader->pAE[n].pFG->pFc[m]; - pAcEnv->pAcoustic_rt60[m] = pRenderConfigReader->pAE[n].pRT60[m]; - pAcEnv->pAcoustic_dsr[m] = pRenderConfigReader->pAE[n].pDSR[m]; + if ( pRenderConfigReader->pAE[n].pFG->pFc[m] > FC_INPUT_MAX || + pRenderConfigReader->pAE[n].pFG->pFc[m] < FC_INPUT_MIN || + pRenderConfigReader->pAE[n].pRT60[m] > ACOUSTIC_RT60_MAX || + pRenderConfigReader->pAE[n].pRT60[m] < ACOUSTIC_RT60_MIN || + pRenderConfigReader->pAE[n].pDSR[m] > ACOUSTIC_DSR_MAX || + pRenderConfigReader->pAE[n].pDSR[m] < ACOUSTIC_DSR_MIN ) + { + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + pAcEnv->pFc_input_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pFG->pFc[m] * ONE_IN_Q16 ); pAcEnv->pAcoustic_rt60_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pRT60[m] * ONE_IN_Q26 ); pAcEnv->pAcoustic_dsr_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pDSR[m] * ONE_IN_Q30 );