From: Takenori Y. <tak...@us...> - 2016-12-22 16:09:09
|
Update of /cvsroot/sp-tk/SPTK4/src In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv28419 Modified Files: Makefile fft.cc ifft.cc Added Files: fast_fourier_transform_for_real_sequence.cc fast_fourier_transform_for_real_sequence.h Log Message: add class of FFT for real sequence Index: ifft.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/ifft.cc,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ifft.cc 12 Oct 2016 12:14:38 -0000 1.5 --- ifft.cc 22 Dec 2016 16:09:07 -0000 1.6 *************** *** 140,153 **** } - // check FFT size - sptk::FastFourierTransform fft; - if (!fft.SetNumDimension(fft_size)) { - std::ostringstream error_message; - error_message << "The FFT size must be a power of 2 and greater than 2"; - sptk::PrintErrorMessage("ifft", error_message); - return 1; - } - fft.SetInverseFlag(true); - // get input file const char* input_file((optind < argc) ? argv[argc - 1] : NULL); --- 140,143 ---- *************** *** 164,167 **** --- 154,166 ---- std::istream& input_stream(ifs.fail() ? std::cin : ifs); + // prepare for fast Fourier transform + sptk::FastFourierTransform fft(fft_size - 1, fft_size, true); + if (!fft.IsValid()) { + std::ostringstream error_message; + error_message << "FFT size must be a power of 2 and greater than 2"; + sptk::PrintErrorMessage("ifft", error_message); + return 1; + } + std::vector<double> input_x(fft_size); std::vector<double> input_y(fft_size); --- NEW FILE: fast_fourier_transform_for_real_sequence.h --- // ----------------------------------------------------------------- // // The Speech Signal Processing Toolkit (SPTK) // // developed by SPTK Working Group // // http://sp-tk.sourceforge.net/ // // ----------------------------------------------------------------- // // // // Copyright (c) 1984-2007 Tokyo Institute of Technology // // Interdisciplinary Graduate School of // // Science and Engineering // // // // 1996-2016 Nagoya Institute of Technology // // Department of Computer Science // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or // // without modification, are permitted provided that the following // // conditions are met: // // // // - Redistributions of source code must retain the above copyright // // notice, this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above // // copyright notice, this list of conditions and the following // // disclaimer in the documentation and/or other materials provided // // with the distribution. // // - Neither the name of the SPTK working group nor the names of its // // contributors may be used to endorse or promote products derived // // from this software without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND // // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS // // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // // POSSIBILITY OF SUCH DAMAGE. // // ----------------------------------------------------------------- // #ifndef SPTK_SRC_FAST_FOURIER_TRANSFORM_FOR_REAL_SEQUENCE_H_ #define SPTK_SRC_FAST_FOURIER_TRANSFORM_FOR_REAL_SEQUENCE_H_ #include <vector> // std::vector #include "fast_fourier_transform.h" #include "sptk_utils.h" namespace sptk { class FastFourierTransformForRealSequence { public: class Buffer { public: Buffer() { } virtual ~Buffer() { } private: std::vector<double> real_part_input_; std::vector<double> imaginary_part_input_; friend class FastFourierTransformForRealSequence; DISALLOW_COPY_AND_ASSIGN(Buffer); }; // FastFourierTransformForRealSequence(int num_order, int fft_size, bool inverse); // virtual ~FastFourierTransformForRealSequence() { } // int GetNumOrder() const { return num_order_; } // int GetFFTSize() const { return fft_size_; } // bool GetInverseFlag() const { return inverse_; } // bool IsValid() const { return is_valid_; } // bool Run(const std::vector<double>& real_part_input, std::vector<double>* real_part_output, std::vector<double>* imaginary_part_output, FastFourierTransformForRealSequence::Buffer* buffer) const; private: // const int num_order_; // const int fft_size_; // const int half_fft_size_; // const bool inverse_; // const FastFourierTransform fast_fourier_transform_; // bool is_valid_; // std::vector<double> sine_table_; // DISALLOW_COPY_AND_ASSIGN(FastFourierTransformForRealSequence); }; } // namespace sptk #endif // SPTK_SRC_FAST_FOURIER_TRANSFORM_FOR_REAL_SEQUENCE_H_ Index: Makefile =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/Makefile,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Makefile 20 Dec 2016 08:23:42 -0000 1.21 --- Makefile 22 Dec 2016 16:09:06 -0000 1.22 *************** *** 52,55 **** --- 52,56 ---- excitation_generation.cc \ fast_fourier_transform.cc \ + fast_fourier_transform_for_real_sequence.cc \ frequency_transform.cc \ generalized_cepstrum_gain_normalization.cc \ --- NEW FILE: fast_fourier_transform_for_real_sequence.cc --- // ----------------------------------------------------------------- // // The Speech Signal Processing Toolkit (SPTK) // // developed by SPTK Working Group // // http://sp-tk.sourceforge.net/ // // ----------------------------------------------------------------- // // // // Copyright (c) 1984-2007 Tokyo Institute of Technology // // Interdisciplinary Graduate School of // // Science and Engineering // // // // 1996-2016 Nagoya Institute of Technology // // Department of Computer Science // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or // // without modification, are permitted provided that the following // // conditions are met: // // // // - Redistributions of source code must retain the above copyright // // notice, this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above // // copyright notice, this list of conditions and the following // // disclaimer in the documentation and/or other materials provided // // with the distribution. // // - Neither the name of the SPTK working group nor the names of its // // contributors may be used to endorse or promote products derived // // from this software without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND // // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, // // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS // // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // // POSSIBILITY OF SUCH DAMAGE. // // ----------------------------------------------------------------- // #include "fast_fourier_transform_for_real_sequence.h" #include <algorithm> // std::fill #include <cmath> // std::sin #include <cstddef> // std::size_t namespace sptk { FastFourierTransformForRealSequence::FastFourierTransformForRealSequence( int num_order, int fft_size, bool inverse) : num_order_(num_order), fft_size_(fft_size), half_fft_size_(fft_size / 2), inverse_(inverse), fast_fourier_transform_(half_fft_size_ - 1, half_fft_size_, false), is_valid_(true) { if (!fast_fourier_transform_.IsValid() || fft_size <= num_order || num_order < 0) { is_valid_ = false; return; } const int table_size(fft_size - fft_size / 4 + 1); const double argument(M_PI / fft_size * 2); sine_table_.resize(table_size); for (int i(0); i < table_size; ++i) { sine_table_[i] = std::sin(argument * i); } sine_table_[fft_size / 2] = 0.0; } bool FastFourierTransformForRealSequence::Run( const std::vector<double>& real_part_input, std::vector<double>* real_part_output, std::vector<double>* imaginary_part_output, FastFourierTransformForRealSequence::Buffer* buffer) const { // check inputs if (!is_valid_ || real_part_input.size() != static_cast<std::size_t>(num_order_ + 1) || NULL == real_part_output || NULL == imaginary_part_output || NULL == buffer) { return false; } // prepare memories if (buffer->real_part_input_.size() != static_cast<std::size_t>(half_fft_size_)) { buffer->real_part_input_.resize(half_fft_size_); } if (buffer->imaginary_part_input_.size() != static_cast<std::size_t>(half_fft_size_)) { buffer->imaginary_part_input_.resize(half_fft_size_); } if (real_part_output->size() < static_cast<std::size_t>(fft_size_)) { real_part_output->resize(fft_size_); } if (imaginary_part_output->size() < static_cast<std::size_t>(fft_size_)) { imaginary_part_output->resize(fft_size_); } // get values and fill zero const int input_size(num_order_ + 1); for (int i(0), j(0); i < input_size; ++j) { buffer->real_part_input_[j] = real_part_input[i++]; if (input_size <= i) break; buffer->imaginary_part_input_[j] = real_part_input[i++]; } std::fill(buffer->real_part_input_.begin() + (input_size + 1) / 2, buffer->real_part_input_.end(), 0.0); std::fill(buffer->imaginary_part_input_.begin() + input_size / 2, buffer->imaginary_part_input_.end(), 0.0); // run fast Fourier transform if (!fast_fourier_transform_.Run(buffer->real_part_input_, buffer->imaginary_part_input_, real_part_output, imaginary_part_output)) { return false; } double* x(&((*real_part_output)[0])); double* y(&((*imaginary_part_output)[0])); double* xp(x); double* yp(y); double* xq(xp + fft_size_); double* yq(yp + fft_size_); *(xp + half_fft_size_) = *xp - *yp; *xp = *xp + *yp; *(yp + half_fft_size_) = 0; *yp = 0; double* sinp(const_cast<double*>(&(sine_table_[0]))); double* cosp(const_cast<double*>(&(sine_table_[0])) + fft_size_ / 4); for (int i(1), j(half_fft_size_ - 2); i < half_fft_size_; ++i, j -= 2) { ++xp; ++yp; ++sinp; ++cosp; const double xt(*xp - *(xp + j)); const double yt(*yp + *(yp + j)); *(--xq) = (*xp + *(xp + j) + *cosp * yt - *sinp * xt) * 0.5; *(--yq) = (-*yp + *(yp + j) + *sinp * yt + *cosp * xt) * 0.5; } xp = x + 1; yp = y + 1; xq = x + fft_size_; yq = y + fft_size_; for (int i(1); i < half_fft_size_; ++i) { *xp++ = *(--xq); *yp++ = -(*(--yq)); } if (inverse_) { xp = x; yp = y; const double inverse_fft_size(1.0 / fft_size_); for (int i(0); i < fft_size_; ++i) { *xp++ *= inverse_fft_size; *yp++ *= inverse_fft_size; } } return true; } } // namespace sptk Index: fft.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/fft.cc,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** fft.cc 12 Oct 2016 12:14:38 -0000 1.9 --- fft.cc 22 Dec 2016 16:09:07 -0000 1.10 *************** *** 160,173 **** } - // check FFT size - sptk::FastFourierTransform fft; - if (!fft.SetNumDimension(fft_size)) { - std::ostringstream error_message; - error_message << "The FFT size must be a power of 2 and greater than 2"; - sptk::PrintErrorMessage("fft", error_message); - return 1; - } - fft.SetInverseFlag(false); - // check order if (is_num_order_specified) { --- 160,163 ---- *************** *** 197,200 **** --- 187,199 ---- std::istream& input_stream(ifs.fail() ? std::cin : ifs); + // prepare for fast Fourier transform + sptk::FastFourierTransform fft(num_order, fft_size, false); + if (!fft.IsValid()) { + std::ostringstream error_message; + error_message << "FFT size must be a power of 2 and greater than 2"; + sptk::PrintErrorMessage("fft", error_message); + return 1; + } + const int length(num_order + 1); std::vector<double> input_x(length); *************** *** 207,211 **** if (!fft.Run(input_x, input_y, &output_x, &output_y)) { std::ostringstream error_message; ! error_message << "Failed to run the fast Fourier transform"; sptk::PrintErrorMessage("fft", error_message); return 1; --- 206,210 ---- if (!fft.Run(input_x, input_y, &output_x, &output_y)) { std::ostringstream error_message; ! error_message << "Failed to run fast Fourier transform"; sptk::PrintErrorMessage("fft", error_message); return 1; |