コード例 #1
0
ファイル: Reverb.cpp プロジェクト: bgrins/gecko-dev
Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, bool useBackgroundThreads, bool normalize, float sampleRate)
{
    float scale = 1;

    AutoTArray<const float*,4> irChannels;
    for (size_t i = 0; i < impulseResponse->GetChannels(); ++i) {
        irChannels.AppendElement(impulseResponse->GetData(i));
    }
    AutoTArray<float,1024> tempBuf;

    if (normalize) {
        scale = calculateNormalizationScale(impulseResponse, impulseResponseBufferLength, sampleRate);

        if (scale) {
            tempBuf.SetLength(irChannels.Length()*impulseResponseBufferLength);
            for (uint32_t i = 0; i < irChannels.Length(); ++i) {
                float* buf = &tempBuf[i*impulseResponseBufferLength];
                AudioBufferCopyWithScale(irChannels[i], scale, buf,
                                         impulseResponseBufferLength);
                irChannels[i] = buf;
            }
        }
    }

    initialize(irChannels, impulseResponseBufferLength,
               maxFFTSize, useBackgroundThreads);
}
コード例 #2
0
ファイル: PeriodicWave.cpp プロジェクト: Andrel322/gecko-dev
// Convert into time-domain wave buffers.
// One table is created for each range for non-aliasing playback
// at different playback rates. Thus, higher ranges have more
// high-frequency partials culled out.
void PeriodicWave::createBandLimitedTables(const float* realData, const float* imagData, unsigned numberOfComponents)
{
    float normalizationScale = 1;

    unsigned fftSize = m_periodicWaveSize;
    unsigned halfSize = fftSize / 2 + 1;
    unsigned i;

    numberOfComponents = std::min(numberOfComponents, halfSize);

    m_bandLimitedTables.SetCapacity(m_numberOfRanges);

    for (unsigned rangeIndex = 0; rangeIndex < m_numberOfRanges; ++rangeIndex) {
        // This FFTBlock is used to cull partials (represented by frequency bins).
        FFTBlock frame(fftSize);
        nsAutoArrayPtr<float> realP(new float[halfSize]);
        nsAutoArrayPtr<float> imagP(new float[halfSize]);

        // Copy from loaded frequency data and scale.
        float scale = fftSize;
        AudioBufferCopyWithScale(realData, scale, realP, numberOfComponents);
        AudioBufferCopyWithScale(imagData, scale, imagP, numberOfComponents);

        // If fewer components were provided than 1/2 FFT size,
        // then clear the remaining bins.
        for (i = numberOfComponents; i < halfSize; ++i) {
            realP[i] = 0;
            imagP[i] = 0;
        }

        // Generate complex conjugate because of the way the
        // inverse FFT is defined.
        float minusOne = -1;
        AudioBufferInPlaceScale(imagP, minusOne, halfSize);

        // Find the starting bin where we should start culling.
        // We need to clear out the highest frequencies to band-limit
        // the waveform.
        unsigned numberOfPartials = numberOfPartialsForRange(rangeIndex);

        // Cull the aliasing partials for this pitch range.
        for (i = numberOfPartials + 1; i < halfSize; ++i) {
            realP[i] = 0;
            imagP[i] = 0;
        }
        // Clear nyquist if necessary.
        if (numberOfPartials < halfSize)
            realP[halfSize-1] = 0;

        // Clear any DC-offset.
        realP[0] = 0;

        // Clear values which have no effect.
        imagP[0] = 0;
        imagP[halfSize-1] = 0;

        // Create the band-limited table.
        AudioFloatArray* table = new AudioFloatArray(m_periodicWaveSize);
        m_bandLimitedTables.AppendElement(table);

        // Apply an inverse FFT to generate the time-domain table data.
        float* data = m_bandLimitedTables[rangeIndex]->Elements();
        frame.PerformInverseFFT(realP, imagP, data);

        // For the first range (which has the highest power), calculate
        // its peak value then compute normalization scale.
        if (!rangeIndex) {
            float maxValue;
            maxValue = AudioBufferPeakValue(data, m_periodicWaveSize);

            if (maxValue)
                normalizationScale = 1.0f / maxValue;
        }

        // Apply normalization scale.
        AudioBufferInPlaceScale(data, normalizationScale, m_periodicWaveSize);
    }
}