Exemple #1
0
HRTFKernel::HRTFKernel(AudioChannel* channel, size_t fftSize, float sampleRate, bool bassBoost)
    : m_frameDelay(0)
    , m_sampleRate(sampleRate)
{
    ASSERT(channel);

    // Determine the leading delay (average group delay) for the response.
    m_frameDelay = extractAverageGroupDelay(channel, fftSize / 2);

    float* impulseResponse = channel->data();
    size_t responseLength = channel->length();

    if (bassBoost) {
        // Run through some post-processing to boost the bass a little -- the HRTF's seem to be a little bass-deficient.
        // FIXME: this post-processing should have already been applied to the HRTF file resources.  Once the files are put into this form,
        // then this code path can be removed along with the bassBoost parameter.
        Biquad filter;
        filter.setLowShelfParams(700.0 / nyquist(), 6.0); // boost 6dB at 700Hz
        filter.process(impulseResponse, impulseResponse, responseLength);
    }

    // We need to truncate to fit into 1/2 the FFT size (with zero padding) in order to do proper convolution.
    size_t truncatedResponseLength = min(responseLength, fftSize / 2); // truncate if necessary to max impulse response length allowed by FFT

    // Quick fade-out (apply window) at truncation point
    unsigned numberOfFadeOutFrames = static_cast<unsigned>(sampleRate / 4410); // 10 sample-frames @44.1KHz sample-rate
    ASSERT(numberOfFadeOutFrames < truncatedResponseLength);
    if (numberOfFadeOutFrames < truncatedResponseLength) {
        for (unsigned i = truncatedResponseLength - numberOfFadeOutFrames; i < truncatedResponseLength; ++i) {
            float x = 1.0f - static_cast<float>(i - (truncatedResponseLength - numberOfFadeOutFrames)) / numberOfFadeOutFrames;
            impulseResponse[i] *= x;
        }
    }

    m_fftFrame = adoptPtr(new FFTFrame(fftSize));
    m_fftFrame->doPaddedFFT(impulseResponse, truncatedResponseLength);
}