Bug 815643 - Part 6: Optimize FFTBlock to avoid recreating kiss_fftr_cfg objects all the time; r=roc

Setting up the FFT tables turns out to be quite expensive because of the
large number of calls to sin() and cos().

In the future we may want to look into having a global cache of FFT
tables per size, in order to pay the cost of setting each one of them up
only once.

--HG--
extra : rebase_source : 871d11e7f74db9e3e6c704da9518d40cba3deb8a
This commit is contained in:
Ehsan Akhgari 2013-06-10 16:09:25 -04:00
Родитель 4237b065da
Коммит 05a4ee9f4a
1 изменённых файлов: 29 добавлений и 8 удалений

Просмотреть файл

@ -19,23 +19,28 @@ namespace mozilla {
class FFTBlock {
public:
explicit FFTBlock(uint32_t aFFTSize)
: mFFTSize(aFFTSize)
: mFFT(nullptr)
, mIFFT(nullptr)
, mFFTSize(aFFTSize)
{
mOutputBuffer.SetLength(aFFTSize / 2 + 1);
PodZero(mOutputBuffer.Elements(), aFFTSize / 2 + 1);
}
~FFTBlock()
{
free(mFFT);
free(mIFFT);
}
void PerformFFT(const float* aData)
{
kiss_fftr_cfg fft = kiss_fftr_alloc(mFFTSize, 0, nullptr, nullptr);
kiss_fftr(fft, aData, mOutputBuffer.Elements());
free(fft);
EnsureFFT();
kiss_fftr(mFFT, aData, mOutputBuffer.Elements());
}
void PerformInverseFFT(float* aData) const
void PerformInverseFFT(float* aData)
{
kiss_fftr_cfg fft = kiss_fftr_alloc(mFFTSize, 1, nullptr, nullptr);
kiss_fftri(fft, mOutputBuffer.Elements(), aData);
free(fft);
EnsureIFFT();
kiss_fftri(mIFFT, mOutputBuffer.Elements(), aData);
for (uint32_t i = 0; i < mFFTSize; ++i) {
aData[i] /= mFFTSize;
}
@ -63,6 +68,7 @@ public:
mFFTSize = aSize;
mOutputBuffer.SetLength(aSize / 2 + 1);
PodZero(mOutputBuffer.Elements(), aSize / 2 + 1);
mFFT = mIFFT = nullptr;
}
uint32_t FFTSize() const
@ -79,6 +85,21 @@ public:
}
private:
void EnsureFFT()
{
if (!mFFT) {
mFFT = kiss_fftr_alloc(mFFTSize, 0, nullptr, nullptr);
}
}
void EnsureIFFT()
{
if (!mIFFT) {
mIFFT = kiss_fftr_alloc(mFFTSize, 1, nullptr, nullptr);
}
}
private:
kiss_fftr_cfg mFFT, mIFFT;
nsTArray<kiss_fft_cpx> mOutputBuffer;
uint32_t mFFTSize;
};