Commit 291e6a43 authored by emerit's avatar emerit
Browse files

fix masa renderer crash when loading hrir from file

parent 95f5e928
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;

+13 −1
Original line number Diff line number Diff line
@@ -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 );
@@ -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
@@ -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;
            }
@@ -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 )
+0 −2
Original line number Diff line number Diff line
@@ -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
)

+187 −0
Original line number Diff line number Diff line
@@ -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 )