Commit 7429c643 authored by emerit's avatar emerit
Browse files

fix masa renderer with hrir binary file, fix renderer tests

parent 7c9450f1
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 )
+44 −0
Original line number Diff line number Diff line
#!/usr/bin/env python3

"""
   (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository. All Rights Reserved.

   This software is protected by copyright law and by international treaties.
   The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository retain full ownership rights in their respective contributions in
   the software. This notice grants no license of any kind, including but not limited to patent
   license, nor is any license granted by implication, estoppel or otherwise.

   Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
   contributions.

   This software is provided "AS IS", without any express or implied warranties. The software is in the
   development stage. It is intended exclusively for experts who have experience with such software and
   solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
   and fitness for a particular purpose are hereby disclaimed and excluded.

   Any dispute, controversy or claim arising under or in relation to providing this software shall be
   submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
   accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
   the United Nations Convention on Contracts on the International Sales of Goods.
"""


def pytest_addoption(parser):
    parser.addoption(
        "--create_ref",
        action="store_true",
        default=False,
    )
    parser.addoption(
        "--create_cut",
        action="store_true",
        default=False,
    )
Loading