Loading lib_rend/ivas_stat_rend.h +4 −0 Original line number Diff line number Diff line Loading @@ -1654,7 +1654,11 @@ typedef struct ivas_masa_external_rendering_struct #endif REVERB_STRUCT_HANDLE hReverb; #ifdef NONBE_FIX_BINARY_BINAURAL_READING HRTFS_PARAMBIN_HANDLE *hHrtfParambin; #else HRTFS_PARAMBIN_HANDLE hHrtfParambin; #endif VBAP_HANDLE hVBAPdata; float *hoa_dec_mtx; Loading lib_rend/lib_rend.c +13 −1 Original line number Diff line number Diff line Loading @@ -9272,7 +9272,11 @@ static ivas_error ivas_masa_ext_rend_parambin_init( error = IVAS_ERR_OK; #ifdef NONBE_FIX_BINARY_BINAURAL_READING hHrtfParambin = *( inputMasa->hMasaExtRend->hHrtfParambin ); #else hHrtfParambin = inputMasa->hMasaExtRend->hHrtfParambin; #endif /* Set common variables and defaults */ output_Fs = *( inputMasa->base.ctx.pOutSampleRate ); Loading Loading @@ -9439,7 +9443,7 @@ static ivas_error initMasaExtRenderer( #endif hMasaExtRend->hReverb = NULL; #ifdef NONBE_FIX_BINARY_BINAURAL_READING hMasaExtRend->hHrtfParambin = hrtfs->hHrtfParambin; hMasaExtRend->hHrtfParambin = &hrtfs->hHrtfParambin; #else hMasaExtRend->hHrtfParambin = NULL; #endif Loading Loading @@ -9533,7 +9537,11 @@ static ivas_error initMasaExtRenderer( { if ( hMasaExtRend->renderer_type != RENDERER_STEREO_PARAMETRIC ) { #ifdef NONBE_FIX_BINARY_BINAURAL_READING if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( inputMasa->hMasaExtRend->hHrtfParambin ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &inputMasa->hMasaExtRend->hHrtfParambin ) ) != IVAS_ERR_OK ) #endif { return error; } Loading Loading @@ -9627,7 +9635,11 @@ static void freeMasaExtRenderer( if ( hMasaExtRend->hHrtfParambin != NULL ) { #ifdef NONBE_FIX_BINARY_BINAURAL_READING ivas_HRTF_parambin_binary_close( hMasaExtRend->hHrtfParambin ); #else ivas_HRTF_parambin_binary_close( &hMasaExtRend->hHrtfParambin ); #endif } if ( hMasaExtRend->hVBAPdata != NULL ) Loading scripts/binauralRenderer_interface/CMakeLists.txt +0 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,6 @@ set(SOURCE_FILES_C ${IVAS_TRUNK_COM_PATH}/tools.c ${IVAS_TRUNK_COM_PATH}/tns_base.c ${IVAS_TRUNK_UTIL_PATH}/cmdl_tools.c ${IVAS_TRUNK_REND_PATH}/ivas_reverb_filter_design.c ${IVAS_TRUNK_REND_PATH}/ivas_reverb_fft_filter.c ${IVAS_TRUNK_REND_PATH}/ivas_rom_rend.c ) Loading scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c +187 −0 Original line number Diff line number Diff line Loading @@ -1497,6 +1497,193 @@ static uint16_t get_fft_size( return 0; } /*-------------------------------------------------------------------* * ivas_reverb_get_hrtf_set_properties() * * Function analyses the HRTF set and computes avarage left/right power spectrum * and frequency-dependent IA coherence. Expects frequency-domain HRTF input *-------------------------------------------------------------------*/ void static ivas_reverb_get_hrtf_set_properties( float **ppHrtf_set_L_re, float **ppHrtf_set_L_im, float **ppHrtf_set_R_re, float **ppHrtf_set_R_im, const AUDIO_CONFIG input_audio_config, const int16_t hrtf_count, const int16_t in_freq_count, const int16_t out_freq_count, float *pOut_avg_pwr_L, float *pOut_avg_pwr_R, float *out_i_a_coherence ) { const float foa_sum_coeffs[4][3] = { { 1.0, 1.0f, 0.0f }, { 1.0, -1.0f, 0.0f }, { 1.0, 0.0f, 1.0f }, { 1.0, 0.0f, -1.0f } }; const float inp_freq_step = 0.5f / (float) in_freq_count; const float inp_freq_offset = 0.5f * inp_freq_step; const float out_freq_step = 0.5f / (float) ( out_freq_count - 1 ); int16_t used_hrtf_count, base_idx, freq_idx, hrtf_idx, out_bin_idx, ch_index, is_ambisonics; float hrtf_count_inverted, relative_pos, weight_1st; float avg_pwr_left[2]; float avg_pwr_right[2]; float IA_coherence[2]; if ( input_audio_config == IVAS_AUDIO_CONFIG_FOA || input_audio_config == IVAS_AUDIO_CONFIG_HOA2 || input_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) { is_ambisonics = 1; used_hrtf_count = 4; /* Using only 1st order HRTFs */ } else { is_ambisonics = 0; used_hrtf_count = hrtf_count; } /* Interpolation (linear to a new grid) */ base_idx = 0; relative_pos = 0.0f; hrtf_count_inverted = 1.0f / (float) used_hrtf_count; /* Loop over output frequency bins */ for ( out_bin_idx = 0; out_bin_idx < out_freq_count; out_bin_idx++ ) { /* Computing normalized frequency for the current bin (1.0 corresponds to sampling rate) */ const float norm_freq = out_freq_step * out_bin_idx; /* Computing the bin index in the source data */ #ifdef NONBE_FIX_AVG_IAC_CLDFB_REVERB if ( in_freq_count == out_freq_count ) { base_idx = out_bin_idx; } else { #endif const float tbl_index = ( norm_freq - inp_freq_offset ) / inp_freq_step; if ( tbl_index <= 0.0f ) /* In case of extrapolation (below 1st bin), choose nearest */ { base_idx = 0; relative_pos = 0.0f; } else { base_idx = (int16_t) floorf( tbl_index ); relative_pos = tbl_index - base_idx; if ( base_idx > ( in_freq_count - 2 ) ) /* In case of extrapolation (above last bin), choose nearest */ { base_idx = in_freq_count - 2; relative_pos = 1.0f; } } #ifdef NONBE_FIX_AVG_IAC_CLDFB_REVERB } #endif /* Computing 2 bins data for later interpolation */ /* Zeroing before accumalation for average value computing */ avg_pwr_left[0] = 0.0f; avg_pwr_left[1] = 0.0f; avg_pwr_right[0] = 0.0f; avg_pwr_right[1] = 0.0f; IA_coherence[0] = 0.0f; IA_coherence[1] = 0.0f; /* Get power spectra and cross - correlation between left and right hrtfs */ /* Loop over all the HRTFs available */ for ( hrtf_idx = 0; hrtf_idx < used_hrtf_count; hrtf_idx++ ) { /* Pointers to current HRTF data */ float *current_base_L_ptr_re, *current_base_L_ptr_im, *current_base_R_ptr_re, *current_base_R_ptr_im; /* combined HRTF data used for FOA */ float combined_channels_L_re[2]; float combined_channels_L_im[2]; float combined_channels_R_re[2]; float combined_channels_R_im[2]; /* Process the frequency bins containing both real and img parts */ /* In case of 5.1 or 7.1 formats, use the available HRTF paires directly*/ if ( !is_ambisonics ) { current_base_L_ptr_re = ppHrtf_set_L_re[hrtf_idx] + base_idx; current_base_R_ptr_re = ppHrtf_set_R_re[hrtf_idx] + base_idx; current_base_L_ptr_im = ppHrtf_set_L_im[hrtf_idx] + base_idx; current_base_R_ptr_im = ppHrtf_set_R_im[hrtf_idx] + base_idx; } /* In case of FOA format, combine the W channel with the X/Y channels */ else { for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { combined_channels_L_re[freq_idx] = 0.0f; combined_channels_R_re[freq_idx] = 0.0f; combined_channels_L_im[freq_idx] = 0.0f; combined_channels_R_im[freq_idx] = 0.0f; for ( ch_index = 0; ch_index < 3; ch_index++ ) { combined_channels_L_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_re[ch_index][base_idx + freq_idx]; combined_channels_R_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_re[ch_index][base_idx + freq_idx]; combined_channels_L_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_im[ch_index][base_idx + freq_idx]; combined_channels_R_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_im[ch_index][base_idx + freq_idx]; } } current_base_L_ptr_re = &combined_channels_L_re[0]; current_base_R_ptr_re = &combined_channels_R_re[0]; current_base_L_ptr_im = &combined_channels_L_im[0]; current_base_R_ptr_im = &combined_channels_R_im[0]; } for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { float L_re, L_im, R_re, R_im, C_re; L_re = current_base_L_ptr_re[freq_idx]; R_re = current_base_R_ptr_re[freq_idx]; L_im = current_base_L_ptr_im[freq_idx]; R_im = current_base_R_ptr_im[freq_idx]; avg_pwr_left[freq_idx] += L_re * L_re + L_im * L_im; avg_pwr_right[freq_idx] += R_re * R_re + R_im * R_im; /* Cross product (Re part) */ C_re = L_re * R_re + L_im * R_im; IA_coherence[freq_idx] += C_re; } } /* Compute the averages and the IA coherence */ for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { avg_pwr_left[freq_idx] *= hrtf_count_inverted; avg_pwr_right[freq_idx] *= hrtf_count_inverted; IA_coherence[freq_idx] = hrtf_count_inverted * IA_coherence[freq_idx] / sqrtf( avg_pwr_left[freq_idx] * avg_pwr_right[freq_idx] ); /* Limiting to (0...1) range in case of small numerical errors or negative values */ IA_coherence[freq_idx] = min( IA_coherence[freq_idx], 1.0f ); IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0.0f ); } /* Computing weighted average of 2 nearest values (1 below + 1 above) for linear interpolation */ weight_1st = 1.0f - relative_pos; pOut_avg_pwr_L[out_bin_idx] = weight_1st * avg_pwr_left[0] + relative_pos * avg_pwr_left[1]; pOut_avg_pwr_R[out_bin_idx] = weight_1st * avg_pwr_right[0] + relative_pos * avg_pwr_right[1]; out_i_a_coherence[out_bin_idx] = weight_1st * IA_coherence[0] + relative_pos * IA_coherence[1]; } return; } #endif int generate_reverb_ivas_tables_from_sofa( const char *file_path ) Loading Loading
lib_rend/ivas_stat_rend.h +4 −0 Original line number Diff line number Diff line Loading @@ -1654,7 +1654,11 @@ typedef struct ivas_masa_external_rendering_struct #endif REVERB_STRUCT_HANDLE hReverb; #ifdef NONBE_FIX_BINARY_BINAURAL_READING HRTFS_PARAMBIN_HANDLE *hHrtfParambin; #else HRTFS_PARAMBIN_HANDLE hHrtfParambin; #endif VBAP_HANDLE hVBAPdata; float *hoa_dec_mtx; Loading
lib_rend/lib_rend.c +13 −1 Original line number Diff line number Diff line Loading @@ -9272,7 +9272,11 @@ static ivas_error ivas_masa_ext_rend_parambin_init( error = IVAS_ERR_OK; #ifdef NONBE_FIX_BINARY_BINAURAL_READING hHrtfParambin = *( inputMasa->hMasaExtRend->hHrtfParambin ); #else hHrtfParambin = inputMasa->hMasaExtRend->hHrtfParambin; #endif /* Set common variables and defaults */ output_Fs = *( inputMasa->base.ctx.pOutSampleRate ); Loading Loading @@ -9439,7 +9443,7 @@ static ivas_error initMasaExtRenderer( #endif hMasaExtRend->hReverb = NULL; #ifdef NONBE_FIX_BINARY_BINAURAL_READING hMasaExtRend->hHrtfParambin = hrtfs->hHrtfParambin; hMasaExtRend->hHrtfParambin = &hrtfs->hHrtfParambin; #else hMasaExtRend->hHrtfParambin = NULL; #endif Loading Loading @@ -9533,7 +9537,11 @@ static ivas_error initMasaExtRenderer( { if ( hMasaExtRend->renderer_type != RENDERER_STEREO_PARAMETRIC ) { #ifdef NONBE_FIX_BINARY_BINAURAL_READING if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( inputMasa->hMasaExtRend->hHrtfParambin ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &inputMasa->hMasaExtRend->hHrtfParambin ) ) != IVAS_ERR_OK ) #endif { return error; } Loading Loading @@ -9627,7 +9635,11 @@ static void freeMasaExtRenderer( if ( hMasaExtRend->hHrtfParambin != NULL ) { #ifdef NONBE_FIX_BINARY_BINAURAL_READING ivas_HRTF_parambin_binary_close( hMasaExtRend->hHrtfParambin ); #else ivas_HRTF_parambin_binary_close( &hMasaExtRend->hHrtfParambin ); #endif } if ( hMasaExtRend->hVBAPdata != NULL ) Loading
scripts/binauralRenderer_interface/CMakeLists.txt +0 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,6 @@ set(SOURCE_FILES_C ${IVAS_TRUNK_COM_PATH}/tools.c ${IVAS_TRUNK_COM_PATH}/tns_base.c ${IVAS_TRUNK_UTIL_PATH}/cmdl_tools.c ${IVAS_TRUNK_REND_PATH}/ivas_reverb_filter_design.c ${IVAS_TRUNK_REND_PATH}/ivas_reverb_fft_filter.c ${IVAS_TRUNK_REND_PATH}/ivas_rom_rend.c ) Loading
scripts/binauralRenderer_interface/generate_crend_ivas_tables_from_sofa.c +187 −0 Original line number Diff line number Diff line Loading @@ -1497,6 +1497,193 @@ static uint16_t get_fft_size( return 0; } /*-------------------------------------------------------------------* * ivas_reverb_get_hrtf_set_properties() * * Function analyses the HRTF set and computes avarage left/right power spectrum * and frequency-dependent IA coherence. Expects frequency-domain HRTF input *-------------------------------------------------------------------*/ void static ivas_reverb_get_hrtf_set_properties( float **ppHrtf_set_L_re, float **ppHrtf_set_L_im, float **ppHrtf_set_R_re, float **ppHrtf_set_R_im, const AUDIO_CONFIG input_audio_config, const int16_t hrtf_count, const int16_t in_freq_count, const int16_t out_freq_count, float *pOut_avg_pwr_L, float *pOut_avg_pwr_R, float *out_i_a_coherence ) { const float foa_sum_coeffs[4][3] = { { 1.0, 1.0f, 0.0f }, { 1.0, -1.0f, 0.0f }, { 1.0, 0.0f, 1.0f }, { 1.0, 0.0f, -1.0f } }; const float inp_freq_step = 0.5f / (float) in_freq_count; const float inp_freq_offset = 0.5f * inp_freq_step; const float out_freq_step = 0.5f / (float) ( out_freq_count - 1 ); int16_t used_hrtf_count, base_idx, freq_idx, hrtf_idx, out_bin_idx, ch_index, is_ambisonics; float hrtf_count_inverted, relative_pos, weight_1st; float avg_pwr_left[2]; float avg_pwr_right[2]; float IA_coherence[2]; if ( input_audio_config == IVAS_AUDIO_CONFIG_FOA || input_audio_config == IVAS_AUDIO_CONFIG_HOA2 || input_audio_config == IVAS_AUDIO_CONFIG_HOA3 ) { is_ambisonics = 1; used_hrtf_count = 4; /* Using only 1st order HRTFs */ } else { is_ambisonics = 0; used_hrtf_count = hrtf_count; } /* Interpolation (linear to a new grid) */ base_idx = 0; relative_pos = 0.0f; hrtf_count_inverted = 1.0f / (float) used_hrtf_count; /* Loop over output frequency bins */ for ( out_bin_idx = 0; out_bin_idx < out_freq_count; out_bin_idx++ ) { /* Computing normalized frequency for the current bin (1.0 corresponds to sampling rate) */ const float norm_freq = out_freq_step * out_bin_idx; /* Computing the bin index in the source data */ #ifdef NONBE_FIX_AVG_IAC_CLDFB_REVERB if ( in_freq_count == out_freq_count ) { base_idx = out_bin_idx; } else { #endif const float tbl_index = ( norm_freq - inp_freq_offset ) / inp_freq_step; if ( tbl_index <= 0.0f ) /* In case of extrapolation (below 1st bin), choose nearest */ { base_idx = 0; relative_pos = 0.0f; } else { base_idx = (int16_t) floorf( tbl_index ); relative_pos = tbl_index - base_idx; if ( base_idx > ( in_freq_count - 2 ) ) /* In case of extrapolation (above last bin), choose nearest */ { base_idx = in_freq_count - 2; relative_pos = 1.0f; } } #ifdef NONBE_FIX_AVG_IAC_CLDFB_REVERB } #endif /* Computing 2 bins data for later interpolation */ /* Zeroing before accumalation for average value computing */ avg_pwr_left[0] = 0.0f; avg_pwr_left[1] = 0.0f; avg_pwr_right[0] = 0.0f; avg_pwr_right[1] = 0.0f; IA_coherence[0] = 0.0f; IA_coherence[1] = 0.0f; /* Get power spectra and cross - correlation between left and right hrtfs */ /* Loop over all the HRTFs available */ for ( hrtf_idx = 0; hrtf_idx < used_hrtf_count; hrtf_idx++ ) { /* Pointers to current HRTF data */ float *current_base_L_ptr_re, *current_base_L_ptr_im, *current_base_R_ptr_re, *current_base_R_ptr_im; /* combined HRTF data used for FOA */ float combined_channels_L_re[2]; float combined_channels_L_im[2]; float combined_channels_R_re[2]; float combined_channels_R_im[2]; /* Process the frequency bins containing both real and img parts */ /* In case of 5.1 or 7.1 formats, use the available HRTF paires directly*/ if ( !is_ambisonics ) { current_base_L_ptr_re = ppHrtf_set_L_re[hrtf_idx] + base_idx; current_base_R_ptr_re = ppHrtf_set_R_re[hrtf_idx] + base_idx; current_base_L_ptr_im = ppHrtf_set_L_im[hrtf_idx] + base_idx; current_base_R_ptr_im = ppHrtf_set_R_im[hrtf_idx] + base_idx; } /* In case of FOA format, combine the W channel with the X/Y channels */ else { for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { combined_channels_L_re[freq_idx] = 0.0f; combined_channels_R_re[freq_idx] = 0.0f; combined_channels_L_im[freq_idx] = 0.0f; combined_channels_R_im[freq_idx] = 0.0f; for ( ch_index = 0; ch_index < 3; ch_index++ ) { combined_channels_L_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_re[ch_index][base_idx + freq_idx]; combined_channels_R_re[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_re[ch_index][base_idx + freq_idx]; combined_channels_L_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_L_im[ch_index][base_idx + freq_idx]; combined_channels_R_im[freq_idx] += foa_sum_coeffs[hrtf_idx][ch_index] * ppHrtf_set_R_im[ch_index][base_idx + freq_idx]; } } current_base_L_ptr_re = &combined_channels_L_re[0]; current_base_R_ptr_re = &combined_channels_R_re[0]; current_base_L_ptr_im = &combined_channels_L_im[0]; current_base_R_ptr_im = &combined_channels_R_im[0]; } for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { float L_re, L_im, R_re, R_im, C_re; L_re = current_base_L_ptr_re[freq_idx]; R_re = current_base_R_ptr_re[freq_idx]; L_im = current_base_L_ptr_im[freq_idx]; R_im = current_base_R_ptr_im[freq_idx]; avg_pwr_left[freq_idx] += L_re * L_re + L_im * L_im; avg_pwr_right[freq_idx] += R_re * R_re + R_im * R_im; /* Cross product (Re part) */ C_re = L_re * R_re + L_im * R_im; IA_coherence[freq_idx] += C_re; } } /* Compute the averages and the IA coherence */ for ( freq_idx = 0; freq_idx < 2; freq_idx++ ) { avg_pwr_left[freq_idx] *= hrtf_count_inverted; avg_pwr_right[freq_idx] *= hrtf_count_inverted; IA_coherence[freq_idx] = hrtf_count_inverted * IA_coherence[freq_idx] / sqrtf( avg_pwr_left[freq_idx] * avg_pwr_right[freq_idx] ); /* Limiting to (0...1) range in case of small numerical errors or negative values */ IA_coherence[freq_idx] = min( IA_coherence[freq_idx], 1.0f ); IA_coherence[freq_idx] = max( IA_coherence[freq_idx], 0.0f ); } /* Computing weighted average of 2 nearest values (1 below + 1 above) for linear interpolation */ weight_1st = 1.0f - relative_pos; pOut_avg_pwr_L[out_bin_idx] = weight_1st * avg_pwr_left[0] + relative_pos * avg_pwr_left[1]; pOut_avg_pwr_R[out_bin_idx] = weight_1st * avg_pwr_right[0] + relative_pos * avg_pwr_right[1]; out_i_a_coherence[out_bin_idx] = weight_1st * IA_coherence[0] + relative_pos * IA_coherence[1]; } return; } #endif int generate_reverb_ivas_tables_from_sofa( const char *file_path ) Loading