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:
parent
8424030e50
commit
e61292fe57
3 changed files with 52 additions and 21 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue