Skip to content
......@@ -229,7 +229,11 @@ static void sincResample_fx(
/* Calculate the sinc-index for the center value of the sinc */
Word16 center_val_e;
Word64 center_val;
#ifndef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
center_val = W_sub( t_frac_plus_eps, W_shl( t, sub( 31, t_frac_plus_eps_e ) ) ); // exp(center_val_e)
#else
center_val = W_sub( t_frac_plus_eps, W_shl( t, s_min( sub( 31, t_frac_plus_eps_e ), 63 ) ) ); // exp( center_val_e )
#endif
center_val_e = add( t_frac_plus_eps_e, 6 );
Word16 com_e = s_max( 0, center_val_e );
center_val = W_add( W_shr( center_val, sub( com_e, center_val_e ) ), W_shl( 1, sub( 30, com_e ) ) ); // exp(center_val_e)
......
......@@ -308,8 +308,13 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx(
/* o : ITD value */ // Q0
Word32 *Gain,
/* o : Gain value */ // Q30
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
TDREND_SRC_t *Src_p /* i/o: Source pointer */
#else
TDREND_SRC_t *Src_p, /* i/o: Source pointer */
const Word16 subframe_update_flag )
const Word16 subframe_update_flag
#endif
)
{
TDREND_MIX_Listener_t *Listener_p;
TDREND_HRFILT_FiltSet_t *HrFiltSet_p;
......@@ -469,7 +474,12 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx(
}
test();
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
IF( ( *intp_count > 0 ) )
#else
IF( ( *intp_count > 0 ) && subframe_update_flag )
#endif
{
/* Set deltas for interpolation */
Word16 tmp_e;
......
......@@ -75,6 +75,12 @@ Word16 ivas_get_nchan_buffers_dec_fx(
const Word32 ivas_total_brate /* i : total IVAS bitrate */
);
/*! r: flag to indicate if split rendering is enabled */
Word16 is_split_rendering_enabled(
const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
const IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* i : Render config data structure */
);
ivas_error get_channel_config(
const AUDIO_CONFIG config, /* i : audio configuration */
Word8 *str /* o : string with the configuration name */
......@@ -699,8 +705,12 @@ ivas_error TDREND_GetMix_fx(
BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
Word32 *output[], /* i/o: ISM object synth / rendered output in 0,1 */
const Word16 subframe_length, /* i/o: subframe length Q11 */
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
const Word16 subframe_idx /* i : Subframe index to 5 ms subframe */
#else
const Word16 subframe_idx, /* i : Subframe index to 5 ms subframe */
const Word16 ism_md_subframe_update /* i : Number of subframes to delay ism metadata to sync with audio */
#endif
);
void BSplineModelEvalDealloc_fx(
......@@ -785,8 +795,13 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx(
Word16 *filterlength, /* o : Length of filters */
Word16 *itd, /* o : ITD value */
Word32 *Gain, /* o : Gain value Q30 */
#ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
TDREND_SRC_t *Src_p /* i/o: Source pointer */
#else
TDREND_SRC_t *Src_p, /* i/o: Source pointer */
const Word16 subframe_update_flag);
const Word16 subframe_update_flag /* i : Flag to determine update subframe idx */
#endif
);
ivas_error TDREND_SRC_Alloc(
TDREND_SRC_t **Src_pp /* i/o: Source */
......@@ -1099,35 +1114,21 @@ void ivas_reverb_calc_color_levels_fx(
const Word32 *pT60_filter_coeff, //input in Q31
Word32 *pTarget_color_L, //output in Q30
Word32 *pTarget_color_R); //output in Q30
ivas_error ivas_reverb_prepare_cldfb_params(
const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params,
const HRTFS_STATISTICS_HANDLE hHrtfStatistics,
const int32_t output_Fs,
float *pOutput_t60,
float *pOutput_ene );
void ivas_reverb_interpolate_acoustic_data_fx(
const Word16 input_table_size,
const Word32 *pInput_fc, //input in Q16
const Word32 *pInput_t60, //input in Q26
const Word32 *pInput_dsr, //input in Q30
const Word16 output_table_size,
const Word32 *pOutput_fc,
const Word32 output_Fs,
Word32 *pOutput_t60,
Word32 *pOutput_dsr,
Word16 *pOutput_t60_e, //output e
Word16 *pOutput_dsr_e //output e
);
void ivas_reverb_interpolate_energies_fx(
Word32 *pOutput_ene );
void ivas_reverb_interp_on_freq_grid_fx(
const Word16 input_table_size,
const Word32 *pInput_fc, //input in Q16
const Word32 *pInput_ene_l, //input in Q28
const Word32 *pInput_ene_r, //input in Q28
const Word32 *pInput_fc, //input center frequencies in Q16
const Word32 *pInput_grid, //input data vector in an arbitrary Q-format
const Word16 output_table_size,
const Word32 *pOutput_fc,
Word32 *pOutput_ene_l_m, // output m
Word32 *pOutput_ene_r_m, // output m
Word16 *pOutput_ene_l_e, //output e
Word16 *pOutput_ene_r_e //output e
Word32 *pOutput_grid //output in the same Q-format as input
);
/*---------------------------------------------------------------------------------*
* Shoebox Prototypes
......
......@@ -671,7 +671,7 @@ void ivas_reverb_calc_color_levels_fx(
const Word32 output_Fs,
const Word16 freq_count,
const Word16 loop_count,
const Word32 *pFc, // input in Q14
const Word32 *pFc, // input in Q16
const Word32 *pAcoustic_dsr, // input in Q31
const Word32 *pHrtf_avg_pwr_L, // input in Q28
const Word32 *pHrtf_avg_pwr_R, // input in Q28
......@@ -689,8 +689,8 @@ void ivas_reverb_calc_color_levels_fx(
/* Pre-computing inverse values for optimisation (to avoid divisions in inner loops) */
Word16 fs_inverted_q;
const Word32 fs_inverted = BASOP_Util_Divide3232_Scale( ONE_IN_Q11, L_shl( output_Fs, 11 ), &fs_inverted_q ); // q= 15 - fs_inverted_q = 29
const Word32 loop_count_inverted = divide3232( ONE_IN_Q27, L_shl( loop_count, 27 ) ); // q= 15;
const Word32 fs_inverted = BASOP_Util_Divide3232_Scale( ONE_IN_Q11, L_shl( output_Fs, 11 ), &fs_inverted_q ); // q= 15 - fs_inverted_q = 29//Q29
const Word32 loop_count_inverted = divide3232( ONE_IN_Q27, L_shl( loop_count, 27 ) ); // q= 15;Q15
const Word32 log__0_001 = -1854286438; // logf( 0.001f ) in q28
move32();
......@@ -740,7 +740,7 @@ void ivas_reverb_calc_color_levels_fx(
Word16 temp = 0, result_e = 0;
move16();
move16();
cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 3 ) ) ); // q = 15
cos_w = getCosWord16R2( (Word16) L_abs( L_shl( Mpy_32_32( pFc[freq_idx], fs_inverted ), 1 ) ) ); // q = 15
H_filter = L_add( L_shr( L_add( L_shr( Mpy_32_32( coefB[0], coefB[0] ), 1 ), L_shr( Mpy_32_32( coefB[1], coefB[1] ), 1 ) ), 2 ), L_shr( Mpy_32_32( coefB[0], Mpy_32_32( coefB[1], L_shl( cos_w, 15 ) ) ), 1 ) ); // q = 28
H_filter = BASOP_Util_Divide3232_Scale_newton( H_filter, L_add( ONE_IN_Q28, L_shr( L_add( L_shr( Mpy_32_32( coefA[1], coefA[1] ), 2 ), Mpy_32_32( coefA[1], L_shl( cos_w, 15 ) ) ), 1 ) ), &temp );
H_filter = Sqrt32( H_filter, &temp );
......@@ -839,135 +839,49 @@ void ivas_reverb_calc_color_levels_fx(
}
/*-------------------------------------------------------------------*
* ivas_reverb_interpolate_acoustic_data_fx()
* ivas_reverb_interp_on_freq_grid_fx()
*
* Interpolates data from the input T60 and DSR tables to the FFT pFilter uniform grid
* Interpolates data from an input grid of center frequencies to an output grid of center frequencies
* Note: the fc frequencies both for the input and the output must be in the ascending order
*-------------------------------------------------------------------*/
void ivas_reverb_interpolate_acoustic_data_fx(
const Word16 input_table_size,
const Word32 *pInput_fc, // input in Q16
const Word32 *pInput_t60, // input in Q26
const Word32 *pInput_dsr, // input in Q30
const Word16 output_table_size,
const Word32 *pOutput_fc, // Q16
Word32 *pOutput_t60, // pOutput_t60_e
Word32 *pOutput_dsr, // pOutput_dsr_e
Word16 *pOutput_t60_e, // output e
Word16 *pOutput_dsr_e // output e
void ivas_reverb_interp_on_freq_grid_fx(
const Word16 input_grid_size,
const Word32 *pInput_fc, // input center frequencies in Q16
const Word32 *pInput_data, // input data vector in an arbitrary Q-format
const Word16 output_grid_size,
const Word32 *pOutput_fc,
Word32 *pOutput_data // output data vector in the same Q-format as input
)
{
Word16 input_idx, output_idx;
Word16 input_idx, input_idx_next, output_idx;
Word32 rel_offset;
Word16 rel_offset_e;
input_idx = 0;
input_idx_next = 0;
move16();
FOR( output_idx = 0; output_idx < output_table_size; output_idx++ )
{
/* if the bin frequency is lower than the 1st frequency point in the input table, take this 1st point */
IF( LT_32( pOutput_fc[output_idx], pInput_fc[0] ) )
{
input_idx = 0;
move16();
rel_offset = 0;
move32();
rel_offset_e = 0;
move16();
}
ELSE
{
/* if the bin frequency is higher than the last frequency point in the input table, take this last point */
IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_table_size - 1] ) )
{
input_idx = sub( input_table_size, 2 );
rel_offset = ONE_IN_Q30; // Q30;
move32();
rel_offset_e = 1;
move16();
}
/* otherwise use linear interpolation between 2 consecutive points in the input table */
ELSE
{
WHILE( GT_32( pOutput_fc[output_idx], pInput_fc[input_idx + 1] ) )
{
input_idx = add( input_idx, 1 );
}
rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx + 1], pInput_fc[input_idx] ), &rel_offset_e ); // q15
rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) );
rel_offset_e = 0;
move16();
}
}
Word32 mult1;
Word16 mult_e = 0;
move16();
mult1 = Mpy_32_32( rel_offset, L_sub( pInput_t60[input_idx + 1], pInput_t60[input_idx] ) );
pOutput_t60[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_t60[input_idx], 5, mult1, add( 5, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 26 - 31)
move32();
pOutput_t60_e[output_idx] = mult_e;
move16();
mult1 = Mpy_32_32( rel_offset, L_sub( pInput_dsr[input_idx + 1], pInput_dsr[input_idx] ) );
pOutput_dsr[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_dsr[input_idx], 1, mult1, add( 1, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 26 - 31)
move32();
pOutput_dsr_e[output_idx] = mult_e;
move16();
}
return;
}
/*-------------------------------------------------------------------*
* ivas_reverb_interpolate_energies_fx()
*
* Interpolates data from the input average energy to the FFT pFilter uniform grid
* Note: the fc frequencies both for the input and the output must be in the ascending order
*-------------------------------------------------------------------*/
void ivas_reverb_interpolate_energies_fx(
const Word16 input_table_size,
const Word32 *pInput_fc, // input in Q16
const Word32 *pInput_ene_l, // input in Q28
const Word32 *pInput_ene_r, // input in Q28
const Word16 output_table_size,
const Word32 *pOutput_fc, // Q16
Word32 *pOutput_ene_l_m,
Word32 *pOutput_ene_r_m,
Word16 *pOutput_ene_l_e,
Word16 *pOutput_ene_r_e )
{
Word16 input_idx, output_idx;
Word32 rel_offset;
Word16 rel_offset_e;
input_idx = 0;
move16();
FOR( output_idx = 0; output_idx < output_table_size; output_idx++ )
FOR( output_idx = 0; output_idx < output_grid_size; output_idx++ )
{
/* if the bin frequency is lower than the 1st frequency point in the input table, take this 1st point */
IF( LT_32( pOutput_fc[output_idx], pInput_fc[0] ) )
{
input_idx = 0;
move16();
input_idx_next = 0;
move16();
rel_offset = 0;
move32();
rel_offset_e = 0;
move16();
}
ELSE
{
/* if the bin frequency is higher than the last frequency point in the input table, take this last point */
IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_table_size - 1] ) )
IF( GT_32( pOutput_fc[output_idx], pInput_fc[input_grid_size - 1] ) )
{
input_idx = sub( input_table_size, 2 );
rel_offset = ONE_IN_Q30; // Q30;
input_idx = sub( input_grid_size, 2 );
input_idx_next = add( input_idx, 1 );
rel_offset = ONE_IN_Q31;
move32();
rel_offset_e = 1;
move16();
}
/* otherwise use linear interpolation between 2 consecutive points in the input table */
ELSE
......@@ -976,26 +890,13 @@ void ivas_reverb_interpolate_energies_fx(
{
input_idx = add( input_idx, 1 );
}
rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx + 1], pInput_fc[input_idx] ), &rel_offset_e ); // q15
rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) );
rel_offset_e = 0;
move16();
input_idx_next = add( input_idx, 1 );
rel_offset = BASOP_Util_Divide3232_Scale( L_sub( pOutput_fc[output_idx], pInput_fc[input_idx] ), L_sub( pInput_fc[input_idx_next], pInput_fc[input_idx] ), &rel_offset_e ); // Q15
rel_offset = L_shl_sat( rel_offset, add( 16, rel_offset_e ) ); // Q31
}
}
Word32 mult1;
Word16 mult_e = 0;
move16();
mult1 = Mpy_32_32( rel_offset, L_sub( pInput_ene_l[input_idx + 1], pInput_ene_l[input_idx] ) );
pOutput_ene_l_m[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_ene_l[input_idx], 3, mult1, add( 3, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 28 - 31)
move32();
pOutput_ene_l_e[output_idx] = mult_e;
move16();
mult1 = Mpy_32_32( rel_offset, L_sub( pInput_ene_r[input_idx + 1], pInput_ene_r[input_idx] ) );
pOutput_ene_r_m[output_idx] = BASOP_Util_Add_Mant32Exp( pInput_ene_r[input_idx], 3, mult1, add( 3, rel_offset_e ), &mult_e ); // 31 - (31 - rel_offset_e + 28 - 31)
move32();
pOutput_ene_r_e[output_idx] = mult_e;
move16();
pOutput_data[output_idx] = L_add( pInput_data[input_idx], Mpy_32_32( rel_offset, L_sub( pInput_data[input_idx_next], pInput_data[input_idx] ) ) );
}
return;
......
......@@ -40,9 +40,6 @@
#include <assert.h>
#include "wmc_auto.h"
#include "debug.h"
#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) )
#define float_to_fixQ31( n ) ( round( n * 0x7fffffff ) )
#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) )
static Word16 wrap_rad_fixed(
Word32 angle /* Q13 */ )
......@@ -123,24 +120,14 @@ typedef struct ivas_reverb_params_t
/* Currently this is fixed to 2. */ /* Mix [S][L] matrix from feedback loops to outputs. */
Word16 pLoop_extract_matrix_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES]; /* Mix [S][L] matrix from feedback loops to outputs. */ /* In Matlab: [S x L] - Currently S=2, later may be more than 2 for speaker playback. */
Word16 t60_filter_order; /* Filter order (length of vector) */
// float pT60_filter_coeff[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH]; /* Filters [][] in feedback loops, controlling T60. */
Word16 pT60_filter_coeff_fx[MAX_NR_OUTPUTS * IVAS_REV_MAX_NR_BRANCHES * IVAS_REV_MAX_IIR_FILTER_LENGTH];
/* In Matlab: IIR: [(2 * L) x (<order> + 1)] (odd: b-vector, even: a-vector) */
/* In Matlab: FIR: [L x <order>] */
// float *pFc; /* Center frequencies for FFT filter design */
// float *pRt60; /* RT60 values at these frequencies */
// float *pDsr; /* DSR values at these frequencies */
Word32 *pFc_fx; /* Center frequencies for FFT filter design */
Word32 *pRt60_fx; /* RT60 values at these frequencies */
Word16 *pRt60_e; /* exponents for RT60 values at these frequencies */
Word32 *pDsr_fx; /* DSR values at these frequencies */
Word16 *pDsr_e; /* DSR values at these frequencies */
// float *pHrtf_avg_pwr_response_l; /* The HRTF set's average left ear power response */
// float *pHrtf_avg_pwr_response_r; /* The HRTF set's average right ear power response */
// float *pHrtf_inter_aural_coherence; /* The HRTF set's inter-aural coherence for diffuse sound */
// const float *pHrtf_avg_pwr_response_l_const; /* The HRTF set's average left ear power response */
// const float *pHrtf_avg_pwr_response_r_const; /* The HRTF set's average right ear power response */
// const float *pHrtf_inter_aural_coherence_const; /* The HRTF set's inter-aural coherence for diffuse sound */
#ifndef FIX_1053_REVERB_RECONFIGURATION
Word32 *pHrtf_avg_pwr_response_l_fx; /* The HRTF set's average left ear power response */
Word32 *pHrtf_avg_pwr_response_r_fx; /* The HRTF set's average right ear power response */
......@@ -585,7 +572,7 @@ static ivas_error set_base_config_fx(
*-----------------------------------------------------------------------------------------*/
static Word32 calc_dmx_gain_fx( void )
{
const Word32 gain = DMX_GAIN; // Q25
const Word32 gain = DMX_GAIN; // Q23
move32();
return gain;
}
......@@ -639,55 +626,58 @@ static ivas_error compute_t60_coeffs_fx(
Word16 bin_idx, loop_idx, tf_T60_len, len;
ivas_error error;
Word16 loop_delay_sec_fx, norm_f_e, tmp;
Word16 loop_delay_sec_fx, tmp;
Word32 freq_Nyquist_fx = L_shr( output_Fs, 1 );
Word16 target_gains_db_fx[RV_LENGTH_NR_FC];
Word16 target_gains_db_fx[RV_LENGTH_NR_FC]; // Q8
Word16 norm_f_fx[RV_LENGTH_NR_FC];
Word32 *targetT60_fx, *pFc_fx;
Word16 *pCoeffs_a_fx, *pCoeffs_b_fx, *targetT60_e;
Word16 target_gains_db_exp[RV_LENGTH_NR_FC];
Word16 *pCoeffs_a_fx, *pCoeffs_b_fx;
Word16 e;
const Word16 min120q8 = -30720; // -120 in Q8
error = IVAS_ERR_OK;
move32();
tf_T60_len = nr_fc_fft_filter;
move16();
len = add( pParams->t60_filter_order, 1 );
pFc_fx = pParams->pFc_fx;
targetT60_fx = pParams->pRt60_fx;
targetT60_e = pParams->pRt60_e;
move16();
FOR( bin_idx = 0; bin_idx < tf_T60_len; bin_idx++ )
{
norm_f_fx[bin_idx] = BASOP_Util_Divide3232_Scale( pFc_fx[bin_idx], freq_Nyquist_fx, &norm_f_e );
norm_f_fx[bin_idx] = BASOP_Util_Divide3232_Scale( pParams->pFc_fx[bin_idx], freq_Nyquist_fx, &e );
move16();
norm_f_e = add( norm_f_e, sub( 17, 31 ) );
norm_f_fx[bin_idx] = shl( norm_f_fx[bin_idx], sub( norm_f_e, 1 ) ); // making Q14
e = add( e, sub( 15, 31 ) );
norm_f_fx[bin_idx] = shl( norm_f_fx[bin_idx], sub( e, 1 ) ); // making Q14
move16();
}
FOR( loop_idx = 0; loop_idx < pParams->nr_loops; loop_idx++ )
{
Word16 loop_delay_sec_fx_exp;
loop_delay_sec_fx = BASOP_Util_Divide3232_Scale( pParams->pLoop_delays[loop_idx], output_Fs, &loop_delay_sec_fx_exp );
loop_delay_sec_fx = BASOP_Util_Divide3232_Scale( pParams->pLoop_delays[loop_idx], output_Fs, &e );
loop_delay_sec_fx = shl( loop_delay_sec_fx, e ); // Q15
FOR( bin_idx = 0; bin_idx < tf_T60_len; bin_idx++ )
{
tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), targetT60_fx[bin_idx], &target_gains_db_exp[bin_idx] );
target_gains_db_exp[bin_idx] = add( target_gains_db_exp[bin_idx], sub( loop_delay_sec_fx_exp, targetT60_e[bin_idx] ) );
move16();
target_gains_db_fx[bin_idx] = mult( -30720, tmp ); // -60 in Q9 -> -30720
move16();
target_gains_db_exp[bin_idx] = add( target_gains_db_exp[bin_idx], 6 ); // Q9 -> e6
move16();
tmp = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( target_gains_db_fx[bin_idx] ), target_gains_db_exp[bin_idx], -2013265920, 7 );
IF( tmp < 0 )
IF( EQ_32( pParams->pRt60_fx[bin_idx], 0 ) )
{
target_gains_db_fx[bin_idx] = -30720; // -60 in Q9 -> -30720
move16();
target_gains_db_exp[bin_idx] = 7;
// If RT60 is 0, target gain is -120dB
target_gains_db_fx[bin_idx] = min120q8;
}
ELSE
{
tmp = BASOP_Util_Divide3232_Scale( L_deposit_h( loop_delay_sec_fx ), pParams->pRt60_fx[bin_idx], &e );
IF( LT_16( e, -1 ) )
{
target_gains_db_fx[bin_idx] = min120q8;
}
ELSE
{
tmp = shr( tmp, sub( 5, e ) ); // scaling tmp to Q15
target_gains_db_fx[bin_idx] = mult( shr( min120q8, 1 ), tmp ); // Q8
}
}
// gain < - 120 ? -120: gain
IF( LT_16( target_gains_db_fx[bin_idx], -30720 ) )
{
target_gains_db_fx[bin_idx] = -30720;
move16();
}
}
......@@ -695,19 +685,9 @@ static ivas_error compute_t60_coeffs_fx(
pCoeffs_a_fx = &pParams->pT60_filter_coeff_fx[add( shl( i_mult( len, loop_idx ), 1 ), len )]; // Q14
pCoeffs_b_fx = &pParams->pT60_filter_coeff_fx[shl( i_mult( len, loop_idx ), 1 )]; // Q14
Word16 val = target_gains_db_exp[0];
move16();
FOR( Word16 i = 1; i < nr_fc_fft_filter; i++ )
{
val = s_max( val, target_gains_db_exp[i] );
}
FOR( Word16 i = 0; i < nr_fc_fft_filter; i++ )
{
target_gains_db_fx[i] = shr( target_gains_db_fx[i], sub( val, target_gains_db_exp[i] ) );
move16();
}
Word16 val = 7;
IF( NE_32( ( error = calc_jot_t60_coeffs_fx( target_gains_db_fx, val, tf_T60_len, norm_f_fx, pCoeffs_a_fx, pCoeffs_b_fx, extract_l( freq_Nyquist_fx ) ) ), IVAS_ERR_OK ) )
{
......@@ -1270,10 +1250,10 @@ static void set_reverb_acoustic_data_fx(
const Word16 nr_fc_input,
const Word16 nr_fc_fft_filter )
{
int16_t bin_idx;
Word16 bin_idx;
Word32 ln_1e6_inverted_fx, delay_diff_fx, L_tmp;
Word16 exp_argument_fx, tmp, tmp_flag, exp_argument_e;
Word16 pow_exp;
Word32 exp_argument_fx, tmp;
Word16 pow_exp, exp_argument_e;
Word32 *pFc_input_fx = pRoomAcoustics->pFc_input_fx;
Word32 *pAcoustic_rt60_fx = pRoomAcoustics->pAcoustic_rt60_fx;
......@@ -1281,63 +1261,45 @@ static void set_reverb_acoustic_data_fx(
Word32 *pFc_fx = pParams->pFc_fx;
Word32 *pRt60_fx = pParams->pRt60_fx;
Word16 *pRt60_e = pParams->pRt60_e;
Word32 *pDsr_fx = pParams->pDsr_fx;
Word16 *pDsr_e = pParams->pDsr_e;
/* interpolate input table data for T60 and DSR to the FFT filter grid */
ivas_reverb_interpolate_acoustic_data_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, pAcoustic_dsr_fx,
nr_fc_fft_filter, pFc_fx, pRt60_fx, pDsr_fx, pRt60_e, pDsr_e );
/* adjust DSR for the delay difference */
ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_rt60_fx, nr_fc_fft_filter, pFc_fx, pRt60_fx ); // Q26
ivas_reverb_interp_on_freq_grid_fx( nr_fc_input, pFc_input_fx, pAcoustic_dsr_fx, nr_fc_fft_filter, pFc_fx, pDsr_fx ); // Q30
///* adjust DSR for the delay difference */
delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx );
delay_diff_fx = L_sub( pRoomAcoustics->inputPreDelay_fx, pRoomAcoustics->acousticPreDelay_fx ); // Q27
ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */
move32();
FOR( bin_idx = 0; bin_idx < nr_fc_fft_filter; bin_idx++ )
{
L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // exp = pRt60_e[bin_idx] + 0
exp_argument_fx = BASOP_Util_Divide3232_Scale( delay_diff_fx, L_tmp, &exp_argument_e );
exp_argument_e = add( exp_argument_e, sub( 4, pRt60_e[bin_idx] ) ); // Q27 -> e4
/* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */
L_tmp = Mpy_32_32( pRt60_fx[bin_idx], ln_1e6_inverted_fx ); // Q26
// 23 in Q26
tmp_flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( exp_argument_fx ), exp_argument_e, 1543503872, 5 );
IF( tmp_flag > 0 )
{
exp_argument_fx = 23552;
move16();
exp_argument_e = 5;
move16();
}
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
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 )
/* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */
IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26
{
exp_argument_fx = -23552;
move16();
exp_argument_e = 5;
move16();
exp_argument_fx = 1543503872;
}
IF( LT_32( exp_argument_fx, -1543503872 ) ) // 23 in Q26
{
exp_argument_fx = -1543503872;
}
Word16 tmp_exp;
/* expf(exp_argument) -> pow(2, log2(e) * exp_argument) */
tmp = mult( 23637, exp_argument_fx ); // exp_argument_e + 1
tmp_exp = add( exp_argument_e, 1 );
L_tmp = BASOP_util_Pow2( L_deposit_h( tmp ), tmp_exp, &pow_exp );
tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21
L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );
L_tmp = Mpy_32_32( L_tmp, pDsr_fx[bin_idx] );
tmp_exp = add( pow_exp, pDsr_e[bin_idx] );
L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31
pDsr_fx[bin_idx] = L_tmp;
move32();
pDsr_e[bin_idx] = tmp_exp;
move16();
}
return;
}
......@@ -1429,7 +1391,7 @@ ivas_error ivas_reverb_open_fx(
REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */
const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */
RENDER_CONFIG_HANDLE hRenderConfig, /* i : Renderer configuration handle */
const int32_t output_Fs )
const Word32 output_Fs )
{
ivas_error error;
#ifdef FIX_1053_REVERB_RECONFIGURATION
......@@ -1537,28 +1499,15 @@ ivas_error ivas_reverb_open_fx(
freq_step_fx = L_mult0( extract_l( L_shr( output_Fs, 2 ) ), div_s( 1, ( nr_fc_fft_filter - 1 ) ) ); /*Q14:0.5f * output_Fs / ( nr_fc_fft_filter - 1 )*/
FOR( bin_idx = 0; bin_idx < nr_fc_fft_filter; bin_idx++ )
{
params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q14*/
params.pFc_fx[bin_idx] = W_extract_l( W_mult0_32_32( freq_step_fx, bin_idx ) ); /*Q16*/
}
test();
/* set up reverb acoustic data on the basis of HRTF data and renderer config */
Scale_sig32( params.pFc_fx, nr_fc_fft_filter, 2 );
Word16 *pRt60_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter );
Word16 *pDsr_e = (Word16 *) malloc( sizeof( Word16 ) * nr_fc_fft_filter );
params.pRt60_e = pRt60_e;
params.pDsr_e = pDsr_e;
set_reverb_acoustic_data_fx( &params, &hRenderConfig->roomAcoustics, nr_fc_input, nr_fc_fft_filter );
Scale_sig32( params.pFc_fx, nr_fc_fft_filter, -2 );
FOR( i = 0; i < nr_fc_fft_filter; i++ )
{
params.pRt60_fx[i] = L_abs( params.pRt60_fx[i] );
move32();
params.pDsr_fx[i] = L_abs( params.pDsr_fx[i] );
move32();
}
params.pHrtf_avg_pwr_response_l_const_fx = hHrtfStatistics->average_energy_l;
params.pHrtf_avg_pwr_response_r_const_fx = hHrtfStatistics->average_energy_r;
......@@ -1608,8 +1557,6 @@ ivas_error ivas_reverb_open_fx(
FOR( i = 0; i < nr_fc_fft_filter; i++ )
{
params.pDsr_fx[i] = L_shl( params.pDsr_fx[i], params.pDsr_e[i] );
move32();
pHrtf_avg_pwr_response_l_const[i] = params.pHrtf_avg_pwr_response_l_const_fx[i]; /*Q28*/
move32();
pHrtf_avg_pwr_response_r_const[i] = params.pHrtf_avg_pwr_response_r_const_fx[i]; /*Q23+5*/
......@@ -1681,7 +1628,7 @@ ivas_error ivas_reverb_open_fx(
Word32 *pHrtf_inter_aural_coherence_const = (Word32 *) malloc( nr_fc_fft_filter * sizeof( Word32 ) );
FOR( i = 0; i < nr_fc_fft_filter; i++ )
{
pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 3 ); /*Scaling up to Q30*/
pHrtf_inter_aural_coherence_const[i] = L_shl( params.pHrtf_inter_aural_coherence_const_fx[i], 4 ); /*Scaling up to Q30*/
move32();
}
ivas_reverb_calc_correl_filters_fx( pHrtf_inter_aural_coherence_const, pTime_window_fx, pState->fft_size, pFft_wf_filter_ch0_fx, pFft_wf_filter_ch1_fx, &q_pFft_wf_filter_ch0_fx, &q_pFft_wf_filter_ch1_fx );
......@@ -1690,16 +1637,16 @@ ivas_error ivas_reverb_open_fx(
FOR( i = 0; i < nr_fc_fft_filter; i++ )
{
pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) );
pFft_wf_filter_ch0_fx[i][0] = L_shl( pFft_wf_filter_ch0_fx[i][0], sub( 31, q_pFft_wf_filter_ch0_fx ) ); // Scale to Q31
move32();
pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) );
pFft_wf_filter_ch0_fx[i][1] = L_shl( pFft_wf_filter_ch0_fx[i][1], sub( 31, q_pFft_wf_filter_ch0_fx ) ); // Scale to Q31
move32();
}
FOR( i = 0; i < nr_fc_fft_filter; i++ )
{
pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) );
pFft_wf_filter_ch1_fx[i][0] = L_shl( pFft_wf_filter_ch1_fx[i][0], sub( 31, q_pFft_wf_filter_ch1_fx ) ); // Scale to Q31
move32();
pFft_wf_filter_ch1_fx[i][1] = L_shl( pFft_wf_filter_ch1_fx[i][1], sub( 31, q_pFft_wf_filter_ch1_fx ) );
pFft_wf_filter_ch1_fx[i][1] = L_shl( pFft_wf_filter_ch1_fx[i][1], sub( 31, q_pFft_wf_filter_ch1_fx ) ); // Scale to Q31
move32();
}
/* Copying the computed FFT correlation filters to the fft_filter components */
......@@ -2524,21 +2471,16 @@ ivas_error ivas_binaural_reverb_init(
if ( ( roomAcoustics != NULL ) && roomAcoustics->override )
{
float t60_temp[CLDFB_NO_CHANNELS_MAX];
float ene_temp[CLDFB_NO_CHANNELS_MAX];
revTimes = t60;
revEne = ene;
if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60_temp, ene_temp ) ) != IVAS_ERR_OK )
if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, t60, ene ) ) != IVAS_ERR_OK )
{
return error;
}
temp32 = Mult_32_16( roomAcoustics->acousticPreDelay_fx, ( ( IVAS_48k / CLDFB_NO_CHANNELS_MAX ) >> 1 ) ); // Q11
preDelay = extract_l( L_shr( L_add( temp32, L_shl( 1, 10 ) ), 11 ) ); // Q0
floatToFixed_arrL( t60_temp, t60, Q26, CLDFB_NO_CHANNELS_MAX );
floatToFixed_arrL( ene_temp, ene, Q31, CLDFB_NO_CHANNELS_MAX );
}
else
{
......
......@@ -43,28 +43,13 @@
* Local constants
*-----------------------------------------------------------------------------------------*/
#define DEFAULT_SRC_DIST ( 1.5f ) /* default source distance [m] for reverb dmx factor computing */
#define MAX_SAMPLING_RATE ( 48000 )
#define CLDFB_CONVOLVER_NTAPS_MAX ( 16 )
#define FFT_SPECTRUM_SIZE ( 1 + ( RV_FILTER_MAX_FFT_SIZE / 2 ) )
#define N_INITIAL_IGNORED_FRAMES 4
/*-----------------------------------------------------------------------------------------*
* Local function prototypes
*-----------------------------------------------------------------------------------------*/
typedef struct cldfb_convolver_state
{
const float *filter_taps_left_re[CLDFB_NO_CHANNELS_MAX];
const float *filter_taps_left_im[CLDFB_NO_CHANNELS_MAX];
const float *filter_taps_right_re[CLDFB_NO_CHANNELS_MAX];
const float *filter_taps_right_im[CLDFB_NO_CHANNELS_MAX];
float filter_states_re[BINAURAL_CONVBANDS][CLDFB_CONVOLVER_NTAPS_MAX];
float filter_states_im[BINAURAL_CONVBANDS][CLDFB_CONVOLVER_NTAPS_MAX];
} cldfb_convolver_state;
static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, const int32_t sampling_rate, float *avg_pwr_l_out, float *avg_pwr_r_out );
static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg_pwr_r, const Word32 sampling_rate, Word32 *avg_pwr_l_out, Word32 *avg_pwr_r_out );
/*-----------------------------------------------------------------------------------------*
* Function ivas_reverb_prepare_cldfb_params()
......@@ -72,59 +57,80 @@ static void ivas_reverb_set_energies( const Word32 *avg_pwr_l, const Word32 *avg
* Prepares reverb parameters for CLDFB-based reverberator
*-----------------------------------------------------------------------------------------*/
ivas_error ivas_reverb_prepare_cldfb_params(
const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params,
const HRTFS_STATISTICS_HANDLE hHrtfStatistics,
const int32_t output_Fs,
float *pOutput_t60,
float *pOutput_ene )
const Word32 output_Fs,
Word32 *pOutput_t60,
Word32 *pOutput_ene )
{
int16_t idx;
float avg_pwr_left[CLDFB_NO_CHANNELS_MAX];
float avg_pwr_right[CLDFB_NO_CHANNELS_MAX];
float delay_diff, ln_1e6_inverted, exp_argument;
const float dist = DEFAULT_SRC_DIST;
const float dmx_gain_2 = 4.0f * EVS_PI * dist * dist / 0.001f;
Word16 idx;
Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX];
Word32 output_t60_fx[CLDFB_NO_CHANNELS_MAX];
Word16 output_t60_e[CLDFB_NO_CHANNELS_MAX];
Word32 output_ene_fx[CLDFB_NO_CHANNELS_MAX];
Word16 output_ene_e[CLDFB_NO_CHANNELS_MAX];
Word32 delay_diff_fx;
for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
Word32 delay_diff_fx, ln_1e6_inverted_fx, L_tmp;
const Word32 dmx_gain_2_fx = 1852986624; // Q16
const Word32 cldfb_band_width = 26214400; // 400 in Q16
Word16 pow_exp, tmp_exp;
Word32 tmp, exp_argument_fx;
Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX];
Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX];
FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
{
output_fc_fx[idx] = (Word32) ( ( idx + 0.5f ) * ( MAX_SAMPLING_RATE / ( 2 * CLDFB_NO_CHANNELS_MAX ) ) ) * ONE_IN_Q16;
output_fc_fx[idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, idx ), 15 ) );
}
ivas_reverb_interpolate_acoustic_data_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, pInput_params->pAcoustic_dsr_fx,
CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx, output_ene_fx, output_t60_e, output_ene_e );
ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_rt60_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_t60_fx ); // Q26
ivas_reverb_interp_on_freq_grid_fx( pInput_params->nBands, pInput_params->pFc_input_fx, pInput_params->pAcoustic_dsr_fx, CLDFB_NO_CHANNELS_MAX, output_fc_fx, output_ene_fx ); // Q30
/* adjust DSR for the delay difference */
delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx );
delay_diff_fx = L_sub( pInput_params->inputPreDelay_fx, pInput_params->acousticPreDelay_fx ); // Q27
delay_diff = (float) delay_diff_fx / ONE_IN_Q27;
for ( int i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
{
pOutput_t60[i] = (float) fabs( me2f( output_t60_fx[i], output_t60_e[i] ) );
pOutput_ene[i] = (float) fabs( me2f( output_ene_fx[i], output_ene_e[i] ) );
}
ln_1e6_inverted_fx = 155440049; // Q31 /* 1.0f / logf( 1e06f ) */
ln_1e6_inverted = 1.0f / logf( 1e06f );
for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
{
exp_argument = delay_diff / ( pOutput_t60[idx] * ln_1e6_inverted );
L_tmp = Mpy_32_32( output_t60_fx[idx], ln_1e6_inverted_fx ); // Q26
exp_argument_fx = BASOP_Util_Divide3232_Scale_newton( delay_diff_fx, L_tmp, &tmp_exp );
exp_argument_fx = L_shr_sat( exp_argument_fx, sub( 6, tmp_exp ) ); // Q26
/* Limit exponent to approx +/-100 dB in case of incoherent value of delay_diff, to prevent overflow */
exp_argument = min( exp_argument, 23.0f );
exp_argument = max( exp_argument, -23.0f );
pOutput_ene[idx] *= expf( exp_argument );
IF( GT_32( exp_argument_fx, 1543503872 ) ) // 23 in Q26
{
exp_argument_fx = 1543503872;
}
IF( LT_32( exp_argument_fx, -1543503872 ) ) //-23 in Q26
{
exp_argument_fx = -1543503872;
}
tmp = Mpy_32_32( 96817114, exp_argument_fx ); // Q21
L_tmp = BASOP_util_Pow2( tmp, 10, &pow_exp );
L_tmp = Mpy_32_32( L_tmp, output_ene_fx[idx] );
L_tmp = L_shl_sat( L_tmp, add( 1, pow_exp ) ); // Q31
pOutput_ene[idx] = L_tmp; // Q31
move32();
pOutput_t60[idx] = output_t60_fx[idx]; // Q26
}
ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left, avg_pwr_right );
for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
ivas_reverb_set_energies( hHrtfStatistics->average_energy_l, hHrtfStatistics->average_energy_r, output_Fs, avg_pwr_left_fx, avg_pwr_right_fx ); // Q28
FOR( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
{
pOutput_ene[idx] *= 0.5f * ( avg_pwr_left[idx] + avg_pwr_right[idx] ) * dmx_gain_2;
Word32 tmp_ene;
tmp_ene = L_shr( L_add( avg_pwr_left_fx[idx], avg_pwr_right_fx[idx] ), 1 ); // Q28
tmp_ene = Mpy_32_32( tmp_ene, dmx_gain_2_fx ); // Q13
pOutput_ene[idx] = Mpy_32_32( pOutput_ene[idx], tmp_ene ); // Q13
pOutput_ene[idx] = L_shl_sat( pOutput_ene[idx], 18 ); // Q31
}
return IVAS_ERR_OK;
......@@ -141,41 +147,40 @@ ivas_error ivas_reverb_prepare_cldfb_params(
static void ivas_reverb_set_energies(
const Word32 *avg_pwr_l,
const Word32 *avg_pwr_r,
const int32_t sampling_rate,
float *avg_pwr_left,
float *avg_pwr_right )
const Word32 sampling_rate,
Word32 *avg_pwr_left,
Word32 *avg_pwr_right )
{
int16_t freq_idx;
float input_fc[FFT_SPECTRUM_SIZE];
Word16 freq_idx;
Word32 input_fc_fx[FFT_SPECTRUM_SIZE];
Word32 output_fc_fx[CLDFB_NO_CHANNELS_MAX];
Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX];
Word16 avg_pwr_left_e[CLDFB_NO_CHANNELS_MAX];
Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX];
Word16 avg_pwr_right_e[CLDFB_NO_CHANNELS_MAX];
const Word16 cldfb_freq_halfstep = MAX_SAMPLING_RATE / ( 4 * CLDFB_NO_CHANNELS_MAX );
Word32 avg_pwr_left_fx[CLDFB_NO_CHANNELS_MAX]; // Q28
Word32 avg_pwr_right_fx[CLDFB_NO_CHANNELS_MAX]; // Q28
const Word32 cldfb_band_width = 26214400; // 400 in Q16
Word16 s;
Word16 temp;
const int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC;
const Word16 avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC;
temp = BASOP_Util_Divide3216_Scale( sampling_rate, sub( avg_pwr_len, 1 ), &s );
for ( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ )
FOR( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ )
{
input_fc[freq_idx] = freq_idx * ( 0.5f * sampling_rate / (float) ( avg_pwr_len - 1 ) );
input_fc_fx[freq_idx] = (Word16) ( input_fc[freq_idx] * ONE_IN_Q16 + 0.5f );
input_fc_fx[freq_idx] = L_shl( L_mult( temp, freq_idx ), add( 15, s ) );
}
for ( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ )
FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ )
{
output_fc_fx[freq_idx] = ( ( freq_idx << 1 ) + 1 ) * cldfb_freq_halfstep * ONE_IN_Q16;
output_fc_fx[freq_idx] = L_add( L_shr( cldfb_band_width, 1 ), L_shl( Mult_32_16( cldfb_band_width, freq_idx ), 15 ) );
}
// Avg Energy Left
ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_l, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx );
// Avg Energy Right
ivas_reverb_interp_on_freq_grid_fx( avg_pwr_len, input_fc_fx, avg_pwr_r, CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_right_fx );
ivas_reverb_interpolate_energies_fx( avg_pwr_len, input_fc_fx, avg_pwr_l, avg_pwr_r,
CLDFB_NO_CHANNELS_MAX, output_fc_fx, avg_pwr_left_fx, avg_pwr_right_fx, avg_pwr_left_e, avg_pwr_right_e );
for ( int i = 0; i < 60; i++ )
FOR( freq_idx = 0; freq_idx < CLDFB_NO_CHANNELS_MAX; freq_idx++ )
{
avg_pwr_left[i] = (float) fabs( me2f( avg_pwr_left_fx[i], avg_pwr_left_e[i] ) );
avg_pwr_right[i] = (float) fabs( me2f( avg_pwr_right_fx[i], avg_pwr_right_e[i] ) );
avg_pwr_left[freq_idx] = avg_pwr_left_fx[freq_idx];
avg_pwr_right[freq_idx] = avg_pwr_right_fx[freq_idx];
}
}
......@@ -678,7 +678,6 @@ void rotateFrame_shd(
const Word16 subframe_idx /* i : subframe index Q0 */
)
{
// Not yet tested, no test cases entering the function.
Word16 i, l, n, m, offset;
Word16 m1, m2;
Word16 shd_rot_max_order;
......@@ -700,7 +699,7 @@ void rotateFrame_shd(
move32();
BREAK;
case L_SUBFRAME_32k:
tmp = Q31_BY_SUB_FRAME_180;
tmp = Q31_BY_NUM_SAMPLES_160;
move32();
BREAK;
case L_SUBFRAME_16k:
......@@ -837,7 +836,7 @@ void rotateFrame_sd(
move32();
BREAK;
case L_SUBFRAME_32k:
tmp = Q31_BY_SUB_FRAME_180;
tmp = Q31_BY_NUM_SAMPLES_160;
move32();
BREAK;
case L_SUBFRAME_16k:
......
......@@ -5437,7 +5437,7 @@ static void renderBufferChannelLerp_fx(
move32();
move32();
BREAK;
case NUM_SAMPLES_160:
case L_SUBFRAME_32k:
tmp = Q31_BY_NUM_SAMPLES_160;
tmp1 = 159; /* NUM_SAMPLES_160 - 1 */
move32();
......@@ -5449,12 +5449,6 @@ static void renderBufferChannelLerp_fx(
move32();
move32();
BREAK;
case L_SUBFRAME_32k:
tmp = Q31_BY_SUB_FRAME_180;
tmp1 = 179; /* L_SUBFRAME_32k - 1 */
move32();
move32();
BREAK;
case L_SUBFRAME_16k:
tmp = Q31_BY_SUB_FRAME_80;
tmp1 = 79; /* L_SUBFRAME_16k - 1 */
......
......@@ -35,6 +35,9 @@
#include <stdlib.h>
#include <math.h>
#include "ivas_prot_fx.h"
#ifdef FIX_1121_MASA_DESCRIPTOR
#include "ivas_rom_com.h" /* load 'ivasmasaFormatDescriptor[8]' */
#endif
struct MasaFileReader
......@@ -111,7 +114,9 @@ ivas_error MasaFileReader_readNextFrame(
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
#ifndef FIX_1121_MASA_DESCRIPTOR
const uint8_t ivasmasaFormatDescriptor[8] = { 0x49, 0x56, 0x41, 0x53, 0x4D, 0x41, 0x53, 0x41 }; /* "IVASMASA" */
#endif
uint16_t twoByteBuffer = 0;
int16_t i, j, b;
IVAS_MASA_METADATA_HANDLE hMeta;
......
......@@ -1216,46 +1216,21 @@ ivas_error RenderConfigReader_checkValues(
return IVAS_ERR_WRONG_PARAMS;
}
/* Verify input pre-delay value */
if ( ( pRoom_acoustics->inputPreDelay > INPUTPREDELAY_MAX ) || ( pRoom_acoustics->inputPreDelay < INPUTPREDELAY_MIN ) )
{
return IVAS_ERR_WRONG_PARAMS;
}
/* Verify data per band in the acoustic properties table */
for ( band_idx = 0; band_idx < pRoom_acoustics->nBands; band_idx++ )
{
/* Verify if the frequencies are in the ascending order (required for interpolation) */
if ( band_idx != 0 )
{
if ( pRoom_acoustics->pFc_input[band_idx] <= pRoom_acoustics->pFc_input[band_idx - 1] )
{
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 ) )
if ( pRoom_acoustics->pFc_input_fx[band_idx] <= pRoom_acoustics->pFc_input_fx[band_idx - 1] )
{
tab_value_err_count++;
}
/* Check the input RT60 values */
if ( ( pRoom_acoustics->pAcoustic_rt60[band_idx] > ACOUSTIC_RT60_MAX ) || ( pRoom_acoustics->pAcoustic_rt60[band_idx] < ACOUSTIC_RT60_MIN ) )
{
tab_value_err_count++;
}
/* Check the input DSR values */
if ( ( pRoom_acoustics->pAcoustic_dsr[band_idx] > ACOUSTIC_DSR_MAX ) || ( pRoom_acoustics->pAcoustic_dsr[band_idx] < ACOUSTIC_DSR_MIN ) )
{
tab_value_err_count++;
}
/* Replace zero DSR values with very small positive values, to avoid issues with coloration filter design */
if ( pRoom_acoustics->pAcoustic_dsr[band_idx] <= 0.0f )
if ( pRoom_acoustics->pAcoustic_dsr_fx[band_idx] == 0 )
{
pRoom_acoustics->pAcoustic_dsr[band_idx] = ACOUSTIC_DSR_EPSILON;
pRoom_acoustics->pAcoustic_dsr_fx[band_idx] = ACOUSTIC_DSR_EPSILON_FX;
}
}
......@@ -2354,11 +2329,12 @@ ivas_error RenderConfigReader_read(
/* Acoustic pre-delay */
else if ( strcmp( item, "ACOUSTICPREDELAY" ) == 0 )
{
if ( !sscanf( pValue, "%f", &hRenderConfig->roomAcoustics.acousticPreDelay ) )
float f;
if ( !sscanf( pValue, "%f", &f ) )
{
errorHandler( item, ERROR_VALUE_INVALID );
}
hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( hRenderConfig->roomAcoustics.acousticPreDelay * ONE_IN_Q27 );
hRenderConfig->roomAcoustics.acousticPreDelay_fx = (Word32) ( f * ONE_IN_Q27 );
}
/* Pre-delay */
else if ( strcmp( item, "PREDELAY" ) == 0 )
......@@ -2828,13 +2804,24 @@ ivas_error RenderConfigReader_getAcousticEnvironment(
if ( id == pRenderConfigReader->pAE[n].id )
{
pAcEnv->nBands = (int16_t) pRenderConfigReader->pAE[n].pFG->nrBands;
pAcEnv->inputPreDelay = pRenderConfigReader->pAE[n].preDelay;
pAcEnv->inputPreDelay_fx = (Word32) ( pRenderConfigReader->pAE[n].preDelay * ONE_IN_Q27 );
if ( pRenderConfigReader->pAE[n].preDelay > INPUTPREDELAY_MAX ||
pRenderConfigReader->pAE[n].preDelay < INPUTPREDELAY_MIN )
{
return IVAS_ERR_INVALID_RENDER_CONFIG;
}
for ( m = 0; m < pAcEnv->nBands; m++ )
{
pAcEnv->pFc_input[m] = pRenderConfigReader->pAE[n].pFG->pFc[m];
pAcEnv->pAcoustic_rt60[m] = pRenderConfigReader->pAE[n].pRT60[m];
pAcEnv->pAcoustic_dsr[m] = pRenderConfigReader->pAE[n].pDSR[m];
if ( pRenderConfigReader->pAE[n].pFG->pFc[m] > FC_INPUT_MAX ||
pRenderConfigReader->pAE[n].pFG->pFc[m] < FC_INPUT_MIN ||
pRenderConfigReader->pAE[n].pRT60[m] > ACOUSTIC_RT60_MAX ||
pRenderConfigReader->pAE[n].pRT60[m] < ACOUSTIC_RT60_MIN ||
pRenderConfigReader->pAE[n].pDSR[m] > ACOUSTIC_DSR_MAX ||
pRenderConfigReader->pAE[n].pDSR[m] < ACOUSTIC_DSR_MIN )
{
return IVAS_ERR_INVALID_RENDER_CONFIG;
}
pAcEnv->pFc_input_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pFG->pFc[m] * ONE_IN_Q16 );
pAcEnv->pAcoustic_rt60_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pRT60[m] * ONE_IN_Q26 );
pAcEnv->pAcoustic_dsr_fx[m] = (Word32) ( pRenderConfigReader->pAE[n].pDSR[m] * ONE_IN_Q30 );
......