diff --git a/modules/juce_audio_basics/effects/juce_FFT.cpp b/modules/juce_audio_basics/effects/juce_FFT.cpp index 2f8829fe8b..dd3e7cc30a 100644 --- a/modules/juce_audio_basics/effects/juce_FFT.cpp +++ b/modules/juce_audio_basics/effects/juce_FFT.cpp @@ -225,19 +225,43 @@ void FFT::perform (const Complex* const input, Complex* const output) const noex config->perform (input, output); } +const size_t maxFFTScratchSpaceToAlloca = 256 * 1024; + void FFT::performRealOnlyForwardTransform (float* d) const noexcept +{ + const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size; + + if (scratchSize < maxFFTScratchSpaceToAlloca) + { + performRealOnlyForwardTransform (static_cast (alloca (scratchSize)), d); + } + else + { + HeapBlock heapSpace (scratchSize); + performRealOnlyForwardTransform (reinterpret_cast (heapSpace.getData()), d); + } +} + +void FFT::performRealOnlyInverseTransform (float* d) const noexcept +{ + const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size; + + if (scratchSize < maxFFTScratchSpaceToAlloca) + { + performRealOnlyForwardTransform (static_cast (alloca (scratchSize)), d); + } + else + { + HeapBlock heapSpace (scratchSize); + performRealOnlyInverseTransform (reinterpret_cast (heapSpace.getData()), d); + } +} + +void FFT::performRealOnlyForwardTransform (Complex* scratch, float* d) const noexcept { // This can only be called on an FFT object that was created to do forward transforms. jassert (! config->inverse); - const size_t sizeInBytes = 16 + sizeof (Complex) * (size_t) size; - - Complex* scratch = static_cast (alloca (sizeInBytes)); - - // try malloc if alloca fails - if (scratch == nullptr) - scratch = static_cast (malloc (sizeInBytes)); - for (int i = 0; i < size; ++i) { scratch[i].r = d[i]; @@ -247,19 +271,11 @@ void FFT::performRealOnlyForwardTransform (float* d) const noexcept perform (scratch, reinterpret_cast (d)); } -void FFT::performRealOnlyInverseTransform (float* d) const noexcept +void FFT::performRealOnlyInverseTransform (Complex* scratch, float* d) const noexcept { // This can only be called on an FFT object that was created to do inverse transforms. jassert (config->inverse); - const size_t sizeInBytes = 16 + sizeof (Complex) * (size_t) size; - - Complex* scratch = static_cast (alloca (sizeInBytes)); - - // try malloc if alloca fails - if (scratch == nullptr) - scratch = static_cast (malloc (sizeInBytes)); - perform (reinterpret_cast (d), scratch); const float scaleFactor = 1.0f / size; diff --git a/modules/juce_audio_basics/effects/juce_FFT.h b/modules/juce_audio_basics/effects/juce_FFT.h index 03eee853f0..f535291970 100644 --- a/modules/juce_audio_basics/effects/juce_FFT.h +++ b/modules/juce_audio_basics/effects/juce_FFT.h @@ -88,5 +88,8 @@ private: ScopedPointer config; const int size; + void performRealOnlyForwardTransform (Complex*, float*) const noexcept; + void performRealOnlyInverseTransform (Complex*, float*) const noexcept; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFT) };