From: Takenori Y. <tak...@us...> - 2015-12-28 12:51:53
|
Update of /cvsroot/sp-tk/SPTK4/src In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv13155 Modified Files: fast_fourier_transform.cc fast_fourier_transform.h fft.cc frequency_transform.h sptk_utils.cc Added Files: ifft.cc Log Message: add ifft command Index: fast_fourier_transform.h =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/fast_fourier_transform.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** fast_fourier_transform.h 17 Nov 2015 10:15:37 -0000 1.3 --- fast_fourier_transform.h 28 Dec 2015 12:51:50 -0000 1.4 *************** *** 53,57 **** public: // ! FastFourierTransform() : num_dimension_(0) {} // --- 53,57 ---- public: // ! FastFourierTransform() : num_dimension_(0), inverse_(false) {} // *************** *** 62,65 **** --- 62,70 ---- // + void SetInverseFlag(bool inverse) { + inverse_ = inverse; + } + + // int GetNumDimension() const { return num_dimension_; *************** *** 67,70 **** --- 72,80 ---- // + bool GetInverseFlag() const { + return inverse_; + } + + // bool Run(const std::vector<double>& real_part_input, const std::vector<double>& imaginary_part_input, *************** *** 83,86 **** --- 93,99 ---- // + bool inverse_; + + // std::vector<double> sine_table_; }; Index: fast_fourier_transform.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/fast_fourier_transform.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** fast_fourier_transform.cc 25 Nov 2015 11:35:26 -0000 1.4 --- fast_fourier_transform.cc 28 Dec 2015 12:51:50 -0000 1.5 *************** *** 106,115 **** 0.0); ! double* x(&((*real_part_output)[0])); ! double* y(&((*imaginary_part_output)[0])); // set values const int half_num_dimension(num_dimension_ / 2); const int dec_num_dimension(num_dimension_ - 1); int lix(num_dimension_); --- 106,123 ---- 0.0); ! double* x; ! double* y; ! if (inverse_) { ! x = &((*imaginary_part_output)[0]); ! y = &((*real_part_output)[0]); ! } else { ! x = &((*real_part_output)[0]); ! y = &((*imaginary_part_output)[0]); ! } // set values const int half_num_dimension(num_dimension_ / 2); const int dec_num_dimension(num_dimension_ - 1); + const double inverse_num_dimension(1.0 / num_dimension_); int lix(num_dimension_); *************** *** 153,163 **** } - // bit reversal xp = x; yp = y; - int j(0); ! for (int lmx(0); lmx < dec_num_dimension; ++lmx) { ! int lmxj(lmx - j); if (lmxj < 0) { const double t1(*(xp)); --- 161,170 ---- } xp = x; yp = y; ! // bit reversal ! for (int lmx(0), j(0); lmx < dec_num_dimension; ++lmx) { ! const int lmxj(lmx - j); if (lmxj < 0) { const double t1(*(xp)); *************** *** 179,182 **** --- 186,199 ---- } + // normalize + if (inverse_) { + xp = x; + yp = y; + for (int i(0); i < num_dimension_; ++i) { + *(xp + i) *= inverse_num_dimension; + *(yp + i) *= inverse_num_dimension; + } + } + return true; } Index: sptk_utils.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/sptk_utils.cc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** sptk_utils.cc 14 Dec 2015 11:56:42 -0000 1.4 --- sptk_utils.cc 28 Dec 2015 12:51:50 -0000 1.5 *************** *** 55,59 **** std::vector<double>* sequence_to_read, std::istream* input_stream) { ! if (1 > read_size || NULL == sequence_to_read || NULL == input_stream) --- 55,59 ---- std::vector<double>* sequence_to_read, std::istream* input_stream) { ! if (0 >= read_size || NULL == sequence_to_read || NULL == input_stream) *************** *** 79,83 **** const int num_zeros(std::ceil( static_cast<double>(num_bytes - gcount) / type_byte)); ! if (num_zeros < 0) return false; // Something wrong! --- 79,83 ---- const int num_zeros(std::ceil( static_cast<double>(num_bytes - gcount) / type_byte)); ! if (0 > num_zeros) return false; // Something wrong! *************** *** 93,97 **** const std::vector<double>& sequence_to_write, std::ostream* output_stream) { ! if (1 > write_size || NULL == output_stream) return false; --- 93,97 ---- const std::vector<double>& sequence_to_write, std::ostream* output_stream) { ! if (0 >= write_size || NULL == output_stream) return false; Index: fft.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/fft.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** fft.cc 25 Nov 2015 11:35:26 -0000 1.3 --- fft.cc 28 Dec 2015 12:51:50 -0000 1.4 *************** *** 45,49 **** #include <unistd.h> #include <cmath> - #include <cstdlib> #include <fstream> #include <iostream> --- 45,48 ---- *************** *** 65,69 **** }; ! const int kDefaultFFTSize(256); void PrintUsage() { --- 64,68 ---- }; ! const int kDefaultFftSize(256); void PrintUsage() { *************** *** 74,80 **** std::cout << " fft [ options ] [ infile ] > stdout" << std::endl; std::cout << " options:" << std::endl; ! std::cout << " -l l : FFT size [" << kDefaultFFTSize << "]" << std::endl; // NOLINT std::cout << " -m m : order of sequence [l-1]" << std::endl; // NOLINT ! std::cout << " -o : output format [0]" << std::endl; // NOLINT std::cout << " 0 (real and imaginary parts)" << std::endl; std::cout << " 1 (real part)" << std::endl; --- 73,79 ---- std::cout << " fft [ options ] [ infile ] > stdout" << std::endl; std::cout << " options:" << std::endl; ! std::cout << " -l l : FFT size [" << kDefaultFftSize << "]" << std::endl; // NOLINT std::cout << " -m m : order of sequence [l-1]" << std::endl; // NOLINT ! std::cout << " -o : output format [0]" << std::endl; // NOLINT std::cout << " 0 (real and imaginary parts)" << std::endl; std::cout << " 1 (real part)" << std::endl; *************** *** 95,99 **** int main(int argc, char* argv[]) { ! int fft_size(kDefaultFFTSize); int order(0); bool order_is_specified(false); --- 94,98 ---- int main(int argc, char* argv[]) { ! int fft_size(kDefaultFftSize); int order(0); bool order_is_specified(false); *************** *** 165,168 **** --- 164,168 ---- return 1; } + fft.SetInverseFlag(false); // check order Index: frequency_transform.h =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/frequency_transform.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** frequency_transform.h 25 Nov 2015 11:35:26 -0000 1.4 --- frequency_transform.h 28 Dec 2015 12:51:50 -0000 1.5 *************** *** 74,80 **** // num_output_order must be not negative bool SetNumOutputOrder(int num_output_order) { ! if (num_output_order < 0) { ! return false; ! } num_output_order_ = num_output_order; return true; --- 74,78 ---- // num_output_order must be not negative bool SetNumOutputOrder(int num_output_order) { ! if (0 > num_output_order) return false; num_output_order_ = num_output_order; return true; --- NEW FILE: ifft.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-2015 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 <unistd.h> #include <fstream> #include <iostream> #include <sstream> #include <vector> #include "fast_fourier_transform.h" #include "sptk_utils.h" namespace { enum OutputFormats { kOutputRealAndImaginaryParts = 0, kOutputRealPart, kOutputImaginaryPart, kNumOutputFormats }; const int kDefaultFftSize(256); void PrintUsage() { std::cout << std::endl; std::cout << " ifft - inverse FFT for complex sequence" << std::endl; std::cout << std::endl; std::cout << " usage:" << std::endl; std::cout << " ifft [ options ] [ infile ] > stdout" << std::endl; std::cout << " options:" << std::endl; std::cout << " -l l : FFT size [" << kDefaultFftSize << "]" << std::endl; // NOLINT std::cout << " -o : output format [0]" << std::endl; // NOLINT std::cout << " 0 (real and imaginary parts)" << std::endl; std::cout << " 1 (real part)" << std::endl; std::cout << " 2 (imaginary part)" << std::endl; std::cout << " -h : print this message" << std::endl; std::cout << " infile:" << std::endl; std::cout << " data sequence (double) [stdin]" << std::endl; // NOLINT std::cout << " stdout:" << std::endl; std::cout << " inverse FFT sequence (double)" << std::endl; std::cout << std::endl; std::cout << " SPTK: version " << sptk::kVersion << std::endl; std::cout << std::endl; } } // namespace int main(int argc, char* argv[]) { int fft_size(kDefaultFftSize); OutputFormats output_format(kOutputRealAndImaginaryParts); while (true) { const char option_char(getopt(argc, argv, "l:o:h")); if (-1 == option_char) break; switch (option_char) { case 'l': { if (!sptk::ConvertStringToInteger(optarg, &fft_size)) { std::ostringstream error_message; error_message << "The argument for the -l option must be an integer"; sptk::PrintErrorMessage("ifft", error_message); return 1; } break; } case 'o': { int output_format_integer; if (!sptk::ConvertStringToInteger(optarg, &output_format_integer)) { std::ostringstream error_message; error_message << "The argument for the -o option must be an integer"; sptk::PrintErrorMessage("ifft", error_message); return 1; } const int min(0); const int max(static_cast<int>(kNumOutputFormats) - 1); if (!sptk::IsInRange(output_format_integer, min, max)) { std::ostringstream error_message; error_message << "The argument for the -o option must be in range" << " (" << min << " .. " << max << ")"; sptk::PrintErrorMessage("ifft", error_message); return 1; } output_format = static_cast<OutputFormats>(output_format_integer); break; } case 'h': { PrintUsage(); return 0; } default: { PrintUsage(); return 1; } } } // check FFT size sptk::FastFourierTransform fft; if (!fft.SetNumDimension(fft_size)) { std::ostringstream error_message; error_message << "The FFT size must be an 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); // open stream std::ifstream ifs; ifs.open(input_file, std::ios::in | std::ios::binary); if (ifs.fail() && NULL != input_file) { std::ostringstream error_message; error_message << "Cannot open file " << input_file; sptk::PrintErrorMessage("ifft", error_message); return 1; } std::istream& input_stream(ifs.fail() ? std::cin : ifs); std::vector<double> input_x(fft_size); std::vector<double> input_y(fft_size); std::vector<double> output_x(fft_size); std::vector<double> output_y(fft_size); while (!input_stream.eof()) { // get input if (!sptk::ReadStream(false, fft_size, &input_x, &input_stream)) break; if (!sptk::ReadStream(false, fft_size, &input_y, &input_stream)) break; if (!fft.Run(input_x, input_y, &output_x, &output_y)) { std::ostringstream error_message; error_message << "Failed to run the inverse fast Fourier transform"; sptk::PrintErrorMessage("ifft", error_message); return 1; } if (kOutputImaginaryPart != output_format && !sptk::WriteStream(fft_size, output_x, &std::cout)) { std::ostringstream error_message; error_message << "Failed to write output sequence"; sptk::PrintErrorMessage("ifft", error_message); return 1; } if ((kOutputRealAndImaginaryParts == output_format || kOutputImaginaryPart == output_format) && !sptk::WriteStream(fft_size, output_y, &std::cout)) { std::ostringstream error_message; error_message << "Failed to write output sequence"; sptk::PrintErrorMessage("ifft", error_message); return 1; } } return 0; } |