Commit b815bed5 authored by Tapani Pihlajakuja's avatar Tapani Pihlajakuja
Browse files

Fixes issue 1139 to prevent sound coloration artefacts at very low reverberation times

parent 782844df
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -181,6 +181,8 @@

#define NONBE_FIX_1174_MCMASA_LBR_LOOP_ERROR            /* Nokia: Fix issue 1174 by removing the unnecessary inner loop causing problems. */

#define FIX_1139_PARAM_REV_COLORATION_SHORT_T60         /* Nokia: Fix issue 1139, prevent sound coloration artefacts at very low reverberation times */

/* ##################### End NON-BE switches ########################### */

/* ################## End DEVELOPMENT switches ######################### */
+12 −0
Original line number Diff line number Diff line
@@ -235,7 +235,19 @@ ivas_error ivas_dirac_dec_init_binaural_data(

            if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */
            {
#ifdef FIX_1139_PARAM_REV_COLORATION_SHORT_T60
                if ( ( error = ivas_binaural_reverb_init_for_parambin( &hDiracDecBin->hReverb,
                                                                         st_ivas->hHrtfStatistics,
                                                                         nBins,
                                                                         CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES,
                                                                         &( st_ivas->hRenderConfig->roomAcoustics ),
                                                                         output_Fs,
                                                                         ( *phHrtfParambin )->parametricReverberationTimes,
                                                                         ( *phHrtfParambin )->parametricReverberationEneCorrections,
                                                                         hDiracDecBin->earlyPartEneCorrection ) ) != IVAS_ERR_OK )
#else
                if ( ( error = ivas_binaural_reverb_init( &hDiracDecBin->hReverb, st_ivas->hHrtfStatistics, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, &( st_ivas->hRenderConfig->roomAcoustics ), output_Fs, ( *phHrtfParambin )->parametricReverberationTimes, ( *phHrtfParambin )->parametricReverberationEneCorrections ) ) != IVAS_ERR_OK )
#endif
                {
                    return error;
                }
+13 −0
Original line number Diff line number Diff line
@@ -940,6 +940,19 @@ ivas_error ivas_binaural_reverb_init(
    const float *defaultEne                                     /* i  : default reverberation energies          */
);

#ifdef FIX_1139_PARAM_REV_COLORATION_SHORT_T60
ivas_error ivas_binaural_reverb_init_for_parambin(
    REVERB_STRUCT_HANDLE *hReverbPr,                            /* i/o: binaural reverb handle                  */
    const HRTFS_STATISTICS_HANDLE hHrtfStatistics,              /* i  : HRTF statistics handle                  */
    const int16_t numBins,                                      /* i  : number of CLDFB bins                    */
    const int16_t numCldfbSlotsPerFrame,                        /* i  : number of CLDFB slots per frame         */
    const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics,       /* i/o: room acoustics parameters               */
    const int32_t sampling_rate,                                /* i  : sampling rate                           */
    const float *defaultTimes,                                  /* i  : default reverberation times             */
    const float *defaultEne,                                    /* i  : default reverberation energies          */
    float *earlyEne                                             /* i/o: early part energies to be modified      */
);
#endif

void ivas_binaural_reverb_close(
    REVERB_STRUCT_HANDLE *hReverb                               /* i/o: binaural reverb handle                  */
+89 −0
Original line number Diff line number Diff line
@@ -254,6 +254,19 @@ static void ivas_binaural_reverb_setReverbTimes(
                }
                currentEnergy *= attenuationFactorPerSampleSq;
            }
#ifdef FIX_1139_PARAM_REV_COLORATION_SHORT_T60
            /* In some configurations with small T60s it is possible the number of taps randomizes to zero.
               Ensure at least 1 filter tap. */
            if (tap == 0)
            {
                hReverb->tapPhaseShiftType[bin][ch][0] = (int16_t) ( binRend_rand( hReverb ) % 4 );
                hReverb->tapPointersReal[bin][ch][0] = &( hReverb->loopBufReal[bin][0] );
                hReverb->tapPointersImag[bin][ch][0] = &( hReverb->loopBufImag[bin][0] );
                tap = 1;
                actualizedEnergy = 1;
            }
#endif

            hReverb->taps[bin][ch] = tap; /* Number of taps determined at the above random procedure */
        }

@@ -1896,6 +1909,82 @@ ivas_error ivas_binaural_reverb_init(
    return error;
}

#ifdef FIX_1139_PARAM_REV_COLORATION_SHORT_T60
/*-------------------------------------------------------------------------
 * ivas_binaural_reverb_init_for_parambin()
 *
 * Allocate and initialize binaural room reverberator handle
 * for parametric binaural renderer, using room effect parameter adjustment
 *------------------------------------------------------------------------*/
ivas_error ivas_binaural_reverb_init_for_parambin(
    REVERB_STRUCT_HANDLE *hReverbPr,                      /* i/o: binaural reverb handle               */
    const HRTFS_STATISTICS_HANDLE hHrtfStatistics,        /* i  : HRTF statistics handle               */
    const int16_t numBins,                                /* i  : number of CLDFB bins                 */
    const int16_t numCldfbSlotsPerFrame,                  /* i  : number of CLDFB slots per frame      */
    const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters            */
    const int32_t sampling_rate,                          /* i  : sampling rate                        */
    const float *defaultTimes,                            /* i  : default reverberation times          */
    const float *defaultEne,                              /* i  : default reverberation energies       */
    float *earlyEne                                       /* i/o: Early part energies to be modified   */
)
{
    ivas_error error;
    float revTimes[CLDFB_NO_CHANNELS_MAX];
    float revEne[CLDFB_NO_CHANNELS_MAX];
    int16_t preDelay, bin;

    error = IVAS_ERR_OK;

    if ( ( roomAcoustics != NULL ) && roomAcoustics->override )
    {
        if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, revTimes, revEne ) ) != IVAS_ERR_OK )
        {
            return error;
        }
        preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX );
    }
    else
    {
        for ( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
        {
            revTimes[bin] = defaultTimes[bin];
            revEne[bin] = defaultEne[bin];
        }
        preDelay = 10;
    }
    for ( bin = 0; bin < 60; bin++ )
    {
        /* Adjust the room effect parameters when the reverberation time is less than a threshold value, to avoid
           spectral artefacts with the synthetic reverberator. */
        const float revTimeThreshold = 0.2f;
        if ( revTimes[bin] < revTimeThreshold )
        {
            float adjustedEarlyEne, adjustedLateEne, adjustedRevTime;
            float revTimeModifier, energyModifier;

            /* Adjust reverberation times, higher towards a threshold */
            revTimeModifier = fmaxf( 0.0f, 1.0f - ( revTimes[bin] / revTimeThreshold ) );
            adjustedRevTime = ( 1.0f - revTimeModifier ) * revTimes[bin];
            adjustedRevTime += revTimeModifier * ( revTimes[bin] + revTimeThreshold ) * 0.5f;
            energyModifier = ( adjustedRevTime - revTimes[bin] ) / adjustedRevTime;

            /* Adjust early and late energies, by moving late energy to early energy */
            adjustedEarlyEne = earlyEne[bin] + revEne[bin] * energyModifier;
            adjustedLateEne = revEne[bin] * ( 1.0f - energyModifier );

            /* Store adjusted room effect parameters to be used in reverb processing */
            revTimes[bin] = adjustedRevTime;
            revEne[bin] = adjustedLateEne;
            earlyEne[bin] = adjustedEarlyEne;
        }
    }

    error = ivas_binaural_reverb_open( hReverbPr, numBins, numCldfbSlotsPerFrame, sampling_rate, revTimes, revEne, preDelay );

    return error;
}
#endif

/*-------------------------------------------------------------------------
 * ivas_binaural_reverb_close()
 *