1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

DSP: Added hint flag to tell juce's FFT to only calculate positive frequencies when perforing real to complex transforms

This commit is contained in:
hogliux 2017-08-22 13:54:38 +01:00
parent 8424030e50
commit e61292fe57
3 changed files with 52 additions and 21 deletions

View file

@ -29,7 +29,7 @@ struct FFT::Instance
{
virtual ~Instance() {}
virtual void perform (const Complex<float>* input, Complex<float>* output, bool inverse) const noexcept = 0;
virtual void performRealOnlyForwardTransform (float*) const noexcept = 0;
virtual void performRealOnlyForwardTransform (float*, bool) const noexcept = 0;
virtual void performRealOnlyInverseTransform (float*) const noexcept = 0;
};
@ -131,7 +131,7 @@ struct FFTFallback : public FFT::Instance
const size_t maxFFTScratchSpaceToAlloca = 256 * 1024;
void performRealOnlyForwardTransform (float* d) const noexcept override
void performRealOnlyForwardTransform (float* d, bool) const noexcept override
{
if (size == 1)
return;
@ -180,7 +180,12 @@ struct FFTFallback : public FFT::Instance
void performRealOnlyInverseTransform (Complex<float>* scratch, float* d) const noexcept
{
perform (reinterpret_cast<const Complex<float>*> (d), scratch, true);
auto* input = reinterpret_cast<Complex<float>*> (d);
for (auto i = size >> 1; i < size; ++i)
input[i] = std::conj (input[size - i]);
perform (input, scratch, true);
for (int i = 0; i < size; ++i)
{
@ -464,7 +469,7 @@ struct AppleFFT : public FFT::Instance
vDSP_vsmul ((float*) output, 1, &factor, (float*) output, 1, static_cast<size_t> (size << 1));
}
void performRealOnlyForwardTransform (float* inoutData) const noexcept override
void performRealOnlyForwardTransform (float* inoutData, bool ignoreNegativeFreqs) const noexcept override
{
auto size = (1 << order);
auto* inout = reinterpret_cast<Complex<float>*> (inoutData);
@ -473,7 +478,8 @@ struct AppleFFT : public FFT::Instance
inoutData[size] = 0.0f;
vDSP_fft_zrip (fftSetup, &splitInOut, 2, order, kFFTDirection_Forward);
vDSP_vsmul (inoutData, 1, &forwardNormalisation, inoutData, 1, static_cast<size_t> (size << 1));
mirrorResult (inout);
mirrorResult (inout, ignoreNegativeFreqs);
}
void performRealOnlyInverseTransform (float* inoutData) const noexcept override
@ -495,7 +501,7 @@ struct AppleFFT : public FFT::Instance
private:
//==============================================================================
void mirrorResult (Complex<float>* out) const noexcept
void mirrorResult (Complex<float>* out, bool ignoreNegativeFreqs) const noexcept
{
auto size = (1 << order);
auto i = size >> 1;
@ -506,8 +512,9 @@ private:
out[i++] = { out[0].imag(), 0.0 };
out[0] = { out[0].real(), 0.0 };
for (; i < size; ++i)
out[i] = std::conj (out[size - i]);
if (! ignoreNegativeFreqs)
for (; i < size; ++i)
out[i] = std::conj (out[size - i]);
}
static DSPSplitComplex toSplitComplex (Complex<float>* data) noexcept
@ -671,7 +678,7 @@ struct FFTWImpl : public FFT::Instance
}
}
void performRealOnlyForwardTransform (float* inputOutputData) const noexcept override
void performRealOnlyForwardTransform (float* inputOutputData, bool ignoreNegativeFreqs) const noexcept override
{
if (order == 0)
return;
@ -682,8 +689,9 @@ struct FFTWImpl : public FFT::Instance
auto size = (1 << order);
for (auto i = size >> 1; i < size; ++i)
out[i] = std::conj (out[size - i]);
if (! ignoreNegativeFreqs)
for (auto i = size >> 1; i < size; ++i)
out[i] = std::conj (out[size - i]);
}
void performRealOnlyInverseTransform (float* inputOutputData) const noexcept override
@ -761,7 +769,7 @@ struct IntelFFT : public FFT::Instance
DftiComputeForward (c2c, (void*) input, output);
}
void performRealOnlyForwardTransform (float* inputOutputData) const noexcept override
void performRealOnlyForwardTransform (float* inputOutputData, bool ignoreNegativeFreqs) const noexcept override
{
if (order == 0)
return;
@ -771,8 +779,9 @@ struct IntelFFT : public FFT::Instance
auto* out = reinterpret_cast<Complex<float>*> (inputOutputData);
auto size = (1 << order);
for (auto i = size >> 1; i < size; ++i)
out[i] = std::conj (out[size - i]);
if (! ignoreNegativeFreqs)
for (auto i = size >> 1; i < size; ++i)
out[i] = std::conj (out[size - i]);
}
void performRealOnlyInverseTransform (float* inputOutputData) const noexcept override
@ -802,10 +811,10 @@ void FFT::perform (const Complex<float>* input, Complex<float>* output, bool inv
engine->perform (input, output, inverse);
}
void FFT::performRealOnlyForwardTransform (float* inputOutputData) const noexcept
void FFT::performRealOnlyForwardTransform (float* inputOutputData, bool ignoreNeagtiveFreqs) const noexcept
{
if (engine != nullptr)
engine->performRealOnlyForwardTransform (inputOutputData);
engine->performRealOnlyForwardTransform (inputOutputData, ignoreNeagtiveFreqs);
}
void FFT::performRealOnlyInverseTransform (float* inputOutputData) const noexcept