Loading lib_com/common_api_types.h +0 −5 Original line number Diff line number Diff line Loading @@ -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 */ Loading lib_rend/ivas_prot_rend_fx.h +9 −23 Original line number Diff line number Diff line Loading @@ -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, const Word32 output_Fs, Word32 *pOutput_t60, Word32 *pOutput_dsr, Word16 *pOutput_t60_e, //output e Word16 *pOutput_dsr_e //output e ); void ivas_reverb_interpolate_energies_fx( 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 Loading lib_rend/ivas_reverb_filter_design_fx.c +26 −125 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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 ); Loading Loading @@ -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 Loading @@ -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; Loading lib_rend/ivas_reverb_fx.c +63 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes lib_rend/ivas_reverb_utils_fx.c +78 −73 Original line number Diff line number Diff line Loading @@ -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 /*-----------------------------------------------------------------------------------------* * 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() Loading @@ -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; Loading @@ -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 int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; 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 ); 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]; } } Loading
lib_com/common_api_types.h +0 −5 Original line number Diff line number Diff line Loading @@ -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 */ Loading
lib_rend/ivas_prot_rend_fx.h +9 −23 Original line number Diff line number Diff line Loading @@ -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, const Word32 output_Fs, Word32 *pOutput_t60, Word32 *pOutput_dsr, Word16 *pOutput_t60_e, //output e Word16 *pOutput_dsr_e //output e ); void ivas_reverb_interpolate_energies_fx( 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 Loading
lib_rend/ivas_reverb_filter_design_fx.c +26 −125 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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 ); Loading Loading @@ -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 Loading @@ -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; Loading
lib_rend/ivas_reverb_fx.c +63 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes
lib_rend/ivas_reverb_utils_fx.c +78 −73 Original line number Diff line number Diff line Loading @@ -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 /*-----------------------------------------------------------------------------------------* * 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() Loading @@ -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; Loading @@ -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 int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; 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 ); 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]; } }