18#ifndef R8B_CDSPREALFFT_INCLUDED
19#define R8B_CDSPREALFFT_INCLUDED
24 #include "pffft_double/pffft_double.h"
66 return( InvMulConst );
100 float*
const op = (
float*) p;
103 for( i = 0; i < Len; i++ )
105 op[ i ] = (float) p[ i ];
112 ippsFFTFwd_RToPerm_64f( p, p, SPtr, WorkBuffer );
116 pffft_transform_ordered( setup, op, op, work, PFFFT_FORWARD );
118 #elif R8B_PFFFT_DOUBLE
120 pffftd_transform_ordered( setup, p, p, work, PFFFT_FORWARD );
124 ooura_fft :: rdft( Len, 1, p, wi, wd );
140 ippsFFTInv_PermToR_64f( p, p, SPtr, WorkBuffer );
144 pffft_transform_ordered( setup, (
float*) p, (
float*) p, work,
147 #elif R8B_PFFFT_DOUBLE
149 pffftd_transform_ordered( setup, p, p, work, PFFFT_BACKWARD );
153 ooura_fft :: rdft( Len, -1, p, wi, wd );
159 const float*
const ip = (
const float*) p;
162 for( i = Len - 1; i >= 0; i-- )
183 double*
const aop )
const
187 const float*
const ip1 = (
const float*) aip1;
188 const float*
const ip2 = (
const float*) aip2;
189 float*
const op = (
float*) aop;
193 const double*
const ip1 = aip1;
194 const double*
const ip2 = aip2;
195 double*
const op = aop;
201 ippsMulPerm_64f( (Ipp64f*) ip1, (Ipp64f*) ip2, (Ipp64f*) op, Len );
205 op[ 0 ] = ip1[ 0 ] * ip2[ 0 ];
206 op[ 1 ] = ip1[ 1 ] * ip2[ 1 ];
212 op[ i ] = ip1[ i ] * ip2[ i ] - ip1[ i + 1 ] * ip2[ i + 1 ];
213 op[ i + 1 ] = ip1[ i ] * ip2[ i + 1 ] + ip1[ i + 1 ] * ip2[ i ];
233 const float*
const ip = (
const float*) aip;
234 float*
const op = (
float*) aop;
239 const double*
const ip = aip;
240 double*
const op = aop;
250 ippsMulPerm_64f( (Ipp64f*) op, (Ipp64f*) ip, (Ipp64f*) op, Len );
261 t = op[ i ] * ip[ i ] - op[ i + 1 ] * ip[ i + 1 ];
262 op[ i + 1 ] = op[ i ] * ip[ i + 1 ] + op[ i + 1 ] * ip[ i ];
286 const float*
const ip = (
const float*) aip;
287 float*
const op = (
float*) aop;
291 const double* ip = aip;
298 #if !R8B_FLOATFFT && defined( R8B_SSE2 )
304 const __m128d iv1 = _mm_load_pd( ip );
305 const __m128d iv2 = _mm_load_pd( ip + 2 );
306 const __m128d ov1 = _mm_load_pd( op );
307 const __m128d ov2 = _mm_load_pd( op + 2 );
308 _mm_store_pd( op, _mm_mul_pd( iv1, ov1 ));
309 _mm_store_pd( op + 2, _mm_mul_pd( iv2, ov2 ));
311 const __m128d iv3 = _mm_load_pd( ip + 4 );
312 const __m128d ov3 = _mm_load_pd( op + 4 );
313 const __m128d iv4 = _mm_load_pd( ip + 6 );
314 const __m128d ov4 = _mm_load_pd( op + 6 );
315 _mm_store_pd( op + 4, _mm_mul_pd( iv3, ov3 ));
316 _mm_store_pd( op + 6, _mm_mul_pd( iv4, ov4 ));
333 #elif !R8B_FLOATFFT && defined( R8B_NEON )
339 const float64x2_t iv1 = vld1q_f64( ip );
340 const float64x2_t iv2 = vld1q_f64( ip + 2 );
341 const float64x2_t ov1 = vld1q_f64( op );
342 const float64x2_t ov2 = vld1q_f64( op + 2 );
343 vst1q_f64( op, vmulq_f64( iv1, ov1 ));
344 vst1q_f64( op + 2, vmulq_f64( iv2, ov2 ));
346 const float64x2_t iv3 = vld1q_f64( ip + 4 );
347 const float64x2_t iv4 = vld1q_f64( ip + 6 );
348 const float64x2_t ov3 = vld1q_f64( op + 4 );
349 const float64x2_t ov4 = vld1q_f64( op + 6 );
350 vst1q_f64( op + 4, vmulq_f64( iv3, ov3 ));
351 vst1q_f64( op + 6, vmulq_f64( iv4, ov4 ));
372 for( i = 0; i < Len; i++ )
392 float*
const p = (
float*) ap;
396 double*
const p = ap;
416 IppsFFTSpec_R_64f* SPtr;
423 #elif R8B_PFFFT_DOUBLE
451 CObjKeeper& operator = ( CDSPRealFFT*
const aObject )
457 operator CDSPRealFFT* ()
const
478 CDSPRealFFT(
const int aLenBits )
479 : LenBits( aLenBits )
480 , Len( 1 << aLenBits )
482 , InvMulConst( 1.0 / Len )
484 , InvMulConst( 1.0 / Len )
486 , InvMulConst( 1.0 / Len )
488 , InvMulConst( 2.0 / Len )
497 ippsFFTGetSize_R_64f( LenBits, IPP_FFT_NODIV_BY_ANY,
498 ippAlgHintFast, &SpecSize, &SpecBufferSize, &BufferSize );
500 CFixedBuffer< unsigned char > InitBuffer( SpecBufferSize );
501 SpecBuffer.
alloc( SpecSize );
502 WorkBuffer.
alloc( BufferSize );
504 ippsFFTInit_R_64f( &SPtr, LenBits, IPP_FFT_NODIV_BY_ANY,
505 ippAlgHintFast, SpecBuffer, InitBuffer );
509 setup = pffft_new_setup( Len, PFFFT_REAL );
512 #elif R8B_PFFFT_DOUBLE
514 setup = pffftd_new_setup( Len, PFFFT_REAL );
519 wi.
alloc( (
int) ceil( 2.0 + sqrt( (
double) ( Len >> 1 ))));
521 wd.
alloc( Len >> 1 );
529 pffft_destroy_setup( setup );
530 #elif R8B_PFFFT_DOUBLE
531 pffftd_destroy_setup( setup );
565 Object = acquire( LenBits );
599 if( Object -> LenBits == LenBits )
607 Object = acquire( LenBits );
627 static CDSPRealFFT :: CObjKeeper FFTObjects[];
638 R8BASSERT( LenBits > 0 && LenBits <= 30 );
642 if( FFTObjects[ LenBits ] == NULL )
647 CDSPRealFFT* ffto = FFTObjects[ LenBits ];
648 FFTObjects[ LenBits ] = ffto -> Next;
659 void release( CDSPRealFFT*
const ffto )
663 ffto -> Next = FFTObjects[ ffto -> LenBits ];
664 FFTObjects[ ffto -> LenBits ] = ffto;
692 const int LenMult = 2,
const bool DoFinalMul =
true,
693 double*
const DCGroupDelay = NULL )
699 const int Len = 1 << LenBits;
700 const int Len2 = Len >> 1;
706 memcpy( &ip[ 0 ], Kernel, KernelLen *
sizeof( ip[ 0 ]));
707 memset( &ip[ KernelLen ], 0, ( Len - KernelLen ) *
sizeof( ip[ 0 ]));
710 ffto -> forward( ip );
716 float*
const aip = (
float*) &ip[ 0 ];
717 float*
const aip2 = (
float*) &ip2[ 0 ];
718 const float nzbias = 1e-35;
720 double*
const aip = &ip[ 0 ];
721 double*
const aip2 = &ip2[ 0 ];
722 const double nzbias = 1e-300;
725 aip2[ 0 ] = aip[ 0 ];
726 aip[ 0 ] = log( fabs( aip[ 0 ]) + nzbias );
727 aip2[ Len2 ] = aip[ 1 ];
728 aip[ 1 ] = log( fabs( aip[ 1 ]) + nzbias );
730 for( i = 1; i < Len2; i++ )
732 aip2[ i ] = sqrt( aip[ i * 2 ] * aip[ i * 2 ] +
733 aip[ i * 2 + 1 ] * aip[ i * 2 + 1 ]);
735 aip[ i * 2 ] = log( aip2[ i ] + nzbias );
736 aip[ i * 2 + 1 ] = 0.0;
741 ffto -> inverse( ip );
743 const double m1 = ffto -> getInvMulConst();
744 const double m2 = -m1;
748 for( i = 1; i < Len2; i++ )
755 for( i = Len2 + 1; i < Len; i++ )
764 ffto -> forward( ip );
766 aip[ 0 ] = aip2[ 0 ];
767 aip[ 1 ] = aip2[ Len2 ];
769 for( i = 1; i < Len2; i++ )
771 aip[ i * 2 + 0 ] = cos( aip[ i * 2 + 1 ]) * aip2[ i ];
772 aip[ i * 2 + 1 ] = sin( aip[ i * 2 + 1 ]) * aip2[ i ];
775 ffto -> inverse( ip );
779 for( i = 0; i < KernelLen; i++ )
781 Kernel[ i ] = ip[ i ] * m1;
786 memcpy( &Kernel[ 0 ], &ip[ 0 ], KernelLen *
sizeof( Kernel[ 0 ]));
789 if( DCGroupDelay != NULL )
Wrapper class for Takuya OOURA's FFT functions.
The "base" inclusion file with basic classes and functions.
#define R8BSYNC(SyncObject)
Definition: r8bbase.h:660
#define R8BNOCTOR(ClassName)
Definition: r8bbase.h:154
#define R8BASSERT(e)
Definition: r8bconf.h:27
#define R8B_PFFFT
Definition: r8bconf.h:170
#define R8B_BASECLASS
Definition: r8bconf.h:54
#define R8B_PFFFT_DOUBLE
Definition: r8bconf.h:159
#define R8B_IPP
Definition: r8bconf.h:147
The "r8brain-free-src" library namespace.
Definition: CDSPBlockConvolver.h:21
double calcFIRFilterGroupDelay(const double *const flt, const int fltlen, const double th)
Definition: r8bbase.h:872
int getBitOccupancy(const int v)
Definition: r8bbase.h:766
void calcMinPhaseTransform(double *const Kernel, const int KernelLen, const int LenMult=2, const bool DoFinalMul=true, double *const DCGroupDelay=NULL)
Definition: CDSPRealFFT.h:691
Real-valued FFT transform class.
Definition: CDSPRealFFT.h:53
int getLenBits() const
Definition: CDSPRealFFT.h:74
void convertToZP(double *const ap) const
Definition: CDSPRealFFT.h:388
void multiplyBlocks(const double *const aip, double *const aop) const
Definition: CDSPRealFFT.h:229
double getInvMulConst() const
Definition: CDSPRealFFT.h:64
void inverse(double *const p) const
Definition: CDSPRealFFT.h:136
void multiplyBlocks(const double *const aip1, const double *const aip2, double *const aop) const
Definition: CDSPRealFFT.h:182
void forward(double *const p) const
Definition: CDSPRealFFT.h:96
int getLen() const
Definition: CDSPRealFFT.h:84
void multiplyBlocksZP(const double *const aip, double *const aop) const
Definition: CDSPRealFFT.h:282
A "keeper" class for real-valued FFT transform objects.
Definition: CDSPRealFFT.h:547
void init(const int LenBits)
Definition: CDSPRealFFT.h:595
void reset()
Definition: CDSPRealFFT.h:614
CDSPRealFFTKeeper(const int LenBits)
Definition: CDSPRealFFT.h:563
const CDSPRealFFT * operator->() const
Definition: CDSPRealFFT.h:580
Templated memory buffer class for element buffers of fixed capacity.
Definition: r8bbase.h:304
void alloc(const int Capacity)
Definition: r8bbase.h:343
Multi-threaded synchronization object class.
Definition: r8bbase.h:526