From bbb30d9157b05870fe3104c891981c8c7d645775 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 16 Jul 2025 17:29:53 +0200 Subject: [PATCH 01/43] mid stage changes --- lib_rend/ivas_prot_rend_fx.h | 10 +- lib_rend/ivas_reverb_filter_design_fx.c | 56 +++++----- lib_rend/ivas_reverb_fx.c | 15 ++- lib_rend/ivas_reverb_utils_fx.c | 131 +++++++++++++++++++----- 4 files changed, 150 insertions(+), 62 deletions(-) diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 0e2033fd4..f3d1be1fe 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1097,8 +1097,8 @@ 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 ); + Word32 *pOutput_t60, + Word32 *pOutput_ene ); void ivas_reverb_interpolate_acoustic_data_fx( const Word16 input_table_size, const Word32 *pInput_fc, //input in Q16 @@ -1119,10 +1119,8 @@ void ivas_reverb_interpolate_energies_fx( const Word32 *pInput_ene_r, //input in Q28 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_ene_l, // output in Q28 + Word32 *pOutput_ene_r // output in Q28 ); #endif /*---------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index a40fcfac8..1cd5b9e7c 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -936,15 +936,14 @@ void ivas_reverb_interpolate_energies_fx( 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 ) + Word32 *pOutput_ene_l, // output in Q28 + Word32 *pOutput_ene_r ) // output in Q28 { - 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++ ) @@ -954,6 +953,8 @@ void ivas_reverb_interpolate_energies_fx( { input_idx = 0; move16(); + input_idx_next = 1; + move16(); rel_offset = 0; move32(); rel_offset_e = 0; @@ -965,7 +966,10 @@ void ivas_reverb_interpolate_energies_fx( 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; + move16(); + input_idx_next = add( input_idx, 1 ); + move16(); + rel_offset = ONE_IN_Q15; move32(); rel_offset_e = 1; move16(); @@ -973,30 +977,34 @@ void ivas_reverb_interpolate_energies_fx( /* 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] ) ) + WHILE( GT_32( pOutput_fc[output_idx], pInput_fc[input_idx_next] ) ) { 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(); + // Rel_offset + 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, rel_offset_e ); } } - 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_ene_l[output_idx] = L_add( pInput_ene_l[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_l[input_idx_next], pInput_ene_l[input_idx] ) ) ); + pOutput_ene_r[output_idx] = L_add( pInput_ene_r[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_r[input_idx_next], pInput_ene_r[input_idx] ) ) ); + + //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(); } return; diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 761f87ef8..85d909ac1 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -2439,24 +2439,31 @@ 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]; + /*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_temp, ene_temp ) ) != IVAS_ERR_OK ) + { + return error; + }*/ + + if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) { return error; } + //Port this?? preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); +/* #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT floatToFixed_arrL( t60_temp, t60, Q26, CLDFB_NO_CHANNELS_MAX ); #else floatToFixed_arrL( t60_temp, t60, Q31, CLDFB_NO_CHANNELS_MAX ); #endif - floatToFixed_arrL( ene_temp, ene, Q31, 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 cfbfd7315..94701b1dd 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -64,7 +64,7 @@ typedef struct cldfb_convolver_state 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 int32_t sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out ); /*-----------------------------------------------------------------------------------------* * Function ivas_reverb_prepare_cldfb_params() @@ -77,21 +77,29 @@ 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 ) + Word32 *pOutput_t60, + Word32 *pOutput_ene ) { int16_t idx; - float avg_pwr_left[CLDFB_NO_CHANNELS_MAX]; + /*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; + const float dmx_gain_2 = 4.0f * EVS_PI * dist * dist / 0.001f;*/ + 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; + + Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp; + const Word32 dmx_gain_2_fx = 1852986624; // Q16 + Word16 exp_argument_fx, exp_argument_e, tmp, tmp_flag; + Word16 pow_exp; + + 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++ ) { @@ -101,30 +109,96 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 ); - /* adjust DSR for the delay difference */ - delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); + /*ivas_reverb_interpolate_energies_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 );*/ - delay_diff = (float) delay_diff_fx / ONE_IN_Q27; + //Return T60 in fixed-point 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] ) ); + pOutput_t60[i] = L_shl( output_t60_fx[i], sub( output_t60_e, 5 ) ); + //pOutput_t60[i] = output_t60_fx[i] * ( 1 << output_t60_e[i] ); // Will not work - mantissa is 16 bit } - ln_1e6_inverted = 1.0f / logf( 1e06f ); + /*for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) //Should not be required in fixed-point + { + pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) ); -->This operation must be recreated in fixed-point to return T60 + pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) ); + }*/ + + /* adjust DSR for the delay difference */ + + delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); + ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ + 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 ); + exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e ); + exp_argument_e = add( exp_argument_e, sub( 4, output_t60_e[idx] ) ); // Q27 -> e4 (from other function). However, t60 is in Q26. This should be handled appropriately + /* 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 ); + // 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 = 23552; + move16(); + exp_argument_e = 5; + move16(); + } + + tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); + IF( tmp_flag < 0 ) + { + 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(); + } + } + + 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 ); + L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); + tmp_exp = add( pow_exp, output_ene_e[idx] ); + + output_ene_fx[idx] = L_tmp; + move32(); + output_ene_e[idx] = tmp_exp; + move16(); + } - ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left, avg_pwr_right ); + + ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); 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; + + // For fixed-point porting -> energies are stored in Q31, but gain is calcualted in Q16. Final result must be in Q31. + + // Steps for this conversion: + // Step 1 : add avg_pwr_left and avg_pwr_right (assuming same Q factor) and store in a temp variable -> use L_add : 32bit addition with saturation + // Step 2 : scale the tmep variable by 0.5 -> can this be done by right shifting by 1? + + tmp_ene = ( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ) ) >> 1; // Or Madd32_32()?? + + // Step 3 : multiply temp variable by gain, with appropriate scaling for Q31 and Q16 multiplication + tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 + // incomplete implentation + + // Step 4 : multiply step 3 result with output energy variable + pOutput_ene[idx] = tmp_ene; + + + /*floating-point + pOutput_ene[idx] *= 0.5f * ( avg_pwr_left[idx] + avg_pwr_right[idx] ) * dmx_gain_2;*/ } return IVAS_ERR_OK; @@ -142,18 +216,16 @@ 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 ) + Word32 *avg_pwr_left, + Word32 *avg_pwr_right ) { int16_t freq_idx; float input_fc[FFT_SPECTRUM_SIZE]; #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT 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]; + Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; // Q28 + Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; // Q28 const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); #endif @@ -164,7 +236,7 @@ static void ivas_reverb_set_energies( { input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - input_fc_fx[freq_idx] = input_fc[freq_idx] * ONE_IN_Q16; + input_fc_fx[freq_idx] = (Word32) input_fc[freq_idx] * ONE_IN_Q16; #endif } @@ -200,7 +272,7 @@ static void ivas_reverb_set_energies( #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT 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 ); + CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx, avg_pwr_right_fx ); #else ivas_reverb_interpolate_acoustic_data_fx( FFT_SPECTRUM_SIZE, 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 ); @@ -208,8 +280,11 @@ static void ivas_reverb_set_energies( for ( int i = 0; i < 60; i++ ) { - 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[i] = (float)avg_pwr_left_fx[i] / ONE_IN_Q28; //(float) fabs( me2f( avg_pwr_left_fx[i], avg_pwr_left_e[i] ) ); + // avg_pwr_right[i] = (float) avg_pwr_right_fx[i] / ONE_IN_Q28; // (float) fabs( me2f( avg_pwr_right_fx[i], avg_pwr_right_e[i] ) ); + + avg_pwr_left[i] = avg_pwr_left_fx[i]; + avg_pwr_right[i] = avg_pwr_right_fx[i]; } #ifndef FIX_1741_REVERB_TIMES_Q_FORMAT -- GitLab From e00fb21526929b56249e38a06cc1a67622a54738 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 17 Jul 2025 17:19:07 +0200 Subject: [PATCH 02/43] mid stage updates - solved logical error --- lib_rend/ivas_prot_rend_fx.h | 5 +-- lib_rend/ivas_reverb_filter_design_fx.c | 47 ++++++++++--------- lib_rend/ivas_reverb_fx.c | 2 +- lib_rend/ivas_reverb_utils_fx.c | 60 ++++++++++++++----------- 4 files changed, 63 insertions(+), 51 deletions(-) diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index f3d1be1fe..107294695 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1099,6 +1099,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( const int32_t output_Fs, Word32 *pOutput_t60, Word32 *pOutput_ene ); + void ivas_reverb_interpolate_acoustic_data_fx( const Word16 input_table_size, const Word32 *pInput_fc, //input in Q16 @@ -1107,9 +1108,7 @@ void ivas_reverb_interpolate_acoustic_data_fx( 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 + Word32 *pOutput_dsr ); #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT void ivas_reverb_interpolate_energies_fx( diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 1cd5b9e7c..1cdb4adc0 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -853,16 +853,16 @@ void ivas_reverb_interpolate_acoustic_data_fx( 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 + Word32 *pOutput_t60, // pOutput_t60_e // output t60 in Q26 + Word32 *pOutput_dsr // pOutput_dsr_e // output dsr in Q 30 ) { - 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(); move16(); FOR( output_idx = 0; output_idx < output_table_size; output_idx++ ) @@ -872,6 +872,8 @@ void ivas_reverb_interpolate_acoustic_data_fx( { input_idx = 0; move16(); + input_idx_next = 0; + move16(); rel_offset = 0; move32(); rel_offset_e = 0; @@ -883,7 +885,8 @@ void ivas_reverb_interpolate_acoustic_data_fx( 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; + input_idx_next = add( input_idx, 1 ); + rel_offset = ONE_IN_Q15; move32(); rel_offset_e = 1; move16(); @@ -895,26 +898,30 @@ void ivas_reverb_interpolate_acoustic_data_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 + 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 + 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(); + pOutput_t60[output_idx] = L_add( pInput_t60[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_t60[input_idx_next], pInput_t60[input_idx] ) ) ); + pOutput_dsr[output_idx] = L_add( pInput_dsr[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_dsr[input_idx_next], pInput_dsr[input_idx] ) ) ); + //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) // If DSR is in Q30 -> Should this not be 31 - (31 - rel_offset_e + 30 - 31)?? + //move32(); + ////pOutput_dsr_e[output_idx] = mult_e; + //move16(); } return; diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 85d909ac1..c72d9d7c7 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1293,7 +1293,7 @@ static void set_reverb_acoustic_data_fx( /* 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 ); + nr_fc_fft_filter, pFc_fx, pRt60_fx, pDsr_fx ); /* adjust DSR for the delay difference */ diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 94701b1dd..882fa7e8a 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -89,9 +89,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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, ln_1e6_inverted_fx, L_tmp; const Word32 dmx_gain_2_fx = 1852986624; // Q16 @@ -106,35 +104,23 @@ ivas_error ivas_reverb_prepare_cldfb_params( output_fc_fx[idx] = (Word32) ( ( idx + 0.5f ) * ( MAX_SAMPLING_RATE / ( 2 * CLDFB_NO_CHANNELS_MAX ) ) ) * ONE_IN_Q16; } - 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_interpolate_energies_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 );*/ - - //Return T60 in fixed-point - for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - pOutput_t60[i] = L_shl( output_t60_fx[i], sub( output_t60_e, 5 ) ); - //pOutput_t60[i] = output_t60_fx[i] * ( 1 << output_t60_e[i] ); // Will not work - mantissa is 16 bit - } + // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. Period. + // ivas_interpolate_on_freq_grids_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx ); - /*for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) //Should not be required in fixed-point - { - pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) ); -->This operation must be recreated in fixed-point to return T60 - pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) ); - }*/ + 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 ); /* adjust DSR for the delay difference */ delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); + ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); + L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // Q26 exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e ); - exp_argument_e = add( exp_argument_e, sub( 4, output_t60_e[idx] ) ); // Q27 -> e4 (from other function). However, t60 is in Q26. This should be handled appropriately + exp_argument_e = add( exp_argument_e, sub( 4, L_tmp ) ); // Q27 -> e4 (from other function). However, t60 is in Q26. This should be handled appropriately /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ // 23 in Q26 @@ -162,19 +148,39 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 ); + tmp = mult( 23637, exp_argument_fx ); + tmp_exp = add( exp_argument_e, 1 ); // exp_argument_e + 1 L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp ); L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); - tmp_exp = add( pow_exp, output_ene_e[idx] ); +// tmp_exp = add( pow_exp, output_ene_e[idx] ); output_ene_fx[idx] = L_tmp; move32(); - output_ene_e[idx] = tmp_exp; +// output_ene_e[idx] = tmp_exp; move16(); } + // interpolate_acoustic_data() is returning t60 values in Q31. + // Return T60 in fixed-point + //The below loop is not needed once interpolate_data() returns only fx values. + for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + // Assign t60 to output variable + //pOutput_t60[i] = L_shl( output_t60_fx[i], sub( output_t60_e[i], 5 ) ); + // Assign energy to output variable + //pOutput_ene[i] = L_shl( output_ene_fx[i], sub( output_ene_e[i], 0 ) ); + // pOutput_t60[i] = L_shl( output_t60_fx[i], output_t60_e[i] ); + // pOutput_t60[i] = output_t60_fx[i] * ( 1 << output_t60_e[i] ); // Will not work - mantissa is 16 bit + } + + + /*for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) //Should not be required in fixed-point + { + pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) ); -->This operation must be recreated in fixed-point to return T60 + pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) ); + }*/ + ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) @@ -193,8 +199,8 @@ ivas_error ivas_reverb_prepare_cldfb_params( tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 // incomplete implentation - // Step 4 : multiply step 3 result with output energy variable - pOutput_ene[idx] = tmp_ene; + // Step 4 : multiply step 3 result with output energy + pOutput_ene[idx] =Mpy_32_32(pOutput_ene[idx] ,tmp_ene); /*floating-point -- GitLab From 2bf3969b74bad2123b6cbd5e44e43884fb8a2277 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 17 Jul 2025 17:23:25 +0200 Subject: [PATCH 03/43] Added logical error fix in interpolate_energies() --- lib_rend/ivas_reverb_filter_design_fx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 1cdb4adc0..efca5a5f8 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -988,6 +988,7 @@ void ivas_reverb_interpolate_energies_fx( { input_idx = add( input_idx, 1 ); } + input_idx_next = add( input_idx, 1 ); // Rel_offset 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, rel_offset_e ); -- GitLab From f1932c516fe39f2bf6e26e7d77af5f3a05b887f7 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 18 Jul 2025 18:16:10 +0200 Subject: [PATCH 04/43] mid stage changes --- lib_rend/ivas_reverb_utils_fx.c | 91 ++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 882fa7e8a..655c58a7a 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -93,7 +93,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp; const Word32 dmx_gain_2_fx = 1852986624; // Q16 - Word16 exp_argument_fx, exp_argument_e, tmp, tmp_flag; + Word32 exp_argument_fx, exp_argument_e, tmp, tmp_flag; Word16 pow_exp; Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; @@ -110,47 +110,80 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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_fx is in Q26 + //output_ene_fx is in 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 ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // Q26 - exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e ); - exp_argument_e = add( exp_argument_e, sub( 4, L_tmp ) ); // Q27 -> e4 (from other function). However, t60 is in Q26. This should be handled appropriately + L_tmp = Mpy_32_32( output_t60_fx[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_fx in Q14 + //exp_argument_fx = L_shl_sat( exp_argument_fx, exp_argument_e ); //exp_argument_fx converted to Q16 + /* Test Segment Begin*/ + //exp_argument_fx = shl_sat( exp_argument_fx, exp_argument_e ); // Q22 + /* Test Segment End*/ + + //exp_argument_e = add( exp_argument_e, sub( 4, pRt60_e[idx] ) ); // Q27 -> e4 -> This step must be adjusted accordingly as per the above two steps /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ // 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 = 23552; - move16(); - exp_argument_e = 5; - move16(); - } - - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); - IF( tmp_flag < 0 ) - { - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( negate( exp_argument_fx ) ), exp_argument_e, 1543503872, 5 ); - IF( tmp_flag < 0 ) + + // Replace by 23 in Q14, only for _fx. 23 in Q14 = 376832 + // Pseudocode + // IF (GT_32(exp_argument_fx, 376832 )) + /*{ + assign Q14 equivalent of Left_Shift(23552,5) to exp_argument_fx + } + IF (LT_32(exp_argument_fx, 0)) + { { - exp_argument_fx = -23552; - move16(); - exp_argument_e = 5; - move16(); + If(LT_32(negate(exp_argument_fx), 376832)) + { + assign Q14 equivalent of Left_Shift(-23552,5) to exp_argument_fx + } } - } + } + */ + + + // TODO: Convert the capping to the limits + //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 1543503872, 5 ); + //IF( tmp_flag > 0 ) + //{ + // exp_argument_fx = 23552; + // move16(); + // exp_argument_e = 5; //exponent is 5 because 5 is the offset from Q31 to Q26 + // move16(); // Same value in Q14 = 184?? + //} + + //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); + //IF( tmp_flag < 0 ) + //{ + // 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(); + // } + //} Word16 tmp_exp; /* expf(exp_argument) -> pow(2, log2(e) * exp_argument) */ - tmp = mult( 23637, exp_argument_fx ); - tmp_exp = add( exp_argument_e, 1 ); // exp_argument_e + 1 - L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp ); + tmp = mult( 23637, exp_argument_fx ); // Q13 : mult(Q14,Q14) results in Q13 // this step denotes x * 1/ln(2) + //tmp_exp = add( exp_argument_e, 1 ); // exp_argument_e + 1 + //L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp ); + L_tmp = BASOP_util_Pow2( tmp, 0, &pow_exp ); + /* L_tmp = mantissa of the operation + pow_exp = exponent of the operation + operation returns 2 ^ ( tmp * 2^(tmp_exp)) + */ L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); // tmp_exp = add( pow_exp, output_ene_e[idx] ); @@ -196,7 +229,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( tmp_ene = ( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ) ) >> 1; // Or Madd32_32()?? // Step 3 : multiply temp variable by gain, with appropriate scaling for Q31 and Q16 multiplication - tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 + tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 // Qfactor of tmp_ene?? dmx_gain_2_fx is in Q16 // incomplete implentation // Step 4 : multiply step 3 result with output energy @@ -278,7 +311,7 @@ static void ivas_reverb_set_energies( #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT 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 ); + CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx, avg_pwr_right_fx ); //Retains Q-Format #else ivas_reverb_interpolate_acoustic_data_fx( FFT_SPECTRUM_SIZE, 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 ); -- GitLab From 00bf2d8f0ce2ded754d026ded8afdfab22e215cc Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:43:30 +0200 Subject: [PATCH 05/43] Fully ported prepare_cldfb_params() - still in draft --- lib_rend/ivas_reverb_filter_design_fx.c | 15 +-- lib_rend/ivas_reverb_utils_fx.c | 127 +++++++----------------- 2 files changed, 44 insertions(+), 98 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index efca5a5f8..6ca1f4503 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -939,8 +939,8 @@ void ivas_reverb_interpolate_acoustic_data_fx( 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 Word32 *pInput_ene_l, // input in Q28 //Changed to Q31 + const Word32 *pInput_ene_r, // input in Q28 //Changes to q31 const Word16 output_table_size, const Word32 *pOutput_fc, // Q16 Word32 *pOutput_ene_l, // output in Q28 @@ -952,6 +952,7 @@ void ivas_reverb_interpolate_energies_fx( input_idx = 0; input_idx_next = 0; move16(); + move16(); FOR( output_idx = 0; output_idx < output_table_size; output_idx++ ) { @@ -960,7 +961,7 @@ void ivas_reverb_interpolate_energies_fx( { input_idx = 0; move16(); - input_idx_next = 1; + input_idx_next = 0; move16(); rel_offset = 0; move32(); @@ -984,14 +985,16 @@ void ivas_reverb_interpolate_energies_fx( /* otherwise use linear interpolation between 2 consecutive points in the input table */ ELSE { - WHILE( GT_32( pOutput_fc[output_idx], pInput_fc[input_idx_next] ) ) + WHILE( GT_32( pOutput_fc[output_idx], pInput_fc[input_idx + 1] ) ) { input_idx = add( input_idx, 1 ); } input_idx_next = add( input_idx, 1 ); // Rel_offset - 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, rel_offset_e ); + 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(); } } diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 655c58a7a..84687565d 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -87,21 +87,23 @@ ivas_error ivas_reverb_prepare_cldfb_params( const float dist = DEFAULT_SRC_DIST; const float dmx_gain_2 = 4.0f * EVS_PI * dist * dist / 0.001f;*/ + #define CLDFB_BAND_WIDTH (400) // TODO: Fixme! Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp; const Word32 dmx_gain_2_fx = 1852986624; // Q16 - Word32 exp_argument_fx, exp_argument_e, tmp, tmp_flag; - Word16 pow_exp; + 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++ ) + 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] = add( shr(CLDFB_BAND_WIDTH, 1), mult(CLDFB_BAND_WIDTH, idx)); } // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. Period. @@ -121,100 +123,41 @@ ivas_error ivas_reverb_prepare_cldfb_params( for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[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_fx in Q14 - //exp_argument_fx = L_shl_sat( exp_argument_fx, exp_argument_e ); //exp_argument_fx converted to Q16 - /* Test Segment Begin*/ - //exp_argument_fx = shl_sat( exp_argument_fx, exp_argument_e ); // Q22 - /* Test Segment End*/ + L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx );// L_tmp in Q26 // exp = pRt60_e[bin_idx] + 0 - //exp_argument_e = add( exp_argument_e, sub( 4, pRt60_e[idx] ) ); // Q27 -> e4 -> This step must be adjusted accordingly as per the above two steps + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );//exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) //Scale() returns values in the highest possible precision + exp_argument_fx = L_shr_sat( exp_argument_fx, sub(6,tmp_exp));//exp_argument_L_fx in Q26 /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ - // 23 in Q26 - - // Replace by 23 in Q14, only for _fx. 23 in Q14 = 376832 - // Pseudocode - // IF (GT_32(exp_argument_fx, 376832 )) - /*{ - assign Q14 equivalent of Left_Shift(23552,5) to exp_argument_fx - } - IF (LT_32(exp_argument_fx, 0)) - { - { - If(LT_32(negate(exp_argument_fx), 376832)) - { - assign Q14 equivalent of Left_Shift(-23552,5) to exp_argument_fx - } - } - } - */ - - - // TODO: Convert the capping to the limits - //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 1543503872, 5 ); - //IF( tmp_flag > 0 ) - //{ - // exp_argument_fx = 23552; - // move16(); - // exp_argument_e = 5; //exponent is 5 because 5 is the offset from Q31 to Q26 - // move16(); // Same value in Q14 = 184?? - //} - - //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); - //IF( tmp_flag < 0 ) - //{ - // 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(); - // } - //} - - Word16 tmp_exp; - /* expf(exp_argument) -> pow(2, log2(e) * exp_argument) */ - tmp = mult( 23637, exp_argument_fx ); // Q13 : mult(Q14,Q14) results in Q13 // this step denotes x * 1/ln(2) - //tmp_exp = add( exp_argument_e, 1 ); // exp_argument_e + 1 - //L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp ); - L_tmp = BASOP_util_Pow2( tmp, 0, &pow_exp ); - /* L_tmp = mantissa of the operation - pow_exp = exponent of the operation - operation returns 2 ^ ( tmp * 2^(tmp_exp)) - */ - L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); -// tmp_exp = add( pow_exp, output_ene_e[idx] ); - - output_ene_fx[idx] = L_tmp; + IF( GT_32( exp_argument_fx, 1543503872 ) ) //23 in Q26 + { + exp_argument_fx = 1543503872; + } + IF( LT_32( exp_argument_fx, -1543503872 ) ) + { + exp_argument_fx = -1543503872; + } + + tmp = Mpy_32_32( 96817114, exp_argument_fx );//Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );//Q28 -> not always, because pow_exp is not fixed + // tmp is a 32-bit signed integer in Q21, therefore expoenent to the power function is 10 + //L_tmp = L_shl_sat( L_tmp, pow_exp );// Q28?? + + //L_tmp = L_shl( L_tmp, add( 1, pow_exp ) ); + //L_tmp = L_shl( L_tmp, pow_exp ); + L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); // Q27. Q28 multiplied by Q30 gives Q27 -> Finally, energy should be in Q31 ( this is mandatory for further computations) + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) );// + + pOutput_ene[idx] = L_tmp; move32(); -// output_ene_e[idx] = tmp_exp; - move16(); - - } - // interpolate_acoustic_data() is returning t60 values in Q31. - // Return T60 in fixed-point - //The below loop is not needed once interpolate_data() returns only fx values. - for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - // Assign t60 to output variable - //pOutput_t60[i] = L_shl( output_t60_fx[i], sub( output_t60_e[i], 5 ) ); - // Assign energy to output variable - //pOutput_ene[i] = L_shl( output_ene_fx[i], sub( output_ene_e[i], 0 ) ); - // pOutput_t60[i] = L_shl( output_t60_fx[i], output_t60_e[i] ); - // pOutput_t60[i] = output_t60_fx[i] * ( 1 << output_t60_e[i] ); // Will not work - mantissa is 16 bit - } + //Assign t60 to output pointer + pOutput_t60[idx] = output_t60_fx[idx]; //Q26 + } - /*for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) //Should not be required in fixed-point - { - pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) ); -->This operation must be recreated in fixed-point to return T60 - pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) ); - }*/ - - ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); + ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { @@ -226,14 +169,14 @@ ivas_error ivas_reverb_prepare_cldfb_params( // Step 1 : add avg_pwr_left and avg_pwr_right (assuming same Q factor) and store in a temp variable -> use L_add : 32bit addition with saturation // Step 2 : scale the tmep variable by 0.5 -> can this be done by right shifting by 1? - tmp_ene = ( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ) ) >> 1; // Or Madd32_32()?? + tmp_ene = ( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ) ) >> 1; //Q28 // Step 3 : multiply temp variable by gain, with appropriate scaling for Q31 and Q16 multiplication tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 // Qfactor of tmp_ene?? dmx_gain_2_fx is in Q16 // incomplete implentation // Step 4 : multiply step 3 result with output energy - pOutput_ene[idx] =Mpy_32_32(pOutput_ene[idx] ,tmp_ene); + pOutput_ene[idx] =Mpy_32_32(pOutput_ene[idx] ,tmp_ene);//result seems to be correct, but in Q13. This should be scaled to Q31 for correct output. /*floating-point -- GitLab From 62e78a91bc274af9e2d7b8e39004af42e3c390b1 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 23 Jul 2025 14:44:28 +0200 Subject: [PATCH 06/43] midway commit - porting output_fc calculation to fixed point --- lib_rend/ivas_reverb_filter_design_fx.c | 4 +- lib_rend/ivas_reverb_utils_fx.c | 58 ++++++++----------------- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 6ca1f4503..6e3697566 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -939,8 +939,8 @@ void ivas_reverb_interpolate_acoustic_data_fx( 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 //Changed to Q31 - const Word32 *pInput_ene_r, // input in Q28 //Changes to q31 + 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, // output in Q28 diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 84687565d..e4d7f3419 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -81,13 +81,10 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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;*/ #define CLDFB_BAND_WIDTH (400) // TODO: Fixme! + const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); + const Word16 halfstep = 13107200; //Q16 Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; @@ -103,27 +100,28 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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] = add( shr(CLDFB_BAND_WIDTH, 1), mult(CLDFB_BAND_WIDTH, idx)); + + output_fc_fx[idx] = ( ( idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; + + output_fc_fx[idx] = mult( add( ( mult(idx, ONE_IN_Q16) << 1 ), ONE_IN_Q16 ), halfstep );//Debug + + int a = 1; // for debugging } // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. Period. - // ivas_interpolate_on_freq_grids_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx ); 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_fx is in Q26 - //output_ene_fx is in Q30 + //output_t60_fx: Q26, output_ene_fx: Q30 /* adjust DSR for the delay difference */ - delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); //Q27 ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx );// L_tmp in Q26 // exp = pRt60_e[bin_idx] + 0 + L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx );// L_tmp in Q26 exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );//exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) //Scale() returns values in the highest possible precision exp_argument_fx = L_shr_sat( exp_argument_fx, sub(6,tmp_exp));//exp_argument_L_fx in Q26 @@ -133,7 +131,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( { exp_argument_fx = 1543503872; } - IF( LT_32( exp_argument_fx, -1543503872 ) ) + IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26 { exp_argument_fx = -1543503872; } @@ -141,14 +139,10 @@ ivas_error ivas_reverb_prepare_cldfb_params( tmp = Mpy_32_32( 96817114, exp_argument_fx );//Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );//Q28 -> not always, because pow_exp is not fixed - // tmp is a 32-bit signed integer in Q21, therefore expoenent to the power function is 10 - //L_tmp = L_shl_sat( L_tmp, pow_exp );// Q28?? - - //L_tmp = L_shl( L_tmp, add( 1, pow_exp ) ); - //L_tmp = L_shl( L_tmp, pow_exp ); - L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); // Q27. Q28 multiplied by Q30 gives Q27 -> Finally, energy should be in Q31 ( this is mandatory for further computations) - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) );// + L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); //Q27 if result of previous step is in Q28 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) );//L_tmp in Q31 + //Assign energyt o putput -pointer pOutput_ene[idx] = L_tmp; move32(); @@ -163,24 +157,11 @@ ivas_error ivas_reverb_prepare_cldfb_params( { Word32 tmp_ene; - // For fixed-point porting -> energies are stored in Q31, but gain is calcualted in Q16. Final result must be in Q31. - - // Steps for this conversion: - // Step 1 : add avg_pwr_left and avg_pwr_right (assuming same Q factor) and store in a temp variable -> use L_add : 32bit addition with saturation - // Step 2 : scale the tmep variable by 0.5 -> can this be done by right shifting by 1? - tmp_ene = ( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ) ) >> 1; //Q28 - - // Step 3 : multiply temp variable by gain, with appropriate scaling for Q31 and Q16 multiplication - tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Mpy_32_32_ss multiplies two 32 bit numberrs in 64-bit with saturation or L_mult -> outputs word16 // Qfactor of tmp_ene?? dmx_gain_2_fx is in Q16 - // incomplete implentation - - // Step 4 : multiply step 3 result with output energy - pOutput_ene[idx] =Mpy_32_32(pOutput_ene[idx] ,tmp_ene);//result seems to be correct, but in Q13. This should be scaled to Q31 for correct output. - - - /*floating-point - pOutput_ene[idx] *= 0.5f * ( avg_pwr_left[idx] + avg_pwr_right[idx] ) * dmx_gain_2;*/ + tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); //Q13 + pOutput_ene[idx] =Mpy_32_32(pOutput_ene[idx] ,tmp_ene);//Q13 + //Scale final output to Q31 for compatibility with further computations + pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 );//Q31 } return IVAS_ERR_OK; @@ -262,9 +243,6 @@ static void ivas_reverb_set_energies( for ( int i = 0; i < 60; i++ ) { - // avg_pwr_left[i] = (float)avg_pwr_left_fx[i] / ONE_IN_Q28; //(float) fabs( me2f( avg_pwr_left_fx[i], avg_pwr_left_e[i] ) ); - // avg_pwr_right[i] = (float) avg_pwr_right_fx[i] / ONE_IN_Q28; // (float) fabs( me2f( avg_pwr_right_fx[i], avg_pwr_right_e[i] ) ); - avg_pwr_left[i] = avg_pwr_left_fx[i]; avg_pwr_right[i] = avg_pwr_right_fx[i]; } -- GitLab From 9c27f3973f8c686d02b2888117347ac99a6660a3 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 24 Jul 2025 09:52:06 +0200 Subject: [PATCH 07/43] Added general interpolate function and converted center frequency calculation to fixed point --- lib_rend/ivas_prot_rend_fx.h | 8 ++ lib_rend/ivas_reverb_filter_design_fx.c | 104 ++++++++++++++++-------- lib_rend/ivas_reverb_utils_fx.c | 25 +++++- 3 files changed, 104 insertions(+), 33 deletions(-) diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 107294695..e22f35ce7 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1122,6 +1122,14 @@ void ivas_reverb_interpolate_energies_fx( Word32 *pOutput_ene_r // output in Q28 ); #endif +void ivas_reverb_interp_on_freq_grid_fx( + const Word16 input_table_size, + 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_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 6e3697566..8934e60b8 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -854,7 +854,7 @@ void ivas_reverb_interpolate_acoustic_data_fx( const Word16 output_table_size, const Word32 *pOutput_fc, // Q16 Word32 *pOutput_t60, // pOutput_t60_e // output t60 in Q26 - Word32 *pOutput_dsr // pOutput_dsr_e // output dsr in Q 30 + Word32 *pOutput_dsr // pOutput_dsr_e // output dsr in Q 30 ) { Word16 input_idx, input_idx_next, output_idx; @@ -908,20 +908,6 @@ void ivas_reverb_interpolate_acoustic_data_fx( pOutput_t60[output_idx] = L_add( pInput_t60[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_t60[input_idx_next], pInput_t60[input_idx] ) ) ); pOutput_dsr[output_idx] = L_add( pInput_dsr[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_dsr[input_idx_next], pInput_dsr[input_idx] ) ) ); - //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) // If DSR is in Q30 -> Should this not be 31 - (31 - rel_offset_e + 30 - 31)?? - //move32(); - ////pOutput_dsr_e[output_idx] = mult_e; - //move16(); } return; @@ -943,8 +929,8 @@ void ivas_reverb_interpolate_energies_fx( const Word32 *pInput_ene_r, // input in Q28 const Word16 output_table_size, const Word32 *pOutput_fc, // Q16 - Word32 *pOutput_ene_l, // output in Q28 - Word32 *pOutput_ene_r ) // output in Q28 + Word32 *pOutput_ene_l, // output in Q28 + Word32 *pOutput_ene_r ) // output in Q28 { Word16 input_idx, input_idx_next, output_idx; Word32 rel_offset; @@ -992,7 +978,7 @@ void ivas_reverb_interpolate_energies_fx( input_idx_next = add( input_idx, 1 ); // Rel_offset 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 = L_shl_sat( rel_offset, add( 16, rel_offset_e ) ); rel_offset_e = 0; move16(); } @@ -1000,24 +986,78 @@ void ivas_reverb_interpolate_energies_fx( pOutput_ene_l[output_idx] = L_add( pInput_ene_l[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_l[input_idx_next], pInput_ene_l[input_idx] ) ) ); pOutput_ene_r[output_idx] = L_add( pInput_ene_r[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_r[input_idx_next], pInput_ene_r[input_idx] ) ) ); + } - //Word32 mult1; - //Word16 mult_e = 0; + return; +} +#endif - //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(); +/*-------------------------------------------------------------------* + * ivas_reverb_interp_on_freq_grid_fx() + * + * 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_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, input_idx_next, output_idx; + Word32 rel_offset; + Word16 rel_offset_e; + input_idx = 0; + input_idx_next = 0; + move16(); + 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(); + 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_grid_size - 1] ) ) + { + input_idx = sub( input_grid_size, 2 ); + input_idx_next = add( input_idx, 1 ); + rel_offset = ONE_IN_Q15; + 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 ); + } + 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 + 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(); + } + } + + 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; } -#endif diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index e4d7f3419..a28f90839 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -91,6 +91,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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; @@ -104,7 +105,8 @@ ivas_error ivas_reverb_prepare_cldfb_params( output_fc_fx[idx] = ( ( idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; output_fc_fx[idx] = mult( add( ( mult(idx, ONE_IN_Q16) << 1 ), ONE_IN_Q16 ), halfstep );//Debug - + + output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl(Mult_32_16( cldfb_band_width, idx ), 15 ) ); int a = 1; // for debugging } @@ -112,6 +114,27 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 ); + + //write to csv + /*FILE *filewriter = fopen("output.csv", "w"); + if (filewriter == NULL) + { + perror("Failed to open file"); + return; + } + fprintf( filewriter, "T60(old function),DSR (old fucntion)\n" ); + + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + { + fprintf( filewriter, "%f,%f", (float) output_t60_fx / ( 1 << 26 ), (float) output_ene_fx / ( 1 << 30 ) ); + }*/ + + //Testing generalised interpolate function - write values to csv for comparison + //T60 + 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 ); + //DSR + 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 ); + //output_t60_fx: Q26, output_ene_fx: Q30 /* adjust DSR for the delay difference */ -- GitLab From 967dafc670089ca717a5f1ac300bb480315d05e1 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 25 Jul 2025 08:49:12 +0200 Subject: [PATCH 08/43] Debugging code --- lib_rend/ivas_reverb_utils_fx.c | 35 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index a28f90839..ea5a39e38 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -83,8 +83,8 @@ ivas_error ivas_reverb_prepare_cldfb_params( int16_t idx; #define CLDFB_BAND_WIDTH (400) // TODO: Fixme! - const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); - const Word16 halfstep = 13107200; //Q16 + //const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); + //const Word16 halfstep = 13107200; //Q16 Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; @@ -100,14 +100,14 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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] = (Word32) ( ( idx + 0.5f ) * ( MAX_SAMPLING_RATE / ( 2 * CLDFB_NO_CHANNELS_MAX ) ) ) * ONE_IN_Q16; - output_fc_fx[idx] = ( ( idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; +// output_fc_fx[idx] = ( ( idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; - output_fc_fx[idx] = mult( add( ( mult(idx, ONE_IN_Q16) << 1 ), ONE_IN_Q16 ), halfstep );//Debug +// output_fc_fx[idx] = mult( add( ( mult(idx, ONE_IN_Q16) << 1 ), ONE_IN_Q16 ), halfstep );//Debug output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl(Mult_32_16( cldfb_band_width, idx ), 15 ) ); - int a = 1; // for debugging + // int a = 1; // for debugging } // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. Period. @@ -116,25 +116,32 @@ ivas_error ivas_reverb_prepare_cldfb_params( CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx, output_ene_fx ); //write to csv - /*FILE *filewriter = fopen("output.csv", "w"); + FILE *filewriter = fopen("output.csv", "w"); if (filewriter == NULL) { perror("Failed to open file"); - return; +// return; } fprintf( filewriter, "T60(old function),DSR (old fucntion)\n" ); - FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - fprintf( filewriter, "%f,%f", (float) output_t60_fx / ( 1 << 26 ), (float) output_ene_fx / ( 1 << 30 ) ); - }*/ + fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + } + fprintf( filewriter, "\n" ); + //Testing generalised interpolate function - write values to csv for comparison //T60 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 ); //DSR 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 ); + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + { + fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + } + //output_t60_fx: Q26, output_ene_fx: Q30 /* adjust DSR for the delay difference */ @@ -174,6 +181,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( } + //This function can be condensed ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) @@ -259,6 +267,11 @@ static void ivas_reverb_set_energies( #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT 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 ); //Retains Q-Format + //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 ); + #else ivas_reverb_interpolate_acoustic_data_fx( FFT_SPECTRUM_SIZE, 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 ); -- GitLab From f4e31a1e81b135c710c230c5bfc869d10b626fec Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:22:34 +0200 Subject: [PATCH 09/43] Debugging code - for condensing ivas_reverb_set-energies() --- lib_rend/ivas_reverb_utils_fx.c | 62 +++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index ea5a39e38..5fec1d2b1 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -110,39 +110,47 @@ ivas_error ivas_reverb_prepare_cldfb_params( // int a = 1; // for debugging } - // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. Period. + // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. The following function and the function call should be removed from code + //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 ); - 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 ); - - //write to csv + /* ---------- Debugging Block Starts-------------------*/ + //write to csv FILE *filewriter = fopen("output.csv", "w"); if (filewriter == NULL) { perror("Failed to open file"); -// return; } fprintf( filewriter, "T60(old function),DSR (old fucntion)\n" ); FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + //Print t60 and DSR + //fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); } - fprintf( filewriter, "\n" ); + //fprintf( filewriter, "\n" ); + + /* --------- Debugging Block Ends--------------------*/ - //Testing generalised interpolate function - write values to csv for comparison - //T60 + //T60 - Q26 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 ); - //DSR + //DSR - Q30 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 ); + /* ---------- Debugging Block Starts-------------------*/ + // write to csv FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + // Print T60 and DSR + // fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + // Print input and output center frequency + fprintf( filewriter, "%f,%f\n", (float) pInput_params->pFc_input_fx[idx] / ( 1 << 16 ), (float) output_fc_fx[idx] / ( 1 << 16 ) ); } - - //output_t60_fx: Q26, output_ene_fx: Q30 + fprintf( filewriter, "\n" ); + //Close file + fclose( filewriter ); + /* --------- Debugging Block Ends--------------------*/ /* adjust DSR for the delay difference */ delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); //Q27 @@ -172,7 +180,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); //Q27 if result of previous step is in Q28 L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) );//L_tmp in Q31 - //Assign energyt o putput -pointer + //Assign energy to output pointer pOutput_ene[idx] = L_tmp; move32(); @@ -181,7 +189,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( } - //This function can be condensed + //This function can be condensed and merged within prepare_cldfb_params(). It is only called once, at this location. ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) @@ -241,6 +249,24 @@ static void ivas_reverb_set_energies( } #endif + /* ---------- Debugging Block Starts-------------------*/ + FILE *filewriter = fopen( "output2.csv", "w" ); + if ( filewriter == NULL ) + { + perror( "Failed to open file" ); + } + // write to csv + FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) + { + // Print T60 and DSR + // fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); + // Print input and output center frequency + fprintf( filewriter, "%f,%f\n", (float) input_fc_fx[freq_idx] / ( 1 << 16 ), (float) output_fc_fx[freq_idx] / ( 1 << 16 ) ); + } + // Close file + fclose( filewriter ); + /* --------- Debugging Block Ends--------------------*/ + #ifndef FIX_1741_REVERB_TIMES_Q_FORMAT Word32 *input_fc_fx = (Word32 *) malloc( 60 * sizeof( Word32 ) ); @@ -265,8 +291,8 @@ static void ivas_reverb_set_energies( #endif #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - 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 ); //Retains Q-Format + //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 ); //Retains Q-Format //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 -- GitLab From ce311bf41cbbea79abf816fb1feedc94ed078993 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Mon, 28 Jul 2025 17:41:12 +0200 Subject: [PATCH 10/43] Minor code cleanup after porting input_fc_fx calculations --- lib_rend/ivas_prot_rend_fx.h | 2 +- lib_rend/ivas_reverb_fx.c | 7 --- lib_rend/ivas_reverb_utils_fx.c | 104 ++++++-------------------------- 3 files changed, 20 insertions(+), 93 deletions(-) diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index e22f35ce7..46a435bf0 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1096,7 +1096,7 @@ void ivas_reverb_calc_color_levels_fx( 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, + const Word32 output_Fs, Word32 *pOutput_t60, Word32 *pOutput_ene ); diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index c72d9d7c7..1ac29c713 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -2439,17 +2439,10 @@ 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 ) - { - return error; - }*/ - if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60, ene ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 5fec1d2b1..ea457dbb9 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -64,7 +64,7 @@ typedef struct cldfb_convolver_state 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, Word32 *avg_pwr_l_out, Word32 *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,19 +72,15 @@ 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, + const Word32 output_Fs, Word32 *pOutput_t60, Word32 *pOutput_ene ) { - int16_t idx; + Word16 idx; - #define CLDFB_BAND_WIDTH (400) // TODO: Fixme! - //const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); - //const Word16 halfstep = 13107200; //Q16 Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX]; Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; @@ -100,58 +96,14 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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] = ( ( idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16; - -// output_fc_fx[idx] = mult( add( ( mult(idx, ONE_IN_Q16) << 1 ), ONE_IN_Q16 ), halfstep );//Debug - output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl(Mult_32_16( cldfb_band_width, idx ), 15 ) ); - // int a = 1; // for debugging - } - - // TODO: Replace all these dedicated interpolate functions with just one taking a single input vector and map it to a single output vector. The following function and the function call should be removed from code - //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 ); - - /* ---------- Debugging Block Starts-------------------*/ - //write to csv - FILE *filewriter = fopen("output.csv", "w"); - if (filewriter == NULL) - { - perror("Failed to open file"); } - fprintf( filewriter, "T60(old function),DSR (old fucntion)\n" ); - - FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) - { - //Print t60 and DSR - //fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); - } - - //fprintf( filewriter, "\n" ); - - /* --------- Debugging Block Ends--------------------*/ //T60 - Q26 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 ); //DSR - Q30 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 ); - /* ---------- Debugging Block Starts-------------------*/ - // write to csv - FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) - { - // Print T60 and DSR - // fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); - // Print input and output center frequency - fprintf( filewriter, "%f,%f\n", (float) pInput_params->pFc_input_fx[idx] / ( 1 << 16 ), (float) output_fc_fx[idx] / ( 1 << 16 ) ); - } - fprintf( filewriter, "\n" ); - //Close file - fclose( filewriter ); - /* --------- Debugging Block Ends--------------------*/ - /* adjust DSR for the delay difference */ delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); //Q27 @@ -161,7 +113,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( { L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx );// L_tmp in Q26 - exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );//exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) //Scale() returns values in the highest possible precision + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );//exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) exp_argument_fx = L_shr_sat( exp_argument_fx, sub(6,tmp_exp));//exp_argument_L_fx in Q26 /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ @@ -186,10 +138,8 @@ ivas_error ivas_reverb_prepare_cldfb_params( //Assign t60 to output pointer pOutput_t60[idx] = output_t60_fx[idx]; //Q26 - } - //This function can be condensed and merged within prepare_cldfb_params(). It is only called once, at this location. ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) @@ -217,56 +167,41 @@ 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, + 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; #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT Word32 input_fc_fx[FFT_SPECTRUM_SIZE]; Word32 output_fc_fx[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 Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX ); + const Word32 cldfb_band_width = 26214400; // 400 in Q16 + Word16 s; + Word16 temp; #endif + float input_fc[FFT_SPECTRUM_SIZE]; - 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 < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) { - input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); -#ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - input_fc_fx[freq_idx] = (Word32) input_fc[freq_idx] * ONE_IN_Q16; -#endif + input_fc_fx[freq_idx] = L_shl( L_mult( temp, freq_idx ), add( 15, s ) ); + + /* input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); + input_fc_fx[freq_idx] = input_fc[freq_idx] * ONE_IN_Q16;*/ } #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT 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 ) ); } #endif - /* ---------- Debugging Block Starts-------------------*/ - FILE *filewriter = fopen( "output2.csv", "w" ); - if ( filewriter == NULL ) - { - perror( "Failed to open file" ); - } - // write to csv - FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) - { - // Print T60 and DSR - // fprintf( filewriter, "%f,%f\n", (float) output_t60_fx[idx] / ( 1 << 26 ), (float) output_ene_fx[idx] / ( 1 << 30 ) ); - // Print input and output center frequency - fprintf( filewriter, "%f,%f\n", (float) input_fc_fx[freq_idx] / ( 1 << 16 ), (float) output_fc_fx[freq_idx] / ( 1 << 16 ) ); - } - // Close file - fclose( filewriter ); - /* --------- Debugging Block Ends--------------------*/ - #ifndef FIX_1741_REVERB_TIMES_Q_FORMAT Word32 *input_fc_fx = (Word32 *) malloc( 60 * sizeof( Word32 ) ); @@ -291,8 +226,7 @@ static void ivas_reverb_set_energies( #endif #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - //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 ); //Retains Q-Format + //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 -- GitLab From c68d8aa687dc954825a3bc4a042093e17756d24a Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:15:39 +0200 Subject: [PATCH 11/43] fixed bugs in acousticPreDelay,input_fc_fx and resolved floating point data members in room acoustics config data + code cleanup --- lib_com/common_api_types.h | 5 --- lib_rend/ivas_reverb_fx.c | 43 +++++++--------------- lib_rend/ivas_reverb_utils_fx.c | 64 +++++++++++++++------------------ lib_util/render_config_reader.c | 53 +++++++++++---------------- 4 files changed, 61 insertions(+), 104 deletions(-) diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 33013360e..5b0275035 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_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 1ac29c713..9f4429b32 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,12 @@ 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 */ + Word16 pT60_filter_coeff_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH]; /* Filters [][] in feedback loops, controlling T60. */ + 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 */ 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 */ @@ -2434,12 +2419,13 @@ ivas_error ivas_binaural_reverb_init( Word32 t60[CLDFB_NO_CHANNELS_MAX]; Word32 ene[CLDFB_NO_CHANNELS_MAX]; Word16 preDelay; + Word16 temp16, s; + Word32 temp32; error = IVAS_ERR_OK; if ( ( roomAcoustics != NULL ) && roomAcoustics->override ) { - revTimes = t60; revEne = ene; @@ -2448,15 +2434,10 @@ ivas_error ivas_binaural_reverb_init( return error; } - //Port this?? - preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); -/* -#ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - floatToFixed_arrL( t60_temp, t60, Q26, CLDFB_NO_CHANNELS_MAX ); -#else - floatToFixed_arrL( t60_temp, t60, Q31, CLDFB_NO_CHANNELS_MAX ); -#endif - floatToFixed_arrL( ene_temp, ene, Q31, CLDFB_NO_CHANNELS_MAX );*/ + temp16 = BASOP_Util_Divide3216_Scale( sampling_rate, CLDFB_NO_CHANNELS_MAX, &s ); + temp16 = shl( temp16, s ); // Q0 + temp32 = Mult_32_16( roomAcoustics->acousticPreDelay_fx, temp16 ); // Q11 + preDelay = shr( add( temp32, shl( 1, 10 ) ), 11 ); // Q0 } else { diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index ea457dbb9..00a72d2b4 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -54,15 +54,15 @@ * 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; +//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 Word32 sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out ); @@ -86,7 +86,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX]; Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp; - const Word32 dmx_gain_2_fx = 1852986624; // Q16 + 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; @@ -94,9 +94,9 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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++ ) + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl(Mult_32_16( cldfb_band_width, idx ), 15 ) ); + output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) ); } //T60 - Q26 @@ -109,12 +109,12 @@ ivas_error ivas_reverb_prepare_cldfb_params( ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ - for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx );// L_tmp in Q26 + L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // L_tmp in Q26 - exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );//exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) - exp_argument_fx = L_shr_sat( exp_argument_fx, sub(6,tmp_exp));//exp_argument_L_fx in Q26 + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp ); //exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); //exp_argument_L_fx in 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 @@ -123,14 +123,14 @@ ivas_error ivas_reverb_prepare_cldfb_params( } IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26 { - exp_argument_fx = -1543503872; + exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx );//Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 - L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );//Q28 -> not always, because pow_exp is not fixed + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); //Q28 -> not always, because pow_exp is not fixed L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); //Q27 if result of previous step is in Q28 - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) );//L_tmp in Q31 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); //L_tmp in Q31 //Assign energy to output pointer pOutput_ene[idx] = L_tmp; @@ -142,15 +142,15 @@ ivas_error ivas_reverb_prepare_cldfb_params( ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? - for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) + FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { Word32 tmp_ene; - tmp_ene = ( 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 + 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 //Scale final output to Q31 for compatibility with further computations - pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 );//Q31 + pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); //Q31 } return IVAS_ERR_OK; @@ -181,22 +181,16 @@ static void ivas_reverb_set_energies( Word16 s; Word16 temp; #endif - - float input_fc[FFT_SPECTRUM_SIZE]; - 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 < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) + FOR( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ ) { input_fc_fx[freq_idx] = L_shl( L_mult( temp, freq_idx ), add( 15, s ) ); - - /* input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) ); - input_fc_fx[freq_idx] = input_fc[freq_idx] * ONE_IN_Q16;*/ } #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - 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] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, freq_idx ), 15 ) ); } @@ -231,13 +225,13 @@ static void ivas_reverb_set_energies( 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 ); - + #else ivas_reverb_interpolate_acoustic_data_fx( FFT_SPECTRUM_SIZE, 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 ); #endif - for ( int i = 0; i < 60; i++ ) + FOR( int i = 0; i < 60; i++ ) { avg_pwr_left[i] = avg_pwr_left_fx[i]; avg_pwr_right[i] = avg_pwr_right_fx[i]; diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index bd9e7a48e..0e9db391d 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1140,46 +1140,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; } } @@ -2230,11 +2205,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 ) @@ -2657,13 +2633,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 ); -- GitLab From cef0fa43447fadd31476e82fb8165089fa0f67e0 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:46:47 +0200 Subject: [PATCH 12/43] cleaned up interpolate_acoustic_data_fx(), interpolate_energies() and cldfb_convolver_state --- lib_rend/ivas_prot_rend_fx.h | 23 +--- lib_rend/ivas_reverb_filter_design_fx.c | 154 ------------------------ lib_rend/ivas_reverb_fx.c | 7 +- lib_rend/ivas_reverb_utils_fx.c | 13 -- 4 files changed, 5 insertions(+), 192 deletions(-) diff --git a/lib_rend/ivas_prot_rend_fx.h b/lib_rend/ivas_prot_rend_fx.h index 46a435bf0..bbaf10c65 100644 --- a/lib_rend/ivas_prot_rend_fx.h +++ b/lib_rend/ivas_prot_rend_fx.h @@ -1093,6 +1093,7 @@ 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, @@ -1100,28 +1101,6 @@ ivas_error ivas_reverb_prepare_cldfb_params( Word32 *pOutput_t60, Word32 *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 -); -#ifdef FIX_1741_REVERB_TIMES_Q_FORMAT -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, - Word32 *pOutput_ene_l, // output in Q28 - Word32 *pOutput_ene_r // output in Q28 -); -#endif void ivas_reverb_interp_on_freq_grid_fx( const Word16 input_table_size, const Word32 *pInput_fc, //input center frequencies in Q16 diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 8934e60b8..d2b58b61e 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -838,160 +838,6 @@ void ivas_reverb_calc_color_levels_fx( return; } -/*-------------------------------------------------------------------* - * ivas_reverb_interpolate_acoustic_data_fx() - * - * Interpolates data from the input T60 and DSR tables 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_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 // output t60 in Q26 - Word32 *pOutput_dsr // pOutput_dsr_e // output dsr in Q 30 -) -{ - Word16 input_idx, input_idx_next, output_idx; - Word32 rel_offset; - Word16 rel_offset_e; - input_idx = 0; - input_idx_next = 0; - move16(); - 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(); - 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] ) ) - { - input_idx = sub( input_table_size, 2 ); - input_idx_next = add( input_idx, 1 ); - rel_offset = ONE_IN_Q15; - 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 ); - } - 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 + 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(); - } - } - - pOutput_t60[output_idx] = L_add( pInput_t60[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_t60[input_idx_next], pInput_t60[input_idx] ) ) ); - pOutput_dsr[output_idx] = L_add( pInput_dsr[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_dsr[input_idx_next], pInput_dsr[input_idx] ) ) ); - } - - return; -} - -#ifdef FIX_1741_REVERB_TIMES_Q_FORMAT -/*-------------------------------------------------------------------* - * 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, // output in Q28 - Word32 *pOutput_ene_r ) // output in Q28 -{ - Word16 input_idx, input_idx_next, output_idx; - Word32 rel_offset; - Word16 rel_offset_e; - input_idx = 0; - input_idx_next = 0; - move16(); - 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(); - 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] ) ) - { - input_idx = sub( input_table_size, 2 ); - move16(); - input_idx_next = add( input_idx, 1 ); - move16(); - rel_offset = ONE_IN_Q15; - 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 ); - } - input_idx_next = add( input_idx, 1 ); - // Rel_offset - 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(); - } - } - - pOutput_ene_l[output_idx] = L_add( pInput_ene_l[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_l[input_idx_next], pInput_ene_l[input_idx] ) ) ); - pOutput_ene_r[output_idx] = L_add( pInput_ene_r[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_ene_r[input_idx_next], pInput_ene_r[input_idx] ) ) ); - } - - return; -} -#endif - /*-------------------------------------------------------------------* * ivas_reverb_interp_on_freq_grid_fx() * diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 9f4429b32..1cb23e292 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1277,13 +1277,14 @@ static void set_reverb_acoustic_data_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 ); + + ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, nr_fc_fft_filter, pFc_fx, pRt60_fx ); + ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_dsr_fx, nr_fc_fft_filter, pFc_fx, pDsr_fx ); /* adjust DSR for the delay difference */ delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); - + ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ move32(); diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 00a72d2b4..a5449afb8 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -54,16 +54,6 @@ * 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 Word32 sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out ); /*-----------------------------------------------------------------------------------------* @@ -226,9 +216,6 @@ static void ivas_reverb_set_energies( //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 ); -#else - ivas_reverb_interpolate_acoustic_data_fx( FFT_SPECTRUM_SIZE, 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 ); #endif FOR( int i = 0; i < 60; i++ ) -- GitLab From 7082a49fcbe6ec3e54050bb587702656ce29d009 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:53:13 +0200 Subject: [PATCH 13/43] removed int and hardcoded loop counter from set_energies() --- lib_rend/ivas_reverb_utils_fx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index a5449afb8..c2a760d75 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -218,10 +218,10 @@ static void ivas_reverb_set_energies( #endif - FOR( int i = 0; i < 60; i++ ) + FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ ) { - avg_pwr_left[i] = avg_pwr_left_fx[i]; - avg_pwr_right[i] = avg_pwr_right_fx[i]; + avg_pwr_left[freq_idx] = avg_pwr_left_fx[freq_idx]; + avg_pwr_right[freq_idx] = avg_pwr_right_fx[freq_idx]; } #ifndef FIX_1741_REVERB_TIMES_Q_FORMAT -- GitLab From 3c8b8d1aa20290026a961996a7829ae39eeeec8b Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:57:43 +0200 Subject: [PATCH 14/43] changed int16/int32 to word16/word32 --- lib_rend/ivas_reverb_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 1cb23e292..f2bf0890d 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1261,7 +1261,7 @@ 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; @@ -1410,7 +1410,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; REVERB_HANDLE pState = NULL; -- GitLab From fa0610aea157bef7cdb931ddf3260815631f39f9 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:45:41 +0200 Subject: [PATCH 15/43] cleaned up deprecated macros from ivas_reverb_utils_fx.c --- lib_rend/ivas_reverb_utils_fx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index c2a760d75..a69f0652a 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -43,13 +43,8 @@ * 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 *-----------------------------------------------------------------------------------------*/ -- GitLab From a992f675758d89d59b2486f3103ab36a0fcfbb8f Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:39:52 +0200 Subject: [PATCH 16/43] optimisation in set_reverb_acoustic_data() --- lib_rend/ivas_reverb_fx.c | 38 ++++++++++++++++++++++++--------- lib_rend/ivas_reverb_utils_fx.c | 6 ++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index f2bf0890d..ce4818535 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1263,8 +1263,9 @@ static void set_reverb_acoustic_data_fx( { 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 tmp_flag, exp_argument_e; + Word16 pow_exp, tmp_exp; Word32 *pFc_input_fx = pRoomAcoustics->pFc_input_fx; Word32 *pAcoustic_rt60_fx = pRoomAcoustics->pAcoustic_rt60_fx; @@ -1278,21 +1279,38 @@ static void set_reverb_acoustic_data_fx( /* interpolate input table data for T60 and DSR to the FFT filter grid */ - ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, nr_fc_fft_filter, pFc_fx, pRt60_fx ); - ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_dsr_fx, nr_fc_fft_filter, pFc_fx, pDsr_fx ); + 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 */ + ///* ---------Start Debugging Block --------------------*/ + // FILE *filewriter = fopen( "output.csv", "w" ); + // if (filewriter == NULL) + //{ + // perror("Failed to open file"); + // } + // fprintf( filewriter, "T60, DSR\n" ); + // for ( int i = 0; i < nr_fc_fft_filter; ++i ) + //{ + // fprintf(filewriter, "%f,%f\n",(float)pRt60_fx[i]/(1 << 26), (float)pDsr_fx[i] / (1<<30)); + // } + // fclose( filewriter ); + ///* ---------End Debugging Block --------------------*/ + + ///* adjust DSR for the delay difference */ + + delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); // Q27 - delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); - 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 + L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // L_tmp in Q26 + + //exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// + 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 ) );//exp_argument_fx in Q26 - verified + /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ // 23 in Q26 diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index a69f0652a..8b7927587 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -84,10 +84,8 @@ ivas_error ivas_reverb_prepare_cldfb_params( output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) ); } - //T60 - Q26 - 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 ); - //DSR - Q30 - 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 ); + 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 ); //Q27 -- GitLab From 5471470d03cc2fe073c9cd3011df543ec99201d4 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:00:13 +0200 Subject: [PATCH 17/43] Ported ivas_set_reverb_acoustic_data() - requires testing and cleanup --- lib_rend/ivas_reverb_fx.c | 91 ++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index ce4818535..f633a600f 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1263,7 +1263,7 @@ static void set_reverb_acoustic_data_fx( { Word16 bin_idx; Word32 ln_1e6_inverted_fx, delay_diff_fx, L_tmp; - Word32 exp_argument_fx, tmp; + Word32 exp_argument_fx, tmp; Word16 tmp_flag, exp_argument_e; Word16 pow_exp, tmp_exp; @@ -1282,20 +1282,6 @@ static void set_reverb_acoustic_data_fx( 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 - ///* ---------Start Debugging Block --------------------*/ - // FILE *filewriter = fopen( "output.csv", "w" ); - // if (filewriter == NULL) - //{ - // perror("Failed to open file"); - // } - // fprintf( filewriter, "T60, DSR\n" ); - // for ( int i = 0; i < nr_fc_fft_filter; ++i ) - //{ - // fprintf(filewriter, "%f,%f\n",(float)pRt60_fx[i]/(1 << 26), (float)pDsr_fx[i] / (1<<30)); - // } - // fclose( filewriter ); - ///* ---------End Debugging Block --------------------*/ - ///* adjust DSR for the delay difference */ delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); // Q27 @@ -1309,45 +1295,62 @@ static void set_reverb_acoustic_data_fx( //exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// 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 ) );//exp_argument_fx in Q26 - verified + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, exp_argument_e ) ); //exp_argument_fx in Q26 - verified /* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */ - - // 23 in Q26 - tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 1543503872, 5 ); - IF( tmp_flag > 0 ) + 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 ); - L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); - tmp_exp = add( pow_exp, pDsr_e[bin_idx] ); + tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); // Q28 -> not always, because pow_exp is not fixed + L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); // Q27 if result of previous step is in Q28 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // L_tmp in Q31 pDsr_fx[bin_idx] = L_tmp; move32(); - pDsr_e[bin_idx] = tmp_exp; - move16(); + + // 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 = 23552; + // move16(); + // exp_argument_e = 5; + // move16(); + //} + + //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); + //IF( tmp_flag < 0 ) + //{ + // 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(); + // } + //} + + //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 ); + //L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); + //tmp_exp = add( pow_exp, pDsr_e[bin_idx] ); + + //pDsr_fx[bin_idx] = L_tmp; + //move32(); + //pDsr_e[bin_idx] = tmp_exp; + //move16(); } return; } -- GitLab From e6c89f0c20b7a50396ff7c4ec925f9b34eb65752 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 31 Jul 2025 10:05:54 +0200 Subject: [PATCH 18/43] added comments to mark _e notation for dsr --- lib_rend/ivas_reverb_fx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index f633a600f..208f63b2e 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1273,9 +1273,9 @@ 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; + Word16 *pRt60_e = pParams->pRt60_e; // should not be required; Word32 *pDsr_fx = pParams->pDsr_fx; - Word16 *pDsr_e = pParams->pDsr_e; + Word16 *pDsr_e = pParams->pDsr_e;//should not be required /* interpolate input table data for T60 and DSR to the FFT filter grid */ @@ -1508,11 +1508,11 @@ ivas_error ivas_reverb_open_fx( /* 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 ); + Word16 *pRt60_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter );//Should be removed + Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter );//Should be removed - params.pRt60_e = pRt60_e; - params.pDsr_e = pDsr_e; + params.pRt60_e = pRt60_e;//Should be removed + params.pDsr_e = pDsr_e;//Should be removed 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 ); @@ -1565,7 +1565,7 @@ 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] ); + params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] );//Pointless - should be elminiated if mantissa and exponent notation is removed move32(); pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ move32(); -- GitLab From a05f5db4ee37b0243c501a05a6451c4a17f5ac6f Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 31 Jul 2025 12:59:52 +0200 Subject: [PATCH 19/43] cleanup comments --- lib_rend/ivas_reverb_fx.c | 42 +-------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index aaf9d6999..09ef78321 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1316,41 +1316,6 @@ static void set_reverb_acoustic_data_fx( pDsr_fx[bin_idx] = L_tmp; move32(); - // 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 = 23552; - // move16(); - // exp_argument_e = 5; - // move16(); - //} - - //tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 0, 31 ); - //IF( tmp_flag < 0 ) - //{ - // 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(); - // } - //} - - //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 ); - //L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); - //tmp_exp = add( pow_exp, pDsr_e[bin_idx] ); - - //pDsr_fx[bin_idx] = L_tmp; - //move32(); - //pDsr_e[bin_idx] = tmp_exp; - //move16(); } return; } @@ -2458,12 +2423,7 @@ ivas_error ivas_binaural_reverb_init( #else preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); #endif -#ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - floatToFixed_arrL( t60_temp, t60, Q26, CLDFB_NO_CHANNELS_MAX ); -#else - floatToFixed_arrL( t60_temp, t60, Q31, CLDFB_NO_CHANNELS_MAX ); -#endif - floatToFixed_arrL( ene_temp, ene, Q31, CLDFB_NO_CHANNELS_MAX ); + } else { -- GitLab From 5d8fa7e8b0e0476df8174224c7a108276fb06ab6 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 31 Jul 2025 17:54:51 +0200 Subject: [PATCH 20/43] mid stage - porting t60 coefficients --- lib_rend/ivas_reverb_fx.c | 53 ++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 09ef78321..376490be8 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -576,7 +576,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; } @@ -630,30 +630,26 @@ 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 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; + 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(); } @@ -661,24 +657,21 @@ static ivas_error compute_t60_coeffs_fx( { 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 ); 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_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), pParams->pRt60_fx[bin_idx], &e ); + tmp = shr( tmp, add( e, 1 ) ); + target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720 //targetgains is in Q9 - tmp = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( target_gains_db_fx[bin_idx] ), target_gains_db_exp[bin_idx], -2013265920, 7 ); + //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 ) { target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720 move16(); - target_gains_db_exp[bin_idx] = 7; + //target_gains_db_exp[bin_idx] = 7; move16(); } } @@ -686,21 +679,21 @@ 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]; + //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] ); + //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] ) ); + //target_gains_db_fx[i] = shr( target_gains_db_fx[i], sub( val, target_gains_db_exp[i] ) ); move16(); } - 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 ) ) + //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 ) ) { return error; } @@ -1480,14 +1473,16 @@ ivas_error ivas_reverb_open_fx( params.pDsr_e = pDsr_e;//Should be removed 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 ); + + //Not needed after adjusting the interpolate and scaling functions to output dsr in Q31, T60 in Q26 + /*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; @@ -1509,7 +1504,7 @@ ivas_error ivas_reverb_open_fx( } /* set up input downmix */ - pState->dmx_gain_fx = calc_dmx_gain_fx(); + pState->dmx_gain_fx = calc_dmx_gain_fx();//Q23 /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay_fx( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay_fx, output_Fs ); -- GitLab From 235156bb95649b70f49fb7f4b5f8eb32a4ea7a38 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 1 Aug 2025 11:23:03 +0200 Subject: [PATCH 21/43] Added sanity check for 120dB in Q8 --- lib_rend/ivas_reverb_fx.c | 64 +++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 376490be8..cc572a6f8 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -632,11 +632,12 @@ static ivas_error compute_t60_coeffs_fx( 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; Word16 e; + const Word16 min120q8 = -30720; // -120 in Q8 error = IVAS_ERR_OK; move32(); @@ -658,20 +659,39 @@ static ivas_error compute_t60_coeffs_fx( Word16 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 ); + 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 ), pParams->pRt60_fx[bin_idx], &e ); - tmp = shr( tmp, add( e, 1 ) ); - target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720 //targetgains is in Q9 + IF( EQ_16( pParams->pRt60_fx[bin_idx], 0 ) ) + { + 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, add( e, 1 ) ); + target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 + } + } + // TODO: check for RT60 not 0, in case of 0, target gain is simply -120 dB + //tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), pParams->pRt60_fx[bin_idx], &e ); + // TODO: check for positive e, otherwise make it -120 dB + //tmp = shr( tmp, add( e, 1 ) ); + //target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720 //targetgains is in Q9 - //tmp = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( target_gains_db_fx[bin_idx] ), target_gains_db_exp[bin_idx], -2013265920, 7 ); + // 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 ) { target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720 move16(); - //target_gains_db_exp[bin_idx] = 7; + // target_gains_db_exp[bin_idx] = 7; move16(); } } @@ -679,21 +699,21 @@ 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]; + // 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] ); + // 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] ) ); + // target_gains_db_fx[i] = shr( target_gains_db_fx[i], sub( val, target_gains_db_exp[i] ) ); move16(); } - //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 ) ) + // 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 ) ) { return error; } @@ -1268,7 +1288,7 @@ static void set_reverb_acoustic_data_fx( Word32 *pRt60_fx = pParams->pRt60_fx; Word16 *pRt60_e = pParams->pRt60_e; // should not be required; Word32 *pDsr_fx = pParams->pDsr_fx; - Word16 *pDsr_e = pParams->pDsr_e;//should not be required + Word16 *pDsr_e = pParams->pDsr_e; // should not be required /* interpolate input table data for T60 and DSR to the FFT filter grid */ @@ -1286,9 +1306,9 @@ static void set_reverb_acoustic_data_fx( { L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // L_tmp in Q26 - //exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// + // exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// 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 ) ); //exp_argument_fx in Q26 - verified + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, exp_argument_e ) ); // exp_argument_fx in Q26 - verified /* 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 @@ -1308,7 +1328,6 @@ static void set_reverb_acoustic_data_fx( pDsr_fx[bin_idx] = L_tmp; move32(); - } return; } @@ -1466,15 +1485,15 @@ ivas_error ivas_reverb_open_fx( /* 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 );//Should be removed - Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter );//Should be removed + Word16 *pRt60_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter ); // Should be removed + Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter ); // Should be removed - params.pRt60_e = pRt60_e;//Should be removed - params.pDsr_e = pDsr_e;//Should be removed + params.pRt60_e = pRt60_e; // Should be removed + params.pDsr_e = pDsr_e; // Should be removed set_reverb_acoustic_data_fx( ¶ms, &hRenderConfig->roomAcoustics, nr_fc_input, nr_fc_fft_filter ); - //Not needed after adjusting the interpolate and scaling functions to output dsr in Q31, T60 in Q26 + // Not needed after adjusting the interpolate and scaling functions to output dsr in Q31, T60 in Q26 /*Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 ); FOR( i = 0; i < nr_fc_fft_filter; i++ ) { @@ -1504,7 +1523,7 @@ ivas_error ivas_reverb_open_fx( } /* set up input downmix */ - pState->dmx_gain_fx = calc_dmx_gain_fx();//Q23 + pState->dmx_gain_fx = calc_dmx_gain_fx(); // Q23 /* set up predelay - must be after set_base_config() and before compute_t60_coeffs() */ calc_predelay_fx( ¶ms, hRenderConfig->roomAcoustics.acousticPreDelay_fx, output_Fs ); @@ -1525,7 +1544,7 @@ 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] );//Pointless - should be elminiated if mantissa and exponent notation is removed + params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] ); // Pointless - should be elminiated if mantissa and exponent notation is removed move32(); pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ move32(); @@ -2418,7 +2437,6 @@ ivas_error ivas_binaural_reverb_init( #else preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); #endif - } else { -- GitLab From 075e6ea0aff76a4f77da54ed81ef808e0d7fa630 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 1 Aug 2025 12:02:45 +0200 Subject: [PATCH 22/43] comments + cleanup --- lib_rend/ivas_reverb_fx.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index cc572a6f8..d2af846c5 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -663,16 +663,17 @@ static ivas_error compute_t60_coeffs_fx( FOR( bin_idx = 0; bin_idx < tf_T60_len; bin_idx++ ) { - IF( EQ_16( pParams->pRt60_fx[bin_idx], 0 ) ) + IF( EQ_32( pParams->pRt60_fx[bin_idx], 0 ) ) { - target_gains_db_fx[bin_idx] == min120q8; + //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; + target_gains_db_fx[bin_idx] = min120q8; } ELSE { @@ -680,40 +681,33 @@ static ivas_error compute_t60_coeffs_fx( target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 } } - // TODO: check for RT60 not 0, in case of 0, target gain is simply -120 dB - //tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), pParams->pRt60_fx[bin_idx], &e ); - // TODO: check for positive e, otherwise make it -120 dB - //tmp = shr( tmp, add( e, 1 ) ); - //target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720 //targetgains is in Q9 - - // 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 ) - { - target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720 - move16(); - // target_gains_db_exp[bin_idx] = 7; - move16(); - } + // gain < - 120 ? -120: gain + IF(LT_16(target_gains_db_fx[bin_idx], -30720)) + { + target_gains_db_fx[bin_idx] = -30720; + move16(); + } } 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] ); + //Should not be required after condensation + //val = s_max( val, target_gains_db_exp[i] ); } FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) { + //Should not be required after condensation // target_gains_db_fx[i] = shr( target_gains_db_fx[i], sub( val, target_gains_db_exp[i] ) ); move16(); } - // 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 ) ) + //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 ) ) { return error; } -- GitLab From f0bc5589d79eadbb1714bec9d99a72b4acb467ad Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 1 Aug 2025 12:14:03 +0200 Subject: [PATCH 23/43] added comments --- lib_rend/ivas_reverb_fx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index d2af846c5..aef5b3c06 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -694,10 +694,13 @@ static ivas_error compute_t60_coeffs_fx( move16(); + // Word16 val = target_gains_db_exp[0]; + FOR( Word16 i = 1; i < nr_fc_fft_filter; i++ ) { //Should not be required after condensation //val = s_max( val, target_gains_db_exp[i] ); + //val stores the gratest value of target_gains_db_exp } FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) -- GitLab From af338a7dc1bdd771ed0b549f41478ef237125aec Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 1 Aug 2025 15:59:37 +0200 Subject: [PATCH 24/43] cleanup --- lib_rend/ivas_reverb_fx.c | 69 +++++++++------------------------------ 1 file changed, 15 insertions(+), 54 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index aef5b3c06..7fc92de77 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -123,9 +123,7 @@ typedef struct ivas_reverb_params_t Word16 pT60_filter_coeff_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH]; /* Filters [][] in feedback loops, controlling T60. */ 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 */ 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 */ @@ -634,7 +632,6 @@ static ivas_error compute_t60_coeffs_fx( Word32 freq_Nyquist_fx = L_shr( output_Fs, 1 ); 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; Word16 e; const Word16 min120q8 = -30720; // -120 in Q8 @@ -656,8 +653,6 @@ static ivas_error compute_t60_coeffs_fx( 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, &e ); loop_delay_sec_fx = shl( loop_delay_sec_fx, e ); // Q15 @@ -665,7 +660,7 @@ static ivas_error compute_t60_coeffs_fx( { IF( EQ_32( pParams->pRt60_fx[bin_idx], 0 ) ) { - //If RT60 is 0, target gain is -120dB + // If RT60 is 0, target gain is -120dB target_gains_db_fx[bin_idx] = min120q8; } ELSE @@ -678,15 +673,15 @@ static ivas_error compute_t60_coeffs_fx( ELSE { tmp = shr( tmp, add( e, 1 ) ); - target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 + 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(); - } + IF( LT_16( target_gains_db_fx[bin_idx], -30720 ) ) + { + target_gains_db_fx[bin_idx] = -30720; + move16(); + } } pCoeffs_a_fx = &pParams->pT60_filter_coeff_fx[add( shl( i_mult( len, loop_idx ), 1 ), len )]; // Q14 @@ -694,23 +689,9 @@ static ivas_error compute_t60_coeffs_fx( move16(); - // Word16 val = target_gains_db_exp[0]; - - FOR( Word16 i = 1; i < nr_fc_fft_filter; i++ ) - { - //Should not be required after condensation - //val = s_max( val, target_gains_db_exp[i] ); - //val stores the gratest value of target_gains_db_exp - } - - FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ ) - { - //Should not be required after condensation - // 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 ) ) + 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 ) ) { return error; } @@ -1274,8 +1255,7 @@ static void set_reverb_acoustic_data_fx( Word16 bin_idx; Word32 ln_1e6_inverted_fx, delay_diff_fx, L_tmp; Word32 exp_argument_fx, tmp; - Word16 tmp_flag, exp_argument_e; - Word16 pow_exp, tmp_exp; + Word16 pow_exp, exp_argument_e; Word32 *pFc_input_fx = pRoomAcoustics->pFc_input_fx; Word32 *pAcoustic_rt60_fx = pRoomAcoustics->pAcoustic_rt60_fx; @@ -1283,9 +1263,7 @@ 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; // should not be required; Word32 *pDsr_fx = pParams->pDsr_fx; - Word16 *pDsr_e = pParams->pDsr_e; // should not be required /* interpolate input table data for T60 and DSR to the FFT filter grid */ @@ -1482,24 +1460,9 @@ ivas_error ivas_reverb_open_fx( /* 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 ); // Should be removed - Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter ); // Should be removed - - params.pRt60_e = pRt60_e; // Should be removed - params.pDsr_e = pDsr_e; // Should be removed set_reverb_acoustic_data_fx( ¶ms, &hRenderConfig->roomAcoustics, nr_fc_input, nr_fc_fft_filter ); - // Not needed after adjusting the interpolate and scaling functions to output dsr in Q31, T60 in Q26 - /*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; params.pHrtf_inter_aural_coherence_const_fx = hHrtfStatistics->inter_aural_coherence; @@ -1532,8 +1495,8 @@ ivas_error ivas_reverb_open_fx( return error; } /* Compute target levels (gains) for the coloration filters */ - Word32 *pHrtf_avg_pwr_response_l_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); - Word32 *pHrtf_avg_pwr_response_r_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); + Word32 *pHrtf_avg_pwr_response_l_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); // not required + Word32 *pHrtf_avg_pwr_response_r_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); // not required Word16 lenT60_filter_coeff = add( params.t60_filter_order, 1 ); lenT60_filter_coeff = add( i_mult( shl( lenT60_filter_coeff, 1 ), sub( params.nr_loops, 1 ) ), add( lenT60_filter_coeff, 2 ) ); Word32 *pT60_filter_coeff = (Word32 *) malloc( ( lenT60_filter_coeff ) * sizeof( Word32 * ) ); @@ -1541,16 +1504,14 @@ 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] ); // Pointless - should be elminiated if mantissa and exponent notation is removed - move32(); - pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ + pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ // Not required - contamination move32(); - pHrtf_avg_pwr_response_r_const[i] = params.pHrtf_avg_pwr_response_r_const_fx[i]; /*Q23+5*/ + pHrtf_avg_pwr_response_r_const[i] = params.pHrtf_avg_pwr_response_r_const_fx[i]; /*Q23+5*/ // Not required - contamination move32(); } FOR( i = 0; i < lenT60_filter_coeff; i++ ) { - pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); + pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); // needed because calc_color_levels() uses 32-bit representaion of T60_filter_coefficients move32(); } ivas_reverb_calc_color_levels_fx( output_Fs, nr_fc_fft_filter, params.nr_loops, params.pFc_fx, params.pDsr_fx, pHrtf_avg_pwr_response_l_const, pHrtf_avg_pwr_response_r_const, -- GitLab From e4ce3d1798abcbc34e41524b9b65bfe9d8acca47 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Mon, 4 Aug 2025 12:45:53 +0200 Subject: [PATCH 25/43] debugging code + struct ivas_reverb_params_t cleanup --- lib_rend/ivas_reverb_filter_design_fx.c | 12 +++++++++--- lib_rend/ivas_reverb_fx.c | 10 ++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index d2b58b61e..3dd38c06e 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -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(); @@ -738,9 +738,15 @@ void ivas_reverb_calc_color_levels_fx( Word32 H_filter; Word32 T60_est; Word16 temp = 0, result_e = 0; + Word32 temp_32; move16(); move16(); - cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15 + //cos_w calculation has a bug. Values of cosine start at 1, but drop off very fast compared to the floating point variant. + //Cosine multiplicaiton factor is 2*PI in floating point. In this code, it is left shift by 3, which is multiplicaiton by 8. + Word32 PI_2_fx = 1684125261; // 2*PI in Q28 // 1686629713 + temp_32 = Mpy_32_32(fs_inverted, PI_2_fx);//Q26 + //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( Mpy_32_32( pFc[freq_idx], temp_32 ) ) ); 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 ); diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 7fc92de77..061de5872 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -125,9 +125,6 @@ typedef struct ivas_reverb_params_t Word32 *pRt60_fx; /* RT60 values at these frequencies */ Word32 *pDsr_fx; /* DSR values at these frequencies */ - 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 */ - Word32 *pHrtf_inter_aural_coherence_fx; /* The HRTF set's inter-aural coherence for diffuse sound */ const Word32 *pHrtf_avg_pwr_response_l_const_fx; /* The HRTF set's average left ear power response */ const Word32 *pHrtf_avg_pwr_response_r_const_fx; /* The HRTF set's average right ear power response */ const Word32 *pHrtf_inter_aural_coherence_const_fx; /* The HRTF set's inter-aural coherence for diffuse sound */ @@ -1439,12 +1436,9 @@ ivas_error ivas_reverb_open_fx( /* === 'Control logic': compute the reverb processing parameters from the === */ /* === room, source and listener acoustic information provided in the reverb config === */ /* Setting up shared temporary buffers for fc, RT60, DSR, etc. */ - params.pHrtf_avg_pwr_response_l_fx = &pFft_wf_filter_ch0_fx[0][0]; - params.pHrtf_avg_pwr_response_r_fx = params.pHrtf_avg_pwr_response_l_fx + nr_fc_fft_filter; params.pRt60_fx = &pFft_wf_filter_ch1_fx[0][0]; params.pDsr_fx = params.pRt60_fx + nr_fc_fft_filter; params.pFc_fx = &pState->fft_filter_color_0.fft_spectrum_fx[0]; - params.pHrtf_inter_aural_coherence_fx = &pState->fft_filter_color_1.fft_spectrum_fx[0]; set32_fx( pState->fft_filter_color_1.fft_spectrum_fx, 0, RV_FILTER_MAX_FFT_SIZE ); /* Note: these temp buffers can only be used before the final step of the FFT filter design : */ /* before calls to ivas_reverb_calc_correl_filters(...) or to ivas_reverb_calc_color_filters(...) */ @@ -1606,8 +1600,8 @@ ivas_error ivas_reverb_open_fx( move32(); } - Scale_sig32( params.pHrtf_inter_aural_coherence_fx, nr_fc_fft_filter, 4 ); /*Scaling ( *hReverb )->fft_filter_color_0.fft_spectrum_fx to Q31*/ - Scale_sig32( params.pFc_fx, nr_fc_fft_filter, 17 ); /*Scaling ( *hReverb )->fft_filter_color_1.fft_spectrum_fx to Q31*/ + //Scale_sig32( pFft_wf_filter_ch1_fx[0][0], nr_fc_fft_filter, 4 ); /*Scaling ( *hReverb )->fft_filter_color_0.fft_spectrum_fx to Q31*/ + //Scale_sig32( pFft_wf_filter_ch1_fx[0][0], nr_fc_fft_filter, 17 ); /*Scaling ( *hReverb )->fft_filter_color_1.fft_spectrum_fx to Q31*/ /* Copying the computed FFT colorations filters to the fft_filter components */ IF( NE_32( ( error = set_color_fft_filter_fx( pState, 0, pFft_wf_filter_ch0_fx ) ), IVAS_ERR_OK ) ) -- GitLab From 90a372d15378aa5c6f7da4419c415f7e9d3756a5 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Mon, 4 Aug 2025 14:07:01 +0200 Subject: [PATCH 26/43] Fixed bug : cosine value dropoff in cal_color_levels_fx() + cleaned up debugging comments --- lib_rend/ivas_reverb_filter_design_fx.c | 10 +++------- lib_rend/ivas_reverb_fx.c | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 3dd38c06e..792bca942 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 Q14 //Input is actually 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 @@ -741,12 +741,8 @@ void ivas_reverb_calc_color_levels_fx( Word32 temp_32; move16(); move16(); - //cos_w calculation has a bug. Values of cosine start at 1, but drop off very fast compared to the floating point variant. - //Cosine multiplicaiton factor is 2*PI in floating point. In this code, it is left shift by 3, which is multiplicaiton by 8. - Word32 PI_2_fx = 1684125261; // 2*PI in Q28 // 1686629713 - temp_32 = Mpy_32_32(fs_inverted, PI_2_fx);//Q26 - //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( Mpy_32_32( pFc[freq_idx], temp_32 ) ) ); + + 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 ); diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 061de5872..2bc4fc1f9 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1447,7 +1447,7 @@ 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 ) ); /*Q14*/ //Initial comment says Q14, but these values align with floating point only if they are considered to be in Q16 } test(); -- GitLab From 0b0b5d9a117bf115b44a571d9df36ae3dc2b8de0 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Mon, 4 Aug 2025 16:58:56 +0200 Subject: [PATCH 27/43] Debugging code --- lib_rend/ivas_reverb_filter_design_fx.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 792bca942..873251007 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -738,15 +738,25 @@ void ivas_reverb_calc_color_levels_fx( Word32 H_filter; Word32 T60_est; Word16 temp = 0, result_e = 0; - Word32 temp_32; move16(); move16(); 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 + Word32 temp1 = 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 ); + Word32 temp2 = L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ); 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 + + temp1 = L_shr(Mpy_32_32( coefA[1], coefA[1] ), 3);//Q28 + temp2 = Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) );//Q30 + 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 = BASOP_Util_Divide3232_Scale_newton( H_filter, L_add( ONE_IN_Q28, L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) , 1 ) ) ), &temp ); + H_filter = Sqrt32( H_filter, &temp ); - T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. + + T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ) , &temp ); // conversion of log2 to log10. t60[freq_idx] = BASOP_Util_Add_Mant32Exp( T60_est, temp, t60[freq_idx], t60_e[freq_idx], &result_e ); move16(); t60_e[freq_idx] = result_e; -- GitLab From 7516c0baefe86e3b8bc541b28442337cd6622249 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 5 Aug 2025 18:59:52 +0200 Subject: [PATCH 28/43] Debugging code for H_filter --- lib_rend/ivas_reverb_filter_design_fx.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 873251007..d4f0db9c4 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -748,15 +748,25 @@ void ivas_reverb_calc_color_levels_fx( Word32 temp2 = L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ); 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 - temp1 = L_shr(Mpy_32_32( coefA[1], coefA[1] ), 3);//Q28 - temp2 = Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) );//Q30 + //temp1 = L_shr(Mpy_32_32( coefA[1], coefA[1] ), 3);//Q28 + temp1 = Mpy_32_32( coefA[1], coefA[1] ); //Q31 + temp2 = L_shl(L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1), 1);//Q31 + // temp2 = L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1);//Q31 + Word32 temp3 = L_add( ONE_IN_Q31, L_add(temp1,temp2) );//Q31 -> aligns with correct result + temp3 = BASOP_Util_Divide3232_Scale_newton( H_filter,temp3, &temp );//Q28 divided by Q31, should be in Q28 + temp3 = L_shr( temp3, 1 ); //Q31 // Or change L_shl after ONE_IN_Q31?? + temp3 = Sqrt32( temp3, &temp );//Q31 + H_filter = temp3;//Q31 + //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 ); + + temp1 = BASOP_Util_Log2( H_filter ); + temp1 = Mpy_32_32(BASOP_Util_Log2( H_filter ), LOG10_2_Q31);//log10(H_filter) in Q25 + //temp1 = Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ); - 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 = BASOP_Util_Divide3232_Scale_newton( H_filter, L_add( ONE_IN_Q28, L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) , 1 ) ) ), &temp ); - - H_filter = Sqrt32( H_filter, &temp ); T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ) , &temp ); // conversion of log2 to log10. + t60[freq_idx] = BASOP_Util_Add_Mant32Exp( T60_est, temp, t60[freq_idx], t60_e[freq_idx], &result_e ); move16(); t60_e[freq_idx] = result_e; -- GitLab From 63ce43bf098e72cb4452bc244aa5d8c9f24bf0a9 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:58:17 +0200 Subject: [PATCH 29/43] debugging code --- lib_rend/ivas_reverb_filter_design_fx.c | 42 +++++++++++++++---------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index d4f0db9c4..a4c215bdb 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -743,27 +743,37 @@ void ivas_reverb_calc_color_levels_fx( 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 - Word32 temp1 = 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 ); - Word32 temp2 = L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ); + Word32 temp1, temp2, temp3; + //Word32 temp1 = 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 ); + //Word32 temp2 = L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ); + 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 - //temp1 = L_shr(Mpy_32_32( coefA[1], coefA[1] ), 3);//Q28 - temp1 = Mpy_32_32( coefA[1], coefA[1] ); //Q31 - temp2 = L_shl(L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1), 1);//Q31 - // temp2 = L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1);//Q31 - Word32 temp3 = L_add( ONE_IN_Q31, L_add(temp1,temp2) );//Q31 -> aligns with correct result - temp3 = BASOP_Util_Divide3232_Scale_newton( H_filter,temp3, &temp );//Q28 divided by Q31, should be in Q28 - temp3 = L_shr( temp3, 1 ); //Q31 // Or change L_shl after ONE_IN_Q31?? - temp3 = Sqrt32( temp3, &temp );//Q31 - H_filter = temp3;//Q31 + //temp1 = Mpy_32_32( coefA[1], coefA[1] ); //Q31 + //temp2 = L_shl(L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1), 1);//Q31 + //Word32 temp3 = L_add( ONE_IN_Q31, L_add(temp1,temp2) );//Q31 -> aligns with correct result + //temp3 = BASOP_Util_Divide3232_Scale_newton( H_filter,temp3, &temp );//Q28 divided by Q31, should be in Q28 + //temp3 = L_shr( temp3, 1 ); //Q31 // Or change L_shl after ONE_IN_Q31?? + //temp3 = Sqrt32( temp3, &temp );//Q31 + //H_filter = temp3;//Q31 + + temp1 = Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) );//Q30 + //temp1 = L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ),1); //2.0f * coefA[1] * cos_w in Q30 + temp1 = L_shl_sat(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ),2); //2.0f * coefA[1] * cos_w in Q31 + temp1 = L_shr( temp1, 3 );//temp1 in Q28 + temp2 = Mpy_32_32( coefA[1], coefA[1] ); // coefA[1] * coefA[1} in Q31 -> must right shift by 3 + temp2 = L_shr(temp2,3)//temp1 in Q28 +; + temp3 = L_add( ONE_IN_Q28, L_add(temp1, temp2)); + H_filter = BASOP_Util_Divide3232_Scale_newton( H_filter, temp3, &temp ); //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 ); + H_filter = Sqrt32( H_filter, &temp ); - temp1 = BASOP_Util_Log2( H_filter ); - temp1 = Mpy_32_32(BASOP_Util_Log2( H_filter ), LOG10_2_Q31);//log10(H_filter) in Q25 + //temp1 = BASOP_Util_Log2( H_filter ); + //temp1 = Mpy_32_32(BASOP_Util_Log2( H_filter ), LOG10_2_Q31);//log10(H_filter) in Q25 //temp1 = Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ); - + //temp1 = Mpy_32_32( temp1, L_shl(output_Fs,15) );//Denominator in Q9 + //temp2 = i_mult( -3, pLoop_delays[loop_idx] ); T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ) , &temp ); // conversion of log2 to log10. -- GitLab From ae34214b641a3f8ff02f1cbcc179a717a03a7622 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Thu, 7 Aug 2025 12:00:28 +0200 Subject: [PATCH 30/43] cleanup debugging code --- lib_rend/ivas_reverb_filter_design_fx.c | 38 ++----------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index a4c215bdb..c5f76f4e9 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -740,43 +740,11 @@ 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 ), 1 ) ) ); // q = 15 - - Word32 temp1, temp2, temp3; - //Word32 temp1 = 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 ); - //Word32 temp2 = L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ); - + 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 - - //temp1 = Mpy_32_32( coefA[1], coefA[1] ); //Q31 - //temp2 = L_shl(L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ), 1), 1);//Q31 - //Word32 temp3 = L_add( ONE_IN_Q31, L_add(temp1,temp2) );//Q31 -> aligns with correct result - //temp3 = BASOP_Util_Divide3232_Scale_newton( H_filter,temp3, &temp );//Q28 divided by Q31, should be in Q28 - //temp3 = L_shr( temp3, 1 ); //Q31 // Or change L_shl after ONE_IN_Q31?? - //temp3 = Sqrt32( temp3, &temp );//Q31 - //H_filter = temp3;//Q31 - - temp1 = Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) );//Q30 - //temp1 = L_shl(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ),1); //2.0f * coefA[1] * cos_w in Q30 - temp1 = L_shl_sat(Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ),2); //2.0f * coefA[1] * cos_w in Q31 - temp1 = L_shr( temp1, 3 );//temp1 in Q28 - temp2 = Mpy_32_32( coefA[1], coefA[1] ); // coefA[1] * coefA[1} in Q31 -> must right shift by 3 - temp2 = L_shr(temp2,3)//temp1 in Q28 -; - temp3 = L_add( ONE_IN_Q28, L_add(temp1, temp2)); - H_filter = BASOP_Util_Divide3232_Scale_newton( H_filter, temp3, &temp ); - //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 = 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 ); - - //temp1 = BASOP_Util_Log2( H_filter ); - //temp1 = Mpy_32_32(BASOP_Util_Log2( H_filter ), LOG10_2_Q31);//log10(H_filter) in Q25 - //temp1 = Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ); - //temp1 = Mpy_32_32( temp1, L_shl(output_Fs,15) );//Denominator in Q9 - //temp2 = i_mult( -3, pLoop_delays[loop_idx] ); - - T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ) , &temp ); // conversion of log2 to log10. - + T60_est = BASOP_Util_Divide3232_Scale_newton( L_shl( i_mult( -3, pLoop_delays[loop_idx] ), 2 ), Mpy_32_32( Mpy_32_32( L_add( BASOP_Util_Log2( H_filter ), L_shl( temp, 25 ) ), LOG10_2_Q31 ), L_shl( output_Fs, 8 ) ), &temp ); // conversion of log2 to log10. t60[freq_idx] = BASOP_Util_Add_Mant32Exp( T60_est, temp, t60[freq_idx], t60_e[freq_idx], &result_e ); move16(); t60_e[freq_idx] = result_e; -- GitLab From 410113e05acb5eada0199cf526613fa638e0dc60 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 12:34:08 +0200 Subject: [PATCH 31/43] Fixed bug for scaling tmp to q15 --- lib_rend/ivas_reverb_fx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 2bc4fc1f9..5d6e455b3 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -669,7 +669,8 @@ static ivas_error compute_t60_coeffs_fx( } ELSE { - tmp = shr( tmp, add( e, 1 ) ); + //tmp = shr( tmp, add( e, 1 ) ); -> does not work, because e is computed as an offset from 20?? Therefore the offset must be adjusted wrt 20 + tmp = shr( tmp, sub( 5, e ) );//scaling tmp to Q15 target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 } } -- GitLab From 1c0df57a47c4fc063e61e50aa87d2afde516ec60 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 14:44:45 +0200 Subject: [PATCH 32/43] Fixed scaling factor for inter_aural_coherence_const in ivas_reverb_fx.c --- lib_rend/ivas_reverb_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 5d6e455b3..170a18311 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1550,7 +1550,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 ); -- GitLab From d99c95ca03231cab778edd01fd52c452334046d5 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:26:58 +0200 Subject: [PATCH 33/43] comments for scaling operations --- lib_rend/ivas_reverb_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 170a18311..74c67e028 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1559,16 +1559,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 */ -- GitLab From 0907319797ad4ac6a42872053744f5bbaa777b8e Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:39:05 +0200 Subject: [PATCH 34/43] comment cleanup --- lib_rend/ivas_reverb_fx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 74c67e028..4544e20b1 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1601,9 +1601,6 @@ ivas_error ivas_reverb_open_fx( move32(); } - //Scale_sig32( pFft_wf_filter_ch1_fx[0][0], nr_fc_fft_filter, 4 ); /*Scaling ( *hReverb )->fft_filter_color_0.fft_spectrum_fx to Q31*/ - //Scale_sig32( pFft_wf_filter_ch1_fx[0][0], nr_fc_fft_filter, 17 ); /*Scaling ( *hReverb )->fft_filter_color_1.fft_spectrum_fx to Q31*/ - /* Copying the computed FFT colorations filters to the fft_filter components */ IF( NE_32( ( error = set_color_fft_filter_fx( pState, 0, pFft_wf_filter_ch0_fx ) ), IVAS_ERR_OK ) ) { -- GitLab From 8560d4fa262dab3466072f8d2674cffc82465086 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:50:06 +0200 Subject: [PATCH 35/43] pulled latest changes from main --- lib_rend/ivas_reverb_fx.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index cbc982e83..561bf7a5b 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -120,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 */ -- GitLab From 456adba60efb2c3ce6b5c904b0c2b43f209105cc Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:54:23 +0200 Subject: [PATCH 36/43] clang patch --- lib_rend/ivas_reverb_fx.c | 14 +++++------ lib_rend/ivas_reverb_utils_fx.c | 44 ++++++++++++++++----------------- lib_util/render_config_reader.c | 4 +-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 561bf7a5b..0c1556638 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -678,8 +678,8 @@ static ivas_error compute_t60_coeffs_fx( } ELSE { - //tmp = shr( tmp, add( e, 1 ) ); -> does not work, because e is computed as an offset from 20?? Therefore the offset must be adjusted wrt 20 - tmp = shr( tmp, sub( 5, e ) );//scaling tmp to Q15 + // tmp = shr( tmp, add( e, 1 ) ); -> does not work, because e is computed as an offset from 20?? Therefore the offset must be adjusted wrt 20 + tmp = shr( tmp, sub( 5, e ) ); // scaling tmp to Q15 target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 } } @@ -1509,7 +1509,7 @@ 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*/ //Initial comment says Q14, but these values align with floating point only if they are considered to be in Q16 + params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q14*/ // Initial comment says Q14, but these values align with floating point only if they are considered to be in Q16 } test(); @@ -1647,16 +1647,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 ) );//Scale to Q31 + 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 ) );//Scale to Q31 + 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 ) );//Scale to Q31 + 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 ) );//Scale to Q31 + 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 */ diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 8b7927587..4690210a2 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -43,7 +43,7 @@ * Local constants *-----------------------------------------------------------------------------------------*/ -#define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) ) +#define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) ) /*-----------------------------------------------------------------------------------------* * Local function prototypes @@ -84,11 +84,11 @@ ivas_error ivas_reverb_prepare_cldfb_params( output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) ); } - 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 + 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 ); //Q27 + delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); // Q27 ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */ @@ -96,11 +96,11 @@ ivas_error ivas_reverb_prepare_cldfb_params( { L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // L_tmp in Q26 - exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp ); //exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) - exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); //exp_argument_L_fx in Q26 + exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp ); // exp_argument_L_fx in Q30 (not alwys, because tmp_exp values are not constant) + exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); // exp_argument_L_fx in 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 + IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 { exp_argument_fx = 1543503872; } @@ -109,31 +109,31 @@ ivas_error ivas_reverb_prepare_cldfb_params( exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 - L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); //Q28 -> not always, because pow_exp is not fixed - L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); //Q27 if result of previous step is in Q28 - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); //L_tmp in Q31 + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); // Q28 -> not always, because pow_exp is not fixed + L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); // Q27 if result of previous step is in Q28 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // L_tmp in Q31 - //Assign energy to output pointer + // Assign energy to output pointer pOutput_ene[idx] = L_tmp; move32(); - //Assign t60 to output pointer - pOutput_t60[idx] = output_t60_fx[idx]; //Q26 + // Assign t60 to output pointer + 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_fx, avg_pwr_right_fx ); //This function returns avg powers for left and right in Q28 -> why?? how?? + ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); // This function returns avg powers for left and right in Q28 -> why?? how?? FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { 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 - //Scale final output to Q31 for compatibility with further computations - pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); //Q31 + 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 + // Scale final output to Q31 for compatibility with further computations + pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); // Q31 } return IVAS_ERR_OK; @@ -204,9 +204,9 @@ static void ivas_reverb_set_energies( #ifdef FIX_1741_REVERB_TIMES_Q_FORMAT - //Avg Energy Left + // 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 + // 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 ); #endif diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 54e7efc34..0eae82e37 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2805,8 +2805,8 @@ ivas_error RenderConfigReader_getAcousticEnvironment( { pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands; pAcEnv->inputPreDelay_fx = (Word32) ( pRenderConfigReader->pAE[n].preDelay * ONE_IN_Q27 ); - if (pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || - pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN) + if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX || + pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN ) { return IVAS_ERR_INVALID_RENDER_CONFIG; } -- GitLab From 58c3c80f65ac541ae5a0e87286b2e3f941bf1c27 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:15:34 +0200 Subject: [PATCH 37/43] Fixed Q format and cleaned up interpolate_acoustic_data() --- lib_rend/ivas_reverb_filter_design_fx.c | 12 +++--------- lib_rend/ivas_reverb_utils_fx.c | 1 - 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index c5f76f4e9..9677eb92e 100644 --- a/lib_rend/ivas_reverb_filter_design_fx.c +++ b/lib_rend/ivas_reverb_filter_design_fx.c @@ -872,8 +872,6 @@ void ivas_reverb_interp_on_freq_grid_fx( move16(); rel_offset = 0; move32(); - rel_offset_e = 0; - move16(); } ELSE { @@ -882,10 +880,8 @@ void ivas_reverb_interp_on_freq_grid_fx( { input_idx = sub( input_grid_size, 2 ); input_idx_next = add( input_idx, 1 ); - rel_offset = ONE_IN_Q15; + rel_offset = ONE_IN_Q31; move32(); - rel_offset_e = 1; - move16(); } /* otherwise use linear interpolation between 2 consecutive points in the input table */ ELSE @@ -895,10 +891,8 @@ void ivas_reverb_interp_on_freq_grid_fx( input_idx = add( input_idx, 1 ); } 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 + 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(); + 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 } } diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 4690210a2..6a0988643 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -85,7 +85,6 @@ ivas_error ivas_reverb_prepare_cldfb_params( } 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 ); // Q27 -- GitLab From b50e43490c6a45bc461a80d6781d41125ddee78a Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 12 Aug 2025 15:10:35 +0200 Subject: [PATCH 38/43] Fixed accidental code removal --- lib_rend/ivas_reverb_utils_fx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 6a0988643..1521b4bae 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -85,6 +85,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( } 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 ); // Q27 -- GitLab From 5058b1d60e3bc13f961aca04a0b0438233903443 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Tue, 12 Aug 2025 15:31:15 +0200 Subject: [PATCH 39/43] clang patch --- lib_rend/ivas_reverb_utils_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 1521b4bae..4690210a2 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -85,7 +85,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( } 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 + 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 ); // Q27 -- GitLab From 3c5aa0b390de1f2ab99c1943603e770ba0a865c8 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:08:07 +0200 Subject: [PATCH 40/43] cleaned up comments + latest merge from main --- lib_rend/ivas_reverb_fx.c | 26 +++++++++++++------------- lib_rend/ivas_reverb_utils_fx.c | 21 +++++++++------------ 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index db11250b5..2aef8253c 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1278,27 +1278,27 @@ static void set_reverb_acoustic_data_fx( 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 ); // L_tmp in Q26 + L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); //Q26 // exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// 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 ) ); // exp_argument_fx in Q26 - verified + 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 + IF( GT_32( exp_argument_fx, 1543503872 ) ) //23 in Q26 { exp_argument_fx = 1543503872; } - IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26 + IF( LT_32( exp_argument_fx, -1543503872 ) ) //23 in Q26 { exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 - L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); // Q28 -> not always, because pow_exp is not fixed - L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); // Q27 if result of previous step is in Q28 - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // L_tmp in Q31 + L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); + L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] ); + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); //Q31 pDsr_fx[bin_idx] = L_tmp; move32(); @@ -1550,8 +1550,8 @@ ivas_error ivas_reverb_open_fx( return error; } /* Compute target levels (gains) for the coloration filters */ - Word32 *pHrtf_avg_pwr_response_l_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); // not required - Word32 *pHrtf_avg_pwr_response_r_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); // not required + Word32 *pHrtf_avg_pwr_response_l_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); + Word32 *pHrtf_avg_pwr_response_r_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 * ) ); Word16 lenT60_filter_coeff = add( params.t60_filter_order, 1 ); lenT60_filter_coeff = add( i_mult( shl( lenT60_filter_coeff, 1 ), sub( params.nr_loops, 1 ) ), add( lenT60_filter_coeff, 2 ) ); Word32 *pT60_filter_coeff = (Word32 *) malloc( ( lenT60_filter_coeff ) * sizeof( Word32 * ) ); @@ -1559,14 +1559,14 @@ ivas_error ivas_reverb_open_fx( FOR( i = 0; i < nr_fc_fft_filter; i++ ) { - pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/ // Not required - contamination + 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*/ // Not required - contamination + pHrtf_avg_pwr_response_r_const[i] = params.pHrtf_avg_pwr_response_r_const_fx[i]; /*Q23+5*/ move32(); } FOR( i = 0; i < lenT60_filter_coeff; i++ ) { - pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); // needed because calc_color_levels() uses 32-bit representaion of T60_filter_coefficients + pT60_filter_coeff[i] = L_shl_sat( params.pT60_filter_coeff_fx[i], 17 ); move32(); } ivas_reverb_calc_color_levels_fx( output_Fs, nr_fc_fft_filter, params.nr_loops, params.pFc_fx, params.pDsr_fx, pHrtf_avg_pwr_response_l_const, pHrtf_avg_pwr_response_r_const, diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index af5092c99..3d4197640 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -94,10 +94,10 @@ ivas_error ivas_reverb_prepare_cldfb_params( FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { - L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // L_tmp in Q26 + 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_L_fx in Q30 (not alwys, because tmp_exp values are not constant) - exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); // exp_argument_L_fx in 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 */ IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 @@ -109,21 +109,19 @@ ivas_error ivas_reverb_prepare_cldfb_params( exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21 -> multiplication of Q26 by Q26 // x * 1/ln(2) it is ensured that exp_argument_fx is always in Q26 + tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 - L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp ); // Q28 -> not always, because pow_exp is not fixed - L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] ); // Q27 if result of previous step is in Q28 - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // L_tmp in Q31 + 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 - // Assign energy to output pointer - pOutput_ene[idx] = L_tmp; + pOutput_ene[idx] = L_tmp; //Q31 move32(); - // Assign t60 to output pointer 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_fx, avg_pwr_right_fx ); // This function returns avg powers for left and right in Q28 -> why?? how?? + 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++ ) { @@ -132,7 +130,6 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 - // Scale final output to Q31 for compatibility with further computations pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); // Q31 } -- GitLab From faf8b55309574658b5c220b0f196e3a82618f25d Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:10:20 +0200 Subject: [PATCH 41/43] clang fix in reverb_utils_fx.c --- lib_rend/ivas_reverb_utils_fx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index 3d4197640..a408e2fcc 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -97,7 +97,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 + 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 */ IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 @@ -130,7 +130,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 + pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); // Q31 } return IVAS_ERR_OK; -- GitLab From 15ee35e76b79aa57e9ac0820dbe6f34ae04cf46d Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 20 Aug 2025 10:38:29 +0200 Subject: [PATCH 42/43] clang patch --- lib_rend/ivas_reverb_fx.c | 12 ++++++------ lib_rend/ivas_reverb_utils_fx.c | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 2aef8253c..33c4472f0 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -1278,27 +1278,27 @@ static void set_reverb_acoustic_data_fx( 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 ); //Q26 + L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // Q26 // exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// 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 + 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 + IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 { exp_argument_fx = 1543503872; } - IF( LT_32( exp_argument_fx, -1543503872 ) ) //23 in Q26 + IF( LT_32( exp_argument_fx, -1543503872 ) ) // 23 in Q26 { exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 + 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] ); - L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); //Q31 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31 pDsr_fx[bin_idx] = L_tmp; move32(); diff --git a/lib_rend/ivas_reverb_utils_fx.c b/lib_rend/ivas_reverb_utils_fx.c index a408e2fcc..553dbdb0a 100644 --- a/lib_rend/ivas_reverb_utils_fx.c +++ b/lib_rend/ivas_reverb_utils_fx.c @@ -97,7 +97,7 @@ ivas_error ivas_reverb_prepare_cldfb_params( 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 + 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 */ IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26 @@ -109,19 +109,19 @@ ivas_error ivas_reverb_prepare_cldfb_params( exp_argument_fx = -1543503872; } - tmp = Mpy_32_32( 96817114, exp_argument_fx ); //Q21 + 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 + L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31 - pOutput_ene[idx] = L_tmp; //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_fx, avg_pwr_right_fx ); //Q28 + 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++ ) { -- GitLab From 1218a00e6d2a5414277a6e4b10ed4609db25de63 Mon Sep 17 00:00:00 2001 From: Devansh Kandpal <43807487+mrkandpal@users.noreply.github.com> Date: Wed, 20 Aug 2025 13:15:23 +0200 Subject: [PATCH 43/43] cleaned up comments --- lib_rend/ivas_reverb_filter_design_fx.c | 2 +- lib_rend/ivas_reverb_fx.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_reverb_filter_design_fx.c b/lib_rend/ivas_reverb_filter_design_fx.c index 9677eb92e..e826596ba 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 //Input is actually in Q16 + 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 diff --git a/lib_rend/ivas_reverb_fx.c b/lib_rend/ivas_reverb_fx.c index 33c4472f0..8d54c39ff 100644 --- a/lib_rend/ivas_reverb_fx.c +++ b/lib_rend/ivas_reverb_fx.c @@ -670,7 +670,6 @@ static ivas_error compute_t60_coeffs_fx( } ELSE { - // tmp = shr( tmp, add( e, 1 ) ); -> does not work, because e is computed as an offset from 20?? Therefore the offset must be adjusted wrt 20 tmp = shr( tmp, sub( 5, e ) ); // scaling tmp to Q15 target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8 } @@ -1280,7 +1279,6 @@ static void set_reverb_acoustic_data_fx( { L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // Q26 - // exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );// 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 @@ -1501,7 +1499,7 @@ 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*/ // Initial comment says Q14, but these values align with floating point only if they are considered to be in Q16 + params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q16*/ } test(); -- GitLab