// Copyright (C) 2013 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #undef DLIB_FFt_ABSTRACT_Hh_ #ifdef DLIB_FFt_ABSTRACT_Hh_ #include "matrix_abstract.h" #include "../algs.h" namespace dlib { // ---------------------------------------------------------------------------------------- template <typename EXP> typename EXP::matrix_type fft ( const matrix_exp<EXP>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - Computes the 1 or 2 dimensional discrete Fourier transform of the given data matrix and returns it. In particular, we return a matrix D such that: - D.nr() == data.nr() - D.nc() == data.nc() - D(0,0) == the DC term of the Fourier transform. - starting with D(0,0), D contains progressively higher frequency components of the input data. - ifft(D) == data !*/ // ---------------------------------------------------------------------------------------- template < typename T, typename Alloc > matrix<std::complex<T>,0,1> fft ( const std::vector<std::complex<T>, Alloc>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - Computes the 1 dimensional discrete Fourier transform of the given data vector and returns it. In particular, we return a matrix D such that: - D.nr() == data.size() - D.nc() == 1 - D(0,0) == the DC term of the Fourier transform. - starting with D(0,0), D contains progressively higher frequency components of the input data. - ifft(D) == data !*/ // ---------------------------------------------------------------------------------------- template <typename EXP> typename EXP::matrix_type ifft ( const matrix_exp<EXP>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - Computes the 1 or 2 dimensional inverse discrete Fourier transform of the given data vector and returns it. In particular, we return a matrix D such that: - D.nr() == data.nr() - D.nc() == data.nc() - fft(D) == data !*/ // ---------------------------------------------------------------------------------------- template < typename T, typename Alloc > matrix<std::complex<T>,0,1> ifft ( const std::vector<std::complex<T>, Alloc>& data ) /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - Computes the 1 dimensional inverse discrete Fourier transform of the given data vector and returns it. In particular, we return a matrix D such that: - D.nr() == data.size() - D.nc() == 1 - fft(D) == data !*/ // ---------------------------------------------------------------------------------------- template <typename EXP> matrix<add_complex_t<typename EXP::type>> fftr ( const matrix_exp<EXP>& data ); /*! requires - data contains elements of type double, float, or long double. - data.nc() is even ensures - Computes the 1 or 2 dimensional real discrete Fourier transform of the given data matrix and returns it. In particular, we return a matrix D such that: - D.nr() == data.nr() - D.nc() == fftr_nc_size(data.nc()) - D(0,0) == the DC term of the Fourier transform. - starting with D(0,0), D contains progressively higher frequency components of the input data. - ifftr(D) == data !*/ // ---------------------------------------------------------------------------------------- template <typename EXP> matrix<remove_complex_t<typename EXP::type>> ifftr ( const matrix_exp<EXP>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - Computes the 1 or 2 dimensional inverse real discrete Fourier transform of the given data vector and returns it. In particular, we return a matrix D such that: - D.nr() == data.nr() - D.nc() == ifftr_nc_size(data.nc()) - fftr(D) == data !*/ // ---------------------------------------------------------------------------------------- template < typename T, long NR, long NC, typename MM, typename L > void fft_inplace ( matrix<std::complex<T>,NR,NC,MM,L>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - This function is identical to fft() except that it does the FFT in-place. That is, after this function executes we will have: - #data == fft(data) !*/ // ---------------------------------------------------------------------------------------- template < typename T, long NR, long NC, typename MM, typename L > void ifft_inplace ( matrix<std::complex<T>,NR,NC,MM,L>& data ); /*! requires - data contains elements of type std::complex<> that itself contains double, float, or long double. ensures - This function is identical to ifft() except that it does the inverse FFT in-place. That is, after this function executes we will have: - #data == ifft(data)*data.size() - Note that the output needs to be divided by data.size() to complete the inverse transformation. !*/ // ---------------------------------------------------------------------------------------- // These return function objects with signature double(size_t i, size_t wlen) // defining PERIODIC window functions suitable for passing to STFT functions inline function_object make_hann(); inline function_object make_blackman(); inline function_object make_blackman_nuttall(); inline function_object make_blackman_harris(); inline function_object make_blackman_harris7(); inline function_object make_kaiser(beta_t beta); // ---------------------------------------------------------------------------------------- template <typename EXP, typename WINDOW> matrix<complex_type> stft ( const matrix_exp<EXP>& signal, const WINDOW& w, std::size_t fftsize, std::size_t wlen, std::size_t hoplen ); /*! requires - is_vector(signal) == true, i.e. signal has rank 1 - signal.size() >= wlen - w is a function object with signature double(size_t i, size_t wlen) that defines a PERIODIC window, e.g. the output of make_hann(). - fftsize >= wlen - wlen >= hoplen - EXP::type is a floating point type (float, double or long double), real or complex ensures - Performs a Short-Time-Fourier-Transform (STFT) on 1D data. - Returns a matrix D where first dimension correponds to time and second dimension corresponds to frequency. - Dimensions of D are: - D.nr() == (signal.size() + hoplen) / hoplen and corresponds to the number of time frames. - D.nc() == fftsize - The type of D is add_complex_t<EXP::type> - Each time frame t (equivalently, each row t) is centered on signal(t*hoplen) - This is equivalent to calling the following in python (provided w is converted into a string representation which scipy can interpret) win = scipy.signal.get_window(w, wlen) scale = win.sum() _, _, Z = scipy.signal.stft(signal, nfft=fftsize, nperseg=wlen, noverlap=(wlen-hoplen), window=win, return_onesided=False) Z *= scale !*/ // ---------------------------------------------------------------------------------------- template <typename T, typename Alloc, typename WINDOW> matrix<complex_type> stft ( const std::vector<T, Alloc>& signal, const WINDOW& w, std::size_t fftsize, std::size_t wlen, std::size_t hoplen ); /*! ensures - This is a shortcut to calling stft(dlib::mat(signal), w, fftsize, wlen, hoplen) !*/ // ---------------------------------------------------------------------------------------- template <typename EXP,typename WINDOW> matrix<complex_type> istft ( const matrix_exp<EXP>& stft, const WINDOW& w, std::size_t wlen, std::size_t hoplen ); /*! requires - m has rank 2 where 1st dimension corresponds to time and second dimension corresponds to frequency - w is a function object with signature double(size_t i, size_t wlen) that defines a PERIODIC window, e.g. the output of make_hann(). - wlen >= hoplen - EXP::type is a complex floating point type (complex<float>, complex<double> or complex<long double>) - If you wish to satisfy istft(stft(x, ...), ...) == x then: - w is the same as what was used with stft() - wlen is the same as what was used with stft() - hoplen is the same as what was used with stft() ensures - Performs an inverse Short-Time-Fourier-Transform (STFT) - istft(stft(x, w, wlen, wlen, hoplen), w, wlen, hoplen)) == x - istft(stft(x, w, fftsize, wlen, hoplen), w, wlen, hoplen)) == x !*/ // ---------------------------------------------------------------------------------------- template <typename EXP, typename WINDOW> matrix<complex_type> stftr ( const matrix_exp<EXP>& signal, const WINDOW& w, std::size_t fftsize, std::size_t wlen, std::size_t hoplen ); /*! requires - is_vector(signal) == true, i.e. signal has rank 1 - signal.size() >= wlen - w is a function object with signature double(size_t i, size_t wlen) that defines a PERIODIC window, e.g. the output of make_hann(). - fftsize >= wlen - wlen >= hoplen - EXP::type is a floating point type (float, double or long double) and must be real ensures - Performs a real Short-Time-Fourier-Transform (STFTr) on 1D data. - Returns a matrix D where first dimension correponds to time and second dimension corresponds to frequency. - Dimensions of D are: - D.nr() == (signal.size() + hoplen) / hoplen and corresponds to the number of time frames. - D.nc() == fftsize/2 + 1 - The type of D is add_complex_t<EXP::type> - Each time frame t (equivalently each row t) is centered on signal(t*hoplen) - This is equivalent to calling the follwoing in python (provided w is converted into a string representation which scipy can interpret) win = scipy.signal.get_window(w, wlen) scale = win.sum() _, _, Z = scipy.signal.stft(signal, nfft=fftsize, nperseg=wlen, noverlap=(wlen-hoplen), window=win, return_onesided=True) Z *= scale !*/ // ---------------------------------------------------------------------------------------- template <typename T, typename Alloc, typename WINDOW> matrix<complex_type> stftr ( const std::vector<T, Alloc>& signal, const WINDOW& w, std::size_t fftsize, std::size_t wlen, std::size_t hoplen ); /*! ensures - This is a shortcut to calling istft(dlib::mat(signal), w, wlen, hoplen) !*/ // ---------------------------------------------------------------------------------------- template <typename EXP, typename WINDOW> matrix<real_type> istftr ( const matrix_exp<EXP>& stft, const WINDOW& w, std::size_t wlen, std::size_t hoplen ); /*! requires - m has rank 2 where 1st dimension corresponds to time and second dimension corresponds to frequency - w is a function object with signature double(size_t i, size_t wlen) that defines a PERIODIC window, e.g. the output of make_hann(). - wlen >= hoplen - EXP::type is a complex floating point type (complex<float>, complex<double> or complex<long double>) - If you wish to satisfy istftr(stftr(x, ...), ...) == x then: - w is the same as what was used with stftr() - wlen is the same as what was used with stftr() - hoplen is the same as what was used with stftr() ensures - Performs an inverse Short-Time-Fourier-Transform (STFT) - istftr(stftr(x, w, wlen, wlen, hoplen), w, wlen, hoplen)) == x - istftr(stftr(x, w, fftsize, wlen, hoplen), w, wlen, hoplen)) == x !*/ // ---------------------------------------------------------------------------------------- } #endif // DLIB_FFt_ABSTRACT_Hh_