1919 ==============================================================================
2020*/
2121
22- namespace yup {
22+ namespace yup
23+ {
2324
2425// ==============================================================================
2526// Implementation structure to hide backend-specific details
@@ -48,12 +49,14 @@ struct FFTProcessor::Impl
4849
4950// ==============================================================================
5051// Constructor implementations
51- FFTProcessor::FFTProcessor () : pImpl (std::make_unique<Impl>())
52+ FFTProcessor::FFTProcessor ()
53+ : pImpl (std::make_unique<Impl>())
5254{
5355 setSize (512 );
5456}
5557
56- FFTProcessor::FFTProcessor (int fftSize) : pImpl (std::make_unique<Impl>())
58+ FFTProcessor::FFTProcessor (int fftSize)
59+ : pImpl (std::make_unique<Impl>())
5760{
5861 setSize (fftSize);
5962}
@@ -64,7 +67,9 @@ FFTProcessor::~FFTProcessor()
6467}
6568
6669FFTProcessor::FFTProcessor (FFTProcessor&& other) noexcept
67- : fftSize (other.fftSize), scaling (other.scaling), pImpl (std::move (other.pImpl))
70+ : fftSize (other.fftSize)
71+ , scaling (other.scaling)
72+ , pImpl (std::move (other.pImpl))
6873{
6974 other.fftSize = 0 ;
7075}
@@ -88,7 +93,7 @@ void FFTProcessor::setSize (int newSize)
8893{
8994 jassert (isPowerOfTwo (newSize));
9095 jassert (newSize >= 2 && newSize <= 65536 );
91-
96+
9297 if (newSize != fftSize)
9398 {
9499 cleanup ();
@@ -100,7 +105,7 @@ void FFTProcessor::setSize (int newSize)
100105void FFTProcessor::performRealFFT (const float * realInput, float * complexOutput, FFTDirection direction)
101106{
102107 jassert (realInput != nullptr && complexOutput != nullptr );
103-
108+
104109#if YUP_FFT_USING_OOURA
105110 performRealFFTOoura (realInput, complexOutput, direction);
106111#elif YUP_FFT_USING_VDSP
@@ -110,14 +115,14 @@ void FFTProcessor::performRealFFT (const float* realInput, float* complexOutput,
110115#elif YUP_FFT_USING_FFTW3
111116 performRealFFTFFTW3 (realInput, complexOutput, direction);
112117#endif
113-
118+
114119 applyScaling (complexOutput, fftSize * 2 , direction);
115120}
116121
117122void FFTProcessor::performComplexFFT (const float * complexInput, float * complexOutput, FFTDirection direction)
118123{
119124 jassert (complexInput != nullptr && complexOutput != nullptr );
120-
125+
121126#if YUP_FFT_USING_OOURA
122127 performComplexFFTOoura (complexInput, complexOutput, direction);
123128#elif YUP_FFT_USING_VDSP
@@ -127,7 +132,7 @@ void FFTProcessor::performComplexFFT (const float* complexInput, float* complexO
127132#elif YUP_FFT_USING_FFTW3
128133 performComplexFFTFFTW3 (complexInput, complexOutput, direction);
129134#endif
130-
135+
131136 applyScaling (complexOutput, fftSize * 2 , direction);
132137}
133138
@@ -219,9 +224,9 @@ void FFTProcessor::applyScaling (float* data, int numElements, FFTDirection dire
219224{
220225 if (scaling == FFTScaling::none)
221226 return ;
222-
227+
223228 float scale = 1 .0f ;
224-
229+
225230 if (scaling == FFTScaling::unitary)
226231 {
227232 scale = 1 .0f / std::sqrt (static_cast <float > (fftSize));
@@ -230,7 +235,7 @@ void FFTProcessor::applyScaling (float* data, int numElements, FFTDirection dire
230235 {
231236 scale = 1 .0f / static_cast <float > (fftSize);
232237 }
233-
238+
234239 if (scale != 1 .0f )
235240 {
236241 for (int i = 0 ; i < numElements; ++i)
@@ -255,7 +260,7 @@ void FFTProcessor::performRealFFTOoura (const float* realInput, float* complexOu
255260{
256261 // Copy real input to work buffer
257262 std::copy (realInput, realInput + fftSize, pImpl->workBuffer .begin ());
258-
263+
259264 if (direction == FFTDirection::forward)
260265 {
261266 // Real-to-complex forward transform
@@ -266,17 +271,17 @@ void FFTProcessor::performRealFFTOoura (const float* realInput, float* complexOu
266271 // Complex-to-real inverse transform
267272 rdft (fftSize, -1 , pImpl->workBuffer .data (), pImpl->intBuffer .data (), pImpl->tempBuffer .data ());
268273 }
269-
274+
270275 // Convert Ooura format to standard interleaved complex format
271276 complexOutput[0 ] = pImpl->workBuffer [0 ]; // DC real
272277 complexOutput[1 ] = 0 .0f ; // DC imag
273-
278+
274279 for (int i = 1 ; i < fftSize / 2 ; ++i)
275280 {
276- complexOutput[i * 2 ] = pImpl->workBuffer [i]; // real
277- complexOutput[i * 2 + 1 ] = pImpl->workBuffer [fftSize - i]; // imag
281+ complexOutput[i * 2 ] = pImpl->workBuffer [i]; // real
282+ complexOutput[i * 2 + 1 ] = pImpl->workBuffer [fftSize - i]; // imag
278283 }
279-
284+
280285 complexOutput[fftSize] = pImpl->workBuffer [fftSize / 2 ]; // Nyquist real
281286 complexOutput[fftSize + 1 ] = 0 .0f ; // Nyquist imag
282287}
@@ -285,7 +290,7 @@ void FFTProcessor::performComplexFFTOoura (const float* complexInput, float* com
285290{
286291 // Copy interleaved complex input to work buffer
287292 std::copy (complexInput, complexInput + fftSize * 2 , pImpl->workBuffer .begin ());
288-
293+
289294 if (direction == FFTDirection::forward)
290295 {
291296 cdft (fftSize * 2 , 1 , pImpl->workBuffer .data (), pImpl->intBuffer .data (), pImpl->tempBuffer .data ());
@@ -294,7 +299,7 @@ void FFTProcessor::performComplexFFTOoura (const float* complexInput, float* com
294299 {
295300 cdft (fftSize * 2 , -1 , pImpl->workBuffer .data (), pImpl->intBuffer .data (), pImpl->tempBuffer .data ());
296301 }
297-
302+
298303 // Copy result
299304 std::copy (pImpl->workBuffer .begin (), pImpl->workBuffer .begin () + fftSize * 2 , complexOutput);
300305}
@@ -315,30 +320,30 @@ void FFTProcessor::initializeVDSP()
315320void FFTProcessor::performRealFFTVDSP (const float * realInput, float * complexOutput, FFTDirection direction)
316321{
317322 const auto halfSize = fftSize / 2 ;
318-
323+
319324 if (direction == FFTDirection::forward)
320325 {
321326 // Copy input to temp buffer
322327 std::copy (realInput, realInput + fftSize, pImpl->tempBuffer .begin ());
323-
328+
324329 // Set up split complex structure
325330 DSPSplitComplex splitComplex;
326331 splitComplex.realp = pImpl->tempBuffer .data ();
327332 splitComplex.imagp = pImpl->tempBuffer .data () + halfSize;
328-
333+
329334 // Perform real forward FFT
330335 vDSP_fft_zrip (pImpl->fftSetup , &splitComplex, 2 , static_cast <vDSP_Length> (std::log2 (fftSize)), kFFTDirection_Forward );
331-
336+
332337 // Convert split format to interleaved format
333338 complexOutput[0 ] = splitComplex.realp [0 ]; // DC real
334339 complexOutput[1 ] = 0 .0f ; // DC imag
335-
340+
336341 for (int i = 1 ; i < halfSize; ++i)
337342 {
338343 complexOutput[i * 2 ] = splitComplex.realp [i]; // real
339344 complexOutput[i * 2 + 1 ] = splitComplex.imagp [i]; // imag
340345 }
341-
346+
342347 complexOutput[fftSize] = splitComplex.imagp [0 ]; // Nyquist real (stored in DC imag)
343348 complexOutput[fftSize + 1 ] = 0 .0f ; // Nyquist imag
344349 }
@@ -348,20 +353,20 @@ void FFTProcessor::performRealFFTVDSP (const float* realInput, float* complexOut
348353 DSPSplitComplex splitComplex;
349354 splitComplex.realp = pImpl->tempBuffer .data ();
350355 splitComplex.imagp = pImpl->tempBuffer .data () + halfSize;
351-
356+
352357 // Convert interleaved to split format
353- splitComplex.realp [0 ] = complexInput[0 ]; // DC real
358+ splitComplex.realp [0 ] = complexInput[0 ]; // DC real
354359 splitComplex.imagp [0 ] = complexInput[fftSize]; // Nyquist real
355-
360+
356361 for (int i = 1 ; i < halfSize; ++i)
357362 {
358363 splitComplex.realp [i] = complexInput[i * 2 ]; // real
359364 splitComplex.imagp [i] = complexInput[i * 2 + 1 ]; // imag
360365 }
361-
366+
362367 // Perform real inverse FFT
363368 vDSP_fft_zrip (pImpl->fftSetup , &splitComplex, 2 , static_cast <vDSP_Length> (std::log2 (fftSize)), kFFTDirection_Inverse );
364-
369+
365370 // Copy result
366371 std::copy (pImpl->tempBuffer .begin (), pImpl->tempBuffer .begin () + fftSize, complexOutput);
367372 }
@@ -370,18 +375,17 @@ void FFTProcessor::performRealFFTVDSP (const float* realInput, float* complexOut
370375void FFTProcessor::performComplexFFTVDSP (const float * complexInput, float * complexOutput, FFTDirection direction)
371376{
372377 const auto halfSize = fftSize / 2 ;
373-
378+
374379 // Set up split complex structure
375380 DSPSplitComplex splitInput, splitOutput;
376381 splitInput.realp = const_cast <float *> (complexInput);
377382 splitInput.imagp = const_cast <float *> (complexInput) + 1 ;
378383 splitOutput.realp = complexOutput;
379384 splitOutput.imagp = complexOutput + 1 ;
380-
385+
381386 // Perform complex FFT
382387 const auto fftDirection = (direction == FFTDirection::forward) ? kFFTDirection_Forward : kFFTDirection_Inverse ;
383- vDSP_fft_zop (pImpl->fftSetup , &splitInput, 2 , &splitOutput, 2 ,
384- static_cast <vDSP_Length> (std::log2 (fftSize)), fftDirection);
388+ vDSP_fft_zop (pImpl->fftSetup , &splitInput, 2 , &splitOutput, 2 , static_cast <vDSP_Length> (std::log2 (fftSize)), fftDirection);
385389}
386390
387391#endif
@@ -393,21 +397,19 @@ void FFTProcessor::performComplexFFTVDSP (const float* complexInput, float* comp
393397void FFTProcessor::initializeIPP ()
394398{
395399 int specSizeComplex, specSizeReal, workSizeComplex, workSizeReal;
396-
400+
397401 // Get buffer sizes
398- ippsFFTGetSize_C_32fc (static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast,
399- &specSizeComplex, nullptr , &workSizeComplex);
400- ippsFFTGetSize_R_32f (static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast,
401- &specSizeReal, nullptr , &workSizeReal);
402-
402+ ippsFFTGetSize_C_32fc (static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, &specSizeComplex, nullptr , &workSizeComplex);
403+ ippsFFTGetSize_R_32f (static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast, &specSizeReal, nullptr , &workSizeReal);
404+
403405 // Allocate specification structures
404406 pImpl->specComplex = reinterpret_cast <IppsFFTSpec_C_32fc*> (ippsMalloc_8u (specSizeComplex));
405407 pImpl->specReal = reinterpret_cast <IppsFFTSpec_R_32f*> (ippsMalloc_8u (specSizeReal));
406-
408+
407409 // Initialize specifications
408410 ippsFFTInit_C_32fc (&pImpl->specComplex , static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast);
409411 ippsFFTInit_R_32f (&pImpl->specReal , static_cast <int > (std::log2 (fftSize)), IPP_FFT_NODIV_BY_ANY, ippAlgHintFast);
410-
412+
411413 // Allocate work buffer
412414 const int maxWorkSize = jmax (workSizeComplex, workSizeReal);
413415 pImpl->workBuffer = reinterpret_cast <Ipp32fc*> (ippsMalloc_8u (maxWorkSize));
@@ -429,7 +431,7 @@ void FFTProcessor::performComplexFFTIPP (const float* complexInput, float* compl
429431{
430432 const auto * input = reinterpret_cast <const Ipp32fc*> (complexInput);
431433 auto * output = reinterpret_cast <Ipp32fc*> (complexOutput);
432-
434+
433435 if (direction == FFTDirection::forward)
434436 {
435437 ippsFFTFwd_CToC_32fc (input, output, pImpl->specComplex , reinterpret_cast <Ipp8u*> (pImpl->workBuffer ));
@@ -451,11 +453,11 @@ void FFTProcessor::initializeFFTW3()
451453 // Allocate buffers
452454 pImpl->tempComplexBuffer .resize (static_cast <size_t > (fftSize));
453455 pImpl->tempRealBuffer .resize (static_cast <size_t > (fftSize));
454-
456+
455457 // Create plans
456458 auto * complexData = pImpl->tempComplexBuffer .data ();
457459 auto * realData = pImpl->tempRealBuffer .data ();
458-
460+
459461 pImpl->planComplexForward = fftwf_plan_dft_1d (fftSize, complexData, complexData, FFTW_FORWARD, FFTW_ESTIMATE);
460462 pImpl->planComplexInverse = fftwf_plan_dft_1d (fftSize, complexData, complexData, FFTW_BACKWARD, FFTW_ESTIMATE);
461463 pImpl->planRealForward = fftwf_plan_dft_r2c_1d (fftSize, realData, complexData, FFTW_ESTIMATE);
@@ -468,7 +470,7 @@ void FFTProcessor::performRealFFTFFTW3 (const float* realInput, float* complexOu
468470 {
469471 std::copy (realInput, realInput + fftSize, pImpl->tempRealBuffer .begin ());
470472 fftwf_execute (pImpl->planRealForward );
471-
473+
472474 // Convert FFTW format to interleaved format
473475 const auto halfSize = fftSize / 2 + 1 ;
474476 for (int i = 0 ; i < halfSize; ++i)
@@ -486,7 +488,7 @@ void FFTProcessor::performRealFFTFFTW3 (const float* realInput, float* complexOu
486488 pImpl->tempComplexBuffer [i][0 ] = complexInput[i * 2 ]; // real
487489 pImpl->tempComplexBuffer [i][1 ] = complexInput[i * 2 + 1 ]; // imag
488490 }
489-
491+
490492 fftwf_execute (pImpl->planRealInverse );
491493 std::copy (pImpl->tempRealBuffer .begin (), pImpl->tempRealBuffer .begin () + fftSize, complexOutput);
492494 }
@@ -500,7 +502,7 @@ void FFTProcessor::performComplexFFTFFTW3 (const float* complexInput, float* com
500502 pImpl->tempComplexBuffer [i][0 ] = complexInput[i * 2 ]; // real
501503 pImpl->tempComplexBuffer [i][1 ] = complexInput[i * 2 + 1 ]; // imag
502504 }
503-
505+
504506 if (direction == FFTDirection::forward)
505507 {
506508 fftwf_execute (pImpl->planComplexForward );
@@ -509,7 +511,7 @@ void FFTProcessor::performComplexFFTFFTW3 (const float* complexInput, float* com
509511 {
510512 fftwf_execute (pImpl->planComplexInverse );
511513 }
512-
514+
513515 // Convert FFTW format to interleaved
514516 for (int i = 0 ; i < fftSize; ++i)
515517 {
0 commit comments