zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

FFTwrapper.h (4341B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   FFTwrapper.h  -  A wrapper for Fast Fourier Transforms
      5   Copyright (C) 2002-2005 Nasca Octavian Paul
      6   Author: Nasca Octavian Paul
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License
     10   as published by the Free Software Foundation; either version 2
     11   of the License, or (at your option) any later version.
     12 */
     13 
     14 #ifndef FFT_WRAPPER_H
     15 #define FFT_WRAPPER_H
     16 #include <fftw3.h>
     17 #include <complex>
     18 #include "../globals.h"
     19 
     20 namespace zyn {
     21 
     22 //! Struct to make sure FFT sizes fit. *Not* an RAII class
     23 struct FFTfreqBuffer
     24 {
     25     friend class FFTwrapper;
     26 
     27     const int fftsize;
     28     fft_t* data;
     29 
     30     // comfort functions
     31     fft_t& operator[](std::size_t idx) { return data[idx]; }
     32     const fft_t& operator[](std::size_t idx) const { return data[idx]; }
     33     //! Allocation size. For users of this class, `fftsize/2` would be enough,
     34     //! But fftw needs `fftsize+1` freqs to operate on
     35     int allocSize() const { return fftsize + 1; }
     36 
     37 private:
     38     FFTfreqBuffer(int fftsize, fft_t* ptr = nullptr) : // called by FFTwrapper
     39         fftsize(fftsize),
     40         data(ptr ? ptr : new fft_t[allocSize()])
     41     {}
     42 };
     43 
     44 //! Struct to make sure FFT sizes fit. *Not* an RAII class
     45 struct FFTsampleBuffer
     46 {
     47     friend class FFTwrapper;
     48 
     49     const int fftsize;
     50     float* data;
     51 
     52     // comfort functions
     53     float& operator[](std::size_t idx) { return data[idx]; }
     54     const float& operator[](std::size_t idx) const { return data[idx]; }
     55     int allocSize() const { return fftsize; }
     56 
     57 private:
     58     FFTsampleBuffer(int fftsize, float* ptr = nullptr) : // called by FFTwrapper
     59         fftsize(fftsize),
     60         data(ptr ? ptr : new float[allocSize()])
     61     {}
     62 };
     63 
     64 /**
     65     A wrapper for the FFTW library (Fast Fourier Transforms)
     66     All methods (except CTOR/DTOR) are static/const. This class is thread-safe.
     67 */
     68 class FFTwrapper
     69 {
     70     public:
     71         /**Constructor
     72          * @param fftsize_ The size of samples to be fed to fftw*/
     73         FFTwrapper(int fftsize_);
     74         /**Destructor*/
     75         ~FFTwrapper();
     76         /**Convert Samples to Frequencies using Fourier Transform
     77          * @param smps Pointer to Samples to be converted; has length fftsize_
     78          * @param freqs Structure FFTFREQS which stores the frequencies*/
     79         void smps2freqs(const FFTsampleBuffer smps, FFTfreqBuffer freqs, FFTsampleBuffer scratch) const;
     80         void freqs2smps(const FFTfreqBuffer freqs, FFTsampleBuffer smps, FFTfreqBuffer scratch) const;
     81         void smps2freqs_noconst_input(FFTsampleBuffer smps, FFTfreqBuffer freqs) const;
     82         void freqs2smps_noconst_input(FFTfreqBuffer freqs, FFTsampleBuffer smps) const;
     83 
     84         // Whenever you need one of the FFT*Buffers, you take them from here
     85         // The methods make sure that the FFT*Buffers match the fftsize
     86         FFTfreqBuffer allocFreqBuf(fft_t* ptr = nullptr) const { return FFTfreqBuffer(m_fftsize, ptr); }
     87         FFTsampleBuffer allocSampleBuf(float* ptr = nullptr) const { return FFTsampleBuffer(m_fftsize, ptr); }
     88         // These should only be used exceptionally if you need to alloc those buffers,
     89         // buf never run any FFT/IFFT on them
     90         static FFTfreqBuffer riskAllocFreqBufWithSize(int othersize) { return FFTfreqBuffer(othersize); }
     91         static FFTsampleBuffer riskAllocSampleBufWithSize(int othersize) { return FFTsampleBuffer(othersize); }
     92 
     93         int fftsize() const { return m_fftsize; }
     94 
     95     private:
     96         const int     m_fftsize;
     97         fftwf_real    *time; // only used when creating plan
     98         fftwf_complex *fft;  // only used when creating plan
     99         fftwf_plan    planfftw, planfftw_inv;
    100 };
    101 
    102 /*
    103  * The "std::polar" template has no clear definition for the range of
    104  * the input parameters, and some C++ standard library implementations
    105  * don't accept negative amplitude among others. Define our own
    106  * FFTpolar template, which works like we expect it to.
    107  */
    108 template<class _Tp>
    109 std::complex<_Tp>
    110 FFTpolar(const _Tp& __rho, const _Tp& __theta = _Tp(0))
    111 {
    112         _Tp __x = __rho * std::cos(__theta);
    113         if (std::isnan(__x))
    114                 __x = 0;
    115         _Tp __y = __rho * std::sin(__theta);
    116         if (std::isnan(__y))
    117                 __y = 0;
    118         return std::complex<_Tp>(__x, __y);
    119 }
    120 
    121 void FFT_cleanup();
    122 
    123 }
    124 
    125 #endif