Commit 82eb1fe4 authored by Jan Brouwer's avatar Jan Brouwer
Browse files

implemented reverb for ParamBin renderer / parametric reverb, see...

implemented reverb for ParamBin renderer / parametric reverb, see ivas_reverb_get_parambin_hrtf_set_energies()
parent fe26d687
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -239,8 +239,7 @@ ivas_error ivas_dirac_dec_init_binaural_data(
        if ( hDiracDecBin->hReverb == NULL )
#endif
            {
                /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */
                if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
                if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &(st_ivas->hRenderConfig->roomAcoustics), output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
                {
                    return error;
                }
+6 −0
Original line number Diff line number Diff line
@@ -1179,6 +1179,12 @@ ivas_error ivas_reverb_prepare_cldfb_params(
    float *pOutput_t60,
    float *pOutput_ene );

ivas_error ivas_reverb_prepare_cldfb_params_parambin(
    IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params,
    const HRTFS_PARAMBIN_HANDLE hHrtfParambin,
    float *pOutput_t60,
    float *pOutput_ene );

void ivas_reverb_interpolate_acoustic_data(
    const int16_t input_table_size,
    const float *pInput_fc,
+4 −5
Original line number Diff line number Diff line
@@ -1957,11 +1957,10 @@ ivas_error ivas_binaural_reverb_open_parambin(
    {
        revTimes = t60;
        revEne = ene;
        /* Todo Philips: This needs a suitable function for ParamBin here. */
        //        if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfFastConv, internal_config, false, sampling_rate, t60, ene ) ) != IVAS_ERR_OK )
        //        {
        //            return error;
        //        }
        if ( ( error = ivas_reverb_prepare_cldfb_params_parambin( roomAcoustics, hHrtfParambin, t60, ene ) ) != IVAS_ERR_OK )
        {
            return error;
        }
        preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX );
    }
    else
+97 −1
Original line number Diff line number Diff line
@@ -68,12 +68,13 @@ typedef struct cldfb_convolver_state
} cldfb_convolver_state;

static ivas_error ivas_reverb_get_fastconv_hrtf_set_energies( const HRTFS_FASTCONV_HANDLE hHrtfFastConv, const AUDIO_CONFIG input_audio_config, const int16_t use_brir, const int32_t sampling_rate, float *avg_pwr_left, float *avg_pwr_right );
static ivas_error ivas_reverb_get_parambin_hrtf_set_energies( const HRTFS_PARAMBIN_HANDLE hHrtfParambin, float *avg_pwr_left, float *avg_pwr_right );


/*-----------------------------------------------------------------------------------------*
 * Function ivas_reverb_prepare_cldfb_params()
 *
 * Prepares reverb parameters for CLDFB-based reverberator
 * Prepares reverb parameters for CLDFB-based reverberator using FastConv renderer HRTFs
 *-----------------------------------------------------------------------------------------*/

ivas_error ivas_reverb_prepare_cldfb_params(
@@ -127,6 +128,60 @@ ivas_error ivas_reverb_prepare_cldfb_params(
}


/*-----------------------------------------------------------------------------------------*
 * Function ivas_reverb_prepare_cldfb_params_parambin()
 *
 * Prepares reverb parameters for CLDFB-based reverberator using ParamBin renderer HRTFs
 *-----------------------------------------------------------------------------------------*/

ivas_error ivas_reverb_prepare_cldfb_params_parambin(
    IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params,
    const HRTFS_PARAMBIN_HANDLE hHrtfParambin,
    float *pOutput_t60,
    float *pOutput_ene )
{
    int16_t idx;
    float fc[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;
    ivas_error error;

    for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
    {
        fc[idx] = ( (float) idx + 0.5f ) * ( (float) MAX_SAMPLING_RATE / (float) ( 2 * CLDFB_NO_CHANNELS_MAX ) );
    }

    ivas_reverb_interpolate_acoustic_data( pInput_params->nBands, pInput_params->pFc_input, pInput_params->pAcoustic_rt60, pInput_params->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX, fc, pOutput_t60, pOutput_ene );

    /* adjust DSR for the delay difference */
    delay_diff = pInput_params->inputPreDelay - pInput_params->acousticPreDelay;
    ln_1e6_inverted = 1.0f / logf( 1e06f );
    for ( idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
    {
        exp_argument = delay_diff / ( pOutput_t60[idx] * ln_1e6_inverted );
        /* 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 ( ( error = ivas_reverb_get_parambin_hrtf_set_energies( hHrtfParambin, avg_pwr_left, avg_pwr_right ) ) != IVAS_ERR_OK )
    {
        return error;
    }

    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;
    }

    return IVAS_ERR_OK;
}


/*-----------------------------------------------------------------------------------------*
 * Function ivas_cldfb_convolver()
 *
@@ -515,3 +570,44 @@ static ivas_error ivas_reverb_get_fastconv_hrtf_set_energies(

    return IVAS_ERR_OK;
}


/*-----------------------------------------------------------------------------------------*
 * Function ivas_reverb_get_parambin_hrtf_set_energies()
 *
 * Function analyses the HRTF set and computes avarage left/right power spectrum.
 * Uses parambin renderer filter taps to compute energies.
 *-----------------------------------------------------------------------------------------*/

static ivas_error ivas_reverb_get_parambin_hrtf_set_energies(
    const HRTFS_PARAMBIN_HANDLE hHrtfParambin,
    float *avg_pwr_left,
    float *avg_pwr_right )
{
    int16_t freq_idx;
    int16_t sh_idx;
    float l_re, l_im, r_re, r_im;

    /* Compute average power from CLDFB HRTF data */
    for ( freq_idx = 0; freq_idx < HRTF_NUM_BINS; freq_idx++ )
    {
        avg_pwr_left[freq_idx] = 0.0f;
        avg_pwr_right[freq_idx] = 0.0f;

        for (sh_idx = 0; sh_idx < HRTF_SH_CHANNELS; sh_idx++)
        {
            l_re = hHrtfParambin->hrtfShCoeffsRe[0][sh_idx][freq_idx];
            l_im = hHrtfParambin->hrtfShCoeffsIm[0][sh_idx][freq_idx];
            r_re = hHrtfParambin->hrtfShCoeffsRe[1][sh_idx][freq_idx];
            r_im = hHrtfParambin->hrtfShCoeffsIm[1][sh_idx][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;
        }

        avg_pwr_left[freq_idx] /= (float) HRTF_SH_CHANNELS;
        avg_pwr_right[freq_idx] /= (float) HRTF_SH_CHANNELS;
    }

    return IVAS_ERR_OK;
}