From: Takenori Y. <tak...@us...> - 2017-04-03 06:05:56
|
Update of /cvsroot/sp-tk/SPTK4/src In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv8703 Added Files: lsp2sp.cc Log Message: add lsp2sp command --- NEW FILE: lsp2sp.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-2017 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 <getopt.h> #include <algorithm> #include <cmath> #include <fstream> #include <functional> #include <iostream> #include <sstream> #include <vector> #include "line_spectral_pairs_to_spectrum.h" #include "sptk_utils.h" namespace { enum InputGainTypes { kLinearGain = 0, kLogGain, kWithoutGain, kNumInputGainTypes }; enum InputFormats { kNormalizedFrequencyInRadians = 0, kNormalizedFrequencyInCycles, kFrequencyInkHz, kFrequencyInHz, kNumInputFormats }; enum OutputFormats { kLogAmplitudeSpectrumInDecibels = 0, kLogAmplitudeSpectrum, kAmplitudeSpectrum, kPowerSpectrum, kNumOutputFormats }; const int kDefaultNumOrder(25); const int kDefaultSpectrumLength(256); const double kDefaultSamplingFrequency(10.0); const InputGainTypes kDefaultInputGainType(kLinearGain); const InputFormats kDefaultInputFormat(kNormalizedFrequencyInRadians); const OutputFormats kDefaultOutputFormat(kLogAmplitudeSpectrumInDecibels); void PrintUsage(std::ostream* stream) { // clang-format off *stream << std::endl; *stream << " lsp2sp - transform line spectral pairs to spectrum" << std::endl; *stream << std::endl; *stream << " usage:" << std::endl; *stream << " lsp2sp [ options ] [ infile ] > stdout" << std::endl; *stream << " options:" << std::endl; *stream << " -m m : order of line spectral pairs [" << kDefaultNumOrder << "]" << std::endl; // NOLINT *stream << " -l l : spectrum legnth [" << kDefaultSpectrumLength << "]" << std::endl; // NOLINT *stream << " -s s : sampling frequency [" << kDefaultSamplingFrequency << "]" << std::endl; // NOLINT *stream << " -k k : input gain type [" << kDefaultInputGainType << "]" << std::endl; // NOLINT *stream << " 0 (linear gain)" << std::endl; *stream << " 1 (log gain)" << std::endl; *stream << " 2 (without gain)" << std::endl; *stream << " -q q : input format [" << kDefaultInputFormat << "]" << std::endl; // NOLINT *stream << " 0 (normalized frequency [0...pi])" << std::endl; *stream << " 1 (normalized frequency [0...1/2])" << std::endl; *stream << " 2 (frequency [kHz])" << std::endl; *stream << " 3 (frequency [Hz])" << std::endl; *stream << " -o o : output format [" << kDefaultOutputFormat << "]" << std::endl; // NOLINT *stream << " 0 (20*log|H(z)|)" << std::endl; *stream << " 1 (ln|H(z)|)" << std::endl; *stream << " 2 (|H(z)|)" << std::endl; *stream << " 3 (|H(z)|^2)" << std::endl; *stream << " -h : print this message" << std::endl; *stream << " infile:" << std::endl; *stream << " line spectral pairs (double) [stdin]" << std::endl; // NOLINT *stream << " stdout:" << std::endl; *stream << " spectrum (double)" << std::endl; *stream << " notice:" << std::endl; *stream << " if k is 2, input length in a frame is assumed to be m instead of m+1" << std::endl; // NOLINT *stream << std::endl; *stream << " SPTK: version " << sptk::kVersion << std::endl; *stream << std::endl; // clang-format on } } // namespace int main(int argc, char* argv[]) { int num_order(kDefaultNumOrder); int spectrum_length(kDefaultSpectrumLength); double sampling_frequency(kDefaultSamplingFrequency); InputGainTypes input_gain_type(kDefaultInputGainType); InputFormats input_format(kDefaultInputFormat); OutputFormats output_format(kDefaultOutputFormat); for (;;) { const int option_char(getopt_long(argc, argv, "m:l:s:k:q:o:h", NULL, NULL)); if (-1 == option_char) break; switch (option_char) { case 'm': { if (!sptk::ConvertStringToInteger(optarg, &num_order) || num_order < 0) { std::ostringstream error_message; error_message << "The argument for the -m option must be a " << "non-negative integer"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } break; } case 'l': { if (!sptk::ConvertStringToInteger(optarg, &spectrum_length) || spectrum_length <= 0) { std::ostringstream error_message; error_message << "The argument for the -l option must be a positive integer"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } break; } case 's': { if (!sptk::ConvertStringToDouble(optarg, &sampling_frequency) || sampling_frequency <= 0.0) { std::ostringstream error_message; error_message << "The argument for the -s option must be a positive number"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } break; } case 'k': { const int min(0); const int max(static_cast<int>(kNumInputGainTypes) - 1); int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || !sptk::IsInRange(tmp, min, max)) { std::ostringstream error_message; error_message << "The argument for the -k option must be an integer " << "in the range of " << min << " to " << max; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } input_gain_type = static_cast<InputGainTypes>(tmp); break; } case 'q': { const int min(0); const int max(static_cast<int>(kNumInputFormats) - 1); int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || !sptk::IsInRange(tmp, min, max)) { std::ostringstream error_message; error_message << "The argument for the -q option must be an integer " << "in the range of " << min << " to " << max; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } input_format = static_cast<InputFormats>(tmp); break; } case 'o': { const int min(0); const int max(static_cast<int>(kNumOutputFormats) - 1); int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || !sptk::IsInRange(tmp, min, max)) { std::ostringstream error_message; error_message << "The argument for the -o option must be an integer " << "in the range of " << min << " to " << max; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } output_format = static_cast<OutputFormats>(tmp); break; } case 'h': { PrintUsage(&std::cout); return 0; } default: { PrintUsage(&std::cerr); return 1; } } } // 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("lsp2sp", error_message); return 1; } std::istream& input_stream(ifs.fail() ? std::cin : ifs); // prepare to transform sptk::LineSpectralPairsToSpectrum line_spectral_pairs_to_spectrum( num_order, spectrum_length); if (!line_spectral_pairs_to_spectrum.IsValid()) { std::ostringstream error_message; error_message << "Failed to set condition for transformation"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } const int input_length(num_order + 1); const int output_length(spectrum_length + 1); const int read_size(kWithoutGain == input_gain_type ? num_order : input_length); const int read_point(kWithoutGain == input_gain_type ? 1 : 0); std::vector<double> line_spectral_pairs(input_length); std::vector<double> spectrum(output_length); while (sptk::ReadStream(false, 0, read_point, read_size, &line_spectral_pairs, &input_stream)) { switch (input_gain_type) { case kLinearGain: { // nothing to do break; } case kLogGain: { line_spectral_pairs[0] = std::exp(line_spectral_pairs[0]); break; } case kWithoutGain: { line_spectral_pairs[0] = 1.0; break; } default: { break; } } switch (input_format) { case kNormalizedFrequencyInRadians: { // nothing to do break; } case kNormalizedFrequencyInCycles: { std::transform(line_spectral_pairs.begin() + 1, line_spectral_pairs.end(), line_spectral_pairs.begin() + 1, std::bind1st(std::multiplies<double>(), sptk::kTwoPi)); break; } case kFrequencyInkHz: { std::transform(line_spectral_pairs.begin() + 1, line_spectral_pairs.end(), line_spectral_pairs.begin() + 1, std::bind1st(std::multiplies<double>(), sptk::kTwoPi / sampling_frequency)); break; } case kFrequencyInHz: { std::transform(line_spectral_pairs.begin() + 1, line_spectral_pairs.end(), line_spectral_pairs.begin() + 1, std::bind1st(std::multiplies<double>(), sptk::kTwoPi * 0.001 / sampling_frequency)); break; } default: { break; } } if (!line_spectral_pairs_to_spectrum.Run(line_spectral_pairs, &spectrum)) { std::ostringstream error_message; error_message << "Failed to transform line spectral pairs to spectrum"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } switch (output_format) { case kLogAmplitudeSpectrumInDecibels: { std::transform(spectrum.begin(), spectrum.end(), spectrum.begin(), std::bind1st(std::multiplies<double>(), sptk::kNp)); break; } case kLogAmplitudeSpectrum: { // nothing to do break; } case kAmplitudeSpectrum: { std::transform(spectrum.begin(), spectrum.end(), spectrum.begin(), std::ptr_fun<double, double>(std::exp)); break; } case kPowerSpectrum: { std::transform(spectrum.begin(), spectrum.end(), spectrum.begin(), std::ptr_fun<double, double>( [](double x) { return std::exp(2.0 * x); })); break; } default: { break; } } if (!sptk::WriteStream(0, output_length, spectrum, &std::cout)) { std::ostringstream error_message; error_message << "Failed to write spectrum"; sptk::PrintErrorMessage("lsp2sp", error_message); return 1; } } return 0; } |