From: Keiichiro O. <ur...@us...> - 2016-12-16 09:36:34
|
Update of /cvsroot/sp-tk/SPTK4/src In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv22172 Modified Files: generalized_cepstrum_transform.cc generalized_cepstrum_transform.h Added Files: mgc2mgc.cc Log Message: add/optimize mgc2mgc --- NEW FILE: mgc2mgc.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 <unistd.h> #include <fstream> #include <iostream> #include <sstream> #include <vector> #include "generalized_cepstrum_transform.h" #include "sptk_utils.h" namespace { const int kDefaultInputNumOrder(25); const double kDefaultInputAlpha(0.0); const double kDefaultInputGamma(0.0); const bool kDefaultInputNormalizationFlag(false); const bool kDefaultInputMultiplicationFlag(false); const int kDefaultOutputNumOrder(25); const double kDefaultOutputAlpha(0.0); const double kDefaultOutputGamma(1.0); const bool kDefaultOutputNormalizationFlag(false); const bool kDefaultOutputMultiplicationFlag(false); void PrintUsage(std::ostream* stream) { // clang-format off *stream << std::endl; *stream << " mgc2mgc - frequency and generalized cepstral transformation" << std::endl; // NOLINT *stream << std::endl; *stream << " usage:" << std::endl; *stream << " mgc2mgc [ options ] [ infile ] > stdout" << std::endl; *stream << " options:" << std::endl; *stream << " -m m : order of mel-generalized cepstrum (input) [" << kDefaultInputNumOrder << "]" << std::endl; // NOLINT *stream << " -a a : alpha of mel-generalized cepstrum (input) [" << kDefaultInputAlpha << "]" << std::endl; // NOLINT *stream << " -g g : gamma of mel-generalized cepstrum (input) [" << kDefaultInputGamma << "]" << std::endl; // NOLINT *stream << " -c c : gamma of mel-generalized cepstrum = -1 / (int) c (input)" << std::endl; // NOLINT *stream << " -n : regard input as normalized mel-generalized cepstrum [" << sptk::ConvertBooleanToString(kDefaultInputNormalizationFlag) << "]" << std::endl; // NOLINT *stream << " -u : regard input as multiplied by gamma [" << sptk::ConvertBooleanToString(kDefaultInputMultiplicationFlag) << "]" << std::endl; // NOLINT *stream << " -M M : order of mel-generalized cepstrum (input) [" << kDefaultOutputNumOrder << "]" << std::endl; // NOLINT *stream << " -A A : alpha of mel-generalized cepstrum (input) [" << kDefaultOutputAlpha << "]" << std::endl; // NOLINT *stream << " -G G : gamma of mel-generalized cepstrum (input) [" << kDefaultOutputGamma << "]" << std::endl; // NOLINT *stream << " -C C : gamma of mel-generalized cepstrum = -1 / (int) C (input)" << std::endl; // NOLINT *stream << " -N : regard input as normalized mel-generalized cepstrum [" << sptk::ConvertBooleanToString(kDefaultOutputNormalizationFlag) << "]" << std::endl; // NOLINT *stream << " -U : regard input as multiplied by gamma [" << sptk::ConvertBooleanToString(kDefaultOutputMultiplicationFlag) << "]" << std::endl; // NOLINT *stream << " -h : print this message" << std::endl; *stream << " infile:" << std::endl; *stream << " mel-generalized cepstrum (double) [stdin]" << std::endl; // NOLINT *stream << " stdout:" << std::endl; *stream << " transformed mel-generalized cepstrum (double)" << std::endl; // NOLINT *stream << " notice:" << std::endl; *stream << " value of c must be c >= 1 (double)" << std::endl; *stream << " if -u is used without -n, input is regarded as 1+g/c[0],g*c[1],...,g*c[m]" << std::endl; // NOLINT *stream << " if -U is used without -N, ouputput is regarded as 1+g/c[0],g*c[1],...,g*c[m]" << 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 input_num_order(kDefaultInputNumOrder); double input_alpha(kDefaultInputAlpha); double input_gamma(kDefaultInputGamma); bool input_normalization_flag(kDefaultInputNormalizationFlag); bool input_multiplication_flag(kDefaultInputMultiplicationFlag); int output_num_order(kDefaultOutputNumOrder); double output_alpha(kDefaultOutputAlpha); double output_gamma(kDefaultOutputGamma); bool output_normalization_flag(kDefaultOutputNormalizationFlag); bool output_multiplication_flag(kDefaultOutputMultiplicationFlag); for (;;) { const char option_char(getopt(argc, argv, "m:a:g:c:nuM:A:G:C:NUh")); if (-1 == option_char) break; switch (option_char) { case 'm': { if (!sptk::ConvertStringToInteger(optarg, &input_num_order) || input_num_order < 0) { std::ostringstream error_message; error_message << "The argument for the -m option must be a " << "non-negative integer"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'a': { if (!sptk::ConvertStringToDouble(optarg, &input_alpha)) { std::ostringstream error_message; error_message << "The argument for the -a option must be numeric"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'g': { if (!sptk::ConvertStringToDouble(optarg, &input_gamma)) { std::ostringstream error_message; error_message << "The argument for the -g option must be numeric"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'c': { int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || tmp < 1) { std::ostringstream error_message; error_message << "The argument for the -c option must be a " << "positive integer"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } input_gamma = -1.0 / tmp; break; } case 'n': { input_normalization_flag = true; break; } case 'u': { input_multiplication_flag = true; break; } case 'M': { if (!sptk::ConvertStringToInteger(optarg, &output_num_order) || output_num_order < 0) { std::ostringstream error_message; error_message << "The argument for the -M option must be a " << "non-negative integer"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'A': { if (!sptk::ConvertStringToDouble(optarg, &output_alpha)) { std::ostringstream error_message; error_message << "The argument for the -A option must be numeric"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'G': { if (!sptk::ConvertStringToDouble(optarg, &output_gamma)) { std::ostringstream error_message; error_message << "The argument for the -G option must be numeric"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } break; } case 'C': { int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || tmp < 1) { std::ostringstream error_message; error_message << "The argument for the -C option must be a " << "positive integer"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } output_gamma = -1.0 / tmp; break; } case 'N': { output_normalization_flag = true; break; } case 'U': { output_multiplication_flag = true; 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("mgc2mgc", error_message); return 1; } std::istream& input_stream(ifs.fail() ? std::cin : ifs); // prepare for gain normalization sptk::GeneralizedCepstrumTransform generalized_cepstrum_transform( input_num_order, input_alpha, input_gamma, input_normalization_flag, input_multiplication_flag, output_num_order, output_alpha, output_gamma, output_normalization_flag, output_multiplication_flag); sptk::GeneralizedCepstrumTransform::Buffer buffer; if (!generalized_cepstrum_transform.IsValid()) { std::ostringstream error_message; error_message << "Failed to set the condition."; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } const int input_length(input_num_order + 1); const int output_length(output_num_order + 1); std::vector<double> generalized_cepstrum(input_length); std::vector<double> transformed_generalized_cepstrum(output_length); while (sptk::ReadStream(false, input_length, &generalized_cepstrum, &input_stream)) { // input modification: 1*g/c[0] -> c[0] if (!input_normalization_flag && input_multiplication_flag) (*generalized_cepstrum.begin()) = (*(generalized_cepstrum.begin()) - 1.0) / input_gamma; // transform if (!generalized_cepstrum_transform.Run( generalized_cepstrum, &transformed_generalized_cepstrum, &buffer)) { std::ostringstream error_message; error_message << "Failed to run the transform"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } // output modification: c[0] -> 1+g*c[0] if (!output_normalization_flag && output_multiplication_flag) (*transformed_generalized_cepstrum.begin()) = *(transformed_generalized_cepstrum.begin()) * output_gamma + 1.0; // write results if (!sptk::WriteStream(output_length, transformed_generalized_cepstrum, &std::cout)) { std::ostringstream error_message; error_message << "Failed to write an output sequence"; sptk::PrintErrorMessage("mgc2mgc", error_message); return 1; } } return 0; } Index: generalized_cepstrum_transform.cc =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/generalized_cepstrum_transform.cc,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** generalized_cepstrum_transform.cc 24 Oct 2016 08:20:30 -0000 1.3 --- generalized_cepstrum_transform.cc 16 Dec 2016 09:36:31 -0000 1.4 *************** *** 53,56 **** --- 53,244 ---- #include "generalized_cepstrum_inverse_gain_normalization.h" + namespace { + + class GainNormalizationModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + GainNormalizationModule(int num_order, double gamma) + : generalized_cepstrum_gain_normalization_(num_order, gamma) { + } + virtual bool IsValid() const { + return generalized_cepstrum_gain_normalization_.IsValid(); + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (!generalized_cepstrum_gain_normalization_.Run(input, output)) { + return false; + } + output->resize(generalized_cepstrum_gain_normalization_.GetNumOrder() + 1); + return true; + } + + private: + const sptk::GeneralizedCepstrumGainNormalization + generalized_cepstrum_gain_normalization_; + DISALLOW_COPY_AND_ASSIGN(GainNormalizationModule); + }; + + class InverseGainNormalizationModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + InverseGainNormalizationModule(int num_order, double gamma) + : generalized_cepstrum_inverse_gain_normalization_(num_order, gamma) { + } + virtual bool IsValid() const { + return generalized_cepstrum_inverse_gain_normalization_.IsValid(); + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (!generalized_cepstrum_inverse_gain_normalization_.Run(input, output)) { + return false; + } + output->resize( + generalized_cepstrum_inverse_gain_normalization_.GetNumOrder() + 1); + return true; + } + + private: + const sptk::GeneralizedCepstrumInverseGainNormalization + generalized_cepstrum_inverse_gain_normalization_; + DISALLOW_COPY_AND_ASSIGN(InverseGainNormalizationModule); + }; + + class FrequencyTransformModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + FrequencyTransformModule(int num_input_order, int num_output_order, + double alpha_transform) + : frequency_transform_(num_input_order, num_output_order, + alpha_transform) { + } + virtual bool IsValid() const { + return frequency_transform_.IsValid(); + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (!frequency_transform_.Run(input, output, frequency_transform_buffer)) { + return false; + } + output->resize(frequency_transform_.GetNumOutputOrder() + 1); + return true; + } + + private: + const sptk::FrequencyTransform frequency_transform_; + DISALLOW_COPY_AND_ASSIGN(FrequencyTransformModule); + }; + + class GeneralizedCepstrumTransformModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + GeneralizedCepstrumTransformModule(int num_input_order, int num_output_order, + double input_gamma, double output_gamma) + : num_input_order_(num_input_order), + num_output_order_(num_output_order), + input_gamma_(input_gamma), + output_gamma_(output_gamma) { + } + virtual bool IsValid() const { + return true; + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (output->size() != static_cast<std::size_t>(num_output_order_ + 1)) { + output->resize(num_output_order_ + 1); + } + const double *c1(&(input)[0]); + double *c2(&((*output)[0])); + + c2[0] = c1[0]; + for (int i(1); i <= num_output_order_; ++i) { + double ss1(0.0), ss2(0.0); + const int min(num_input_order_ < i ? num_input_order_ : i - 1); + for (int k(1); k <= min; ++k) { + const int mk(i - k); + const double cc(c1[k] * c2[mk]); + ss2 += k * cc; + ss1 += mk * cc; + } + + if (i <= num_input_order_) + c2[i] = c1[i] + (output_gamma_ * ss2 - input_gamma_ * ss1) / i; + else + c2[i] = (output_gamma_ * ss2 - input_gamma_ * ss1) / i; + } + return true; + } + + private: + const int num_input_order_; + const int num_output_order_; + const double input_gamma_; + const double output_gamma_; + DISALLOW_COPY_AND_ASSIGN(GeneralizedCepstrumTransformModule); + }; + + class GammaDivisionModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + GammaDivisionModule(int num_order, double gamma) + : num_order_(num_order), gamma_(gamma) { + } + virtual bool IsValid() const { + return true; + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (output->size() != static_cast<std::size_t>(num_order_ + 1)) { + output->resize(num_order_ + 1); + } + // c[0] is not changed + *(output->begin()) = *(input.begin()); + // c[1-m] /= g + std::transform(++(input.begin()), input.end(), ++(output->begin()), + std::bind1st(std::multiplies<double>(), 1.0 / gamma_)); + return true; + } + + private: + const int num_order_; + const double gamma_; + DISALLOW_COPY_AND_ASSIGN(GammaDivisionModule); + }; + + class GammaMultiplicationModule + : public sptk::GeneralizedCepstrumTransform::ModuleInterface { + public: + GammaMultiplicationModule(int num_order, double gamma) + : num_order_(num_order), gamma_(gamma) { + } + virtual bool IsValid() const { + return true; + } + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + sptk::FrequencyTransform::Buffer *frequency_transform_buffer) const { + if (output->size() != static_cast<std::size_t>(num_order_ + 1)) { + output->resize(num_order_ + 1); + } + // copy c[0] + *(output->begin()) = *(input.begin()); + // c[1-m] *= g + std::transform(++(input.begin()), input.end(), ++(output->begin()), + std::bind1st(std::multiplies<double>(), gamma_)); + return true; + } + + private: + const int num_order_; + const double gamma_; + DISALLOW_COPY_AND_ASSIGN(GammaMultiplicationModule); + }; + + } // namespace + namespace sptk { *************** *** 78,282 **** return; } if (input_alpha_ != output_alpha_) { alpha_transform_ = (output_alpha_ - input_alpha_) / (1.0 - input_alpha_ * output_alpha_); } - } ! bool GeneralizedCepstrumTransform::Run( ! const std::vector<double>& input, std::vector<double>* output, ! GeneralizedCepstrumTransform::Buffer* buffer) const { ! if (!is_valid_ || ! static_cast<std::size_t>(num_input_order_ + 1) != input.size() || ! NULL == output || NULL == buffer) { ! return false; ! } ! if (output->size() < static_cast<std::size_t>(num_output_order_ + 1)) { ! output->resize(num_output_order_ + 1); ! } ! // mgc2mgc input ! // norm=false multi=false freqt=false ! // -> -> -> gnorm -> gc2gc ! // norm=false multi=true freqt=false ! // -> c[1-m]/g -> -> gnorm -> gc2gc ! // norm=true multi=false freqt=false ! // -> gc2gc ! // norm=true multi=true freqt=false ! // ignorm -> c[1-m]/g -> -> gnorm -> gc2gc ! // norm=false multi=false freqt=true ! // -> -> freqt -> gnorm -> gc2gc ! // norm=false multi=true freqt=true ! // -> c[1-m]/g -> freqt -> gnorm -> gc2gc ! // norm=true multi=false freqt=true ! // ignorm -> -> freqt -> gnorm -> gc2gc ! // norm=true multi=true freqt=true ! // ignorm -> c[1-m]/g -> freqt -> gnorm -> gc2gc ! // do nothing ! if (num_input_order_ == num_output_order_ && input_alpha_ == output_alpha_ && ! input_gamma_ == output_gamma_ && ! is_normalized_input_ == is_normalized_output_ && ! is_multiplied_input_ == is_multiplied_output_) { ! std::copy(input.begin(), input.end(), output->begin()); ! return true; ! } ! // inverse gain normalization ! // input: input ! // output: inverse_gain_normalized_input ! const std::vector<double>* inverse_gain_normalized_input; ! if (is_normalized_input_ && ! (is_multiplied_input_ || 0.0 != alpha_transform_)) { ! GeneralizedCepstrumInverseGainNormalization ! generalized_cepstrum_inverse_gain_normalization(num_input_order_, ! input_gamma_); ! if (!generalized_cepstrum_inverse_gain_normalization.IsValid()) { ! return false; ! } ! if (!generalized_cepstrum_inverse_gain_normalization.Run( ! input, &buffer->inverse_gain_normalized_input_)) { ! return false; ! } ! inverse_gain_normalized_input = &buffer->inverse_gain_normalized_input_; ! } else { ! inverse_gain_normalized_input = &input; ! } ! // gamma division ! // input: inverse_gain_normalized_input ! // output: gamma_divided_input ! const std::vector<double>* gamma_divided_input; ! if (is_multiplied_input_) { ! if (buffer->gamma_divided_input_.size() < ! static_cast<std::size_t>(num_input_order_ + 1)) { ! buffer->gamma_divided_input_.resize(num_input_order_ + 1); ! } ! std::transform(inverse_gain_normalized_input->begin(), ! inverse_gain_normalized_input->end(), ! buffer->gamma_divided_input_.begin(), ! std::bind1st(std::multiplies<double>(), 1.0 / input_gamma_)); ! gamma_divided_input = &buffer->gamma_divided_input_; ! } else { ! gamma_divided_input = inverse_gain_normalized_input; ! } ! // frequency transform ! // input: gamma_divided_input ! // output: frequency_transformed_input ! const std::vector<double>* frequency_transformed_input; ! if (0.0 != alpha_transform_) { ! FrequencyTransform frequency_transform(num_input_order_, num_input_order_, ! alpha_transform_); ! if (!frequency_transform.IsValid()) { ! return false; ! } ! if (!frequency_transform.Run(*gamma_divided_input, ! &buffer->frequency_transformed_input_, ! &buffer->frequency_transform_buffer_)) { ! return false; ! } ! frequency_transformed_input = &buffer->frequency_transformed_input_; ! } else { ! frequency_transformed_input = gamma_divided_input; ! } ! // gain normalization ! // input: frequency_transformed_input ! // output: gain_normalized_input ! const std::vector<double>* gain_normalized_input; ! if (!is_normalized_input_ || is_multiplied_input_ || ! 0.0 != alpha_transform_) { ! GeneralizedCepstrumGainNormalization ! generalized_cepstrum_gain_normalization(num_input_order_, input_gamma_); ! if (!generalized_cepstrum_gain_normalization.IsValid()) { ! return false; ! } ! if (!generalized_cepstrum_gain_normalization.Run( ! *frequency_transformed_input, &buffer->gain_normalized_input_)) { ! return false; } - gain_normalized_input = &buffer->gain_normalized_input_; } else { ! gain_normalized_input = frequency_transformed_input; } ! // generalized cepstrum transform ! // input: gain_normalized_input ! // output: generalized_cepstrum_transformed_output ! const std::vector<double>* generalized_cepstrum_transformed_output; ! if (input_gamma_ != output_gamma_ || num_input_order_ != num_output_order_) { ! if (buffer->generalized_cepstrum_transformed_output_.size() < ! static_cast<std::size_t>(num_output_order_ + 1)) { ! buffer->generalized_cepstrum_transformed_output_.resize( ! num_output_order_ + 1); } ! const double* c1(&(*gain_normalized_input)[0]); ! double* c2(&(buffer->generalized_cepstrum_transformed_output_[0])); ! c2[0] = c1[0]; ! for (int i(1); i <= num_output_order_; ++i) { ! double ss1(0.0), ss2(0.0); ! const int min(num_output_order_ < i ? num_output_order_ : i - 1); ! for (int k(1); k <= min; ++k) { ! int mk(i - k); ! double cc(c1[k] * c2[mk]); ! ss2 += k * cc; ! ss1 += mk * cc; ! } ! if (i <= num_input_order_) ! c2[i] = c1[i] + (output_gamma_ * ss2 - input_gamma_ * ss1) / i; ! else ! c2[i] = (output_gamma_ * ss2 - input_gamma_ * ss1) / i; } ! generalized_cepstrum_transformed_output = ! &buffer->generalized_cepstrum_transformed_output_; ! } else { ! generalized_cepstrum_transformed_output = gain_normalized_input; } ! // mgc2mgc output ! // norm=false multi=false ! // ignorm -> -> ! // norm=false multi=true ! // ignorm -> -> c[1-m]*g ! // norm=true multi=false ! // -> -> ! // norm=true multi=true ! // -> -> c[1-m]*g ! ! // inverse gain normalization ! // input: generalized_cepstrum_transformed_output ! // output: inverse_gain_normalized_output ! const std::vector<double>* inverse_gain_normalized_output; ! if (!is_normalized_output_) { ! GeneralizedCepstrumInverseGainNormalization ! generalized_cepstrum_inverse_gain_normalization(num_output_order_, ! output_gamma_); ! if (!generalized_cepstrum_inverse_gain_normalization.IsValid()) { ! return false; } ! if (!generalized_cepstrum_inverse_gain_normalization.Run( ! *generalized_cepstrum_transformed_output, ! &buffer->inverse_gain_normalized_output_)) { return false; } - inverse_gain_normalized_output = &buffer->inverse_gain_normalized_output_; - } else { - inverse_gain_normalized_output = generalized_cepstrum_transformed_output; - } - - // gamma multiplication - // input: inverse_gain_normalized_output - // output: output - if (is_multiplied_output_) { - std::transform(inverse_gain_normalized_output->begin(), - inverse_gain_normalized_output->end(), output->begin(), - std::bind1st(std::multiplies<double>(), output_gamma_)); - } else { - std::copy(inverse_gain_normalized_output->begin(), - inverse_gain_normalized_output->end(), output->begin()); } --- 266,446 ---- return; } + if (input_alpha_ != output_alpha_) { alpha_transform_ = (output_alpha_ - input_alpha_) / (1.0 - input_alpha_ * output_alpha_); } ! // ch_a: change alpha ! // norm_i: normalized input ! // norm_o: normalized output ! // ch_g: change gamma ! // ch_m: change order ! // ch_a=F norm_i=F norm_o=F ch_g=F ch_m=F ! // -> -> -> -> ! // ch_a=F norm_i=F norm_o=F ch_g=F ch_m=T ! // -> -> gnorm -> gc2gc -> ignorm ! // ch_a=F norm_i=F norm_o=F ch_g=T ch_m=F ! // -> -> gnorm -> gc2gc -> ignorm ! // ch_a=F norm_i=F norm_o=F ch_g=T ch_m=T ! // -> -> gnorm -> gc2gc -> ignorm ! // ch_a=F norm_i=F norm_o=T ch_g=F ch_m=F ! // -> -> gnorm -> -> ! // ch_a=F norm_i=F norm_o=T ch_g=F ch_m=T ! // -> -> gnorm -> gc2gc -> ! // ch_a=F norm_i=F norm_o=T ch_g=T ch_m=F ! // -> -> gnorm -> gc2gc -> ! // ch_a=F norm_i=F norm_o=T ch_g=T ch_m=T ! // -> -> gnorm -> gc2gc -> ! // ch_a=F norm_i=T norm_o=F ch_g=F ch_m=F ! // -> -> -> -> ignorm ! // ch_a=F norm_i=T norm_o=F ch_g=F ch_m=T ! // -> -> -> gc2gc -> ignorm ! // ch_a=F norm_i=T norm_o=F ch_g=T ch_m=F ! // -> -> -> gc2gc -> ignorm ! // ch_a=F norm_i=T norm_o=F ch_g=T ch_m=T ! // -> -> -> gc2gc -> ignorm ! // ch_a=F norm_i=T norm_o=T ch_g=F ch_m=F ! // -> -> -> -> ! // ch_a=F norm_i=T norm_o=T ch_g=F ch_m=T ! // -> -> -> gc2gc -> ! // ch_a=F norm_i=T norm_o=T ch_g=T ch_m=F ! // -> -> -> gc2gc -> ! // ch_a=F norm_i=T norm_o=T ch_g=T ch_m=T ! // -> -> -> gc2gc -> ! // ch_a=T norm_i=F norm_o=F ch_g=F ch_m=F ! // -> freqt -> -> -> ! // ch_a=T norm_i=F norm_o=F ch_g=F ch_m=T ! // -> freqt -> -> -> ! // ch_a=T norm_i=F norm_o=F ch_g=T ch_m=F ! // -> freqt -> gnorm -> gc2gc -> ignorm ! // ch_a=T norm_i=F norm_o=F ch_g=T ch_m=T ! // -> freqt -> gnorm -> gc2gc -> ignorm ! // ch_a=T norm_i=F norm_o=T ch_g=F ch_m=F ! // -> freqt -> gnorm -> -> ! // ch_a=T norm_i=F norm_o=T ch_g=F ch_m=T ! // -> freqt -> gnorm -> -> ! // ch_a=T norm_i=F norm_o=T ch_g=T ch_m=F ! // -> freqt -> gnorm -> gc2gc -> ! // ch_a=T norm_i=F norm_o=T ch_g=T ch_m=T ! // -> freqt -> gnorm -> gc2gc -> ! // ch_a=T norm_i=T norm_o=F ch_g=F ch_m=F ! // ignorm -> freqt -> -> -> ! // ch_a=T norm_i=T norm_o=F ch_g=F ch_m=T ! // ignorm -> freqt -> -> -> ! // ch_a=T norm_i=T norm_o=F ch_g=T ch_m=F ! // ignorm -> freqt -> gnorm -> gc2gc -> ignorm ! // ch_a=T norm_i=T norm_o=F ch_g=T ch_m=T ! // ignorm -> freqt -> gnorm -> gc2gc -> ignorm ! ! // ch_a=T norm_i=T norm_o=T ch_g=F ch_m=F ! // ignorm -> freqt -> gnorm -> -> ! // ch_a=T norm_i=T norm_o=T ch_g=F ch_m=T ! // ignorm -> freqt -> gnorm -> -> ! // ch_a=T norm_i=T norm_o=T ch_g=T ch_m=F ! // ignorm -> freqt -> gnorm -> gc2gc -> ! // ch_a=T norm_i=T norm_o=T ch_g=T ch_m=T ! // ignorm -> freqt -> gnorm -> gc2gc -> ! ! if (0.0 == alpha_transform_) { ! if (num_input_order_ == num_output_order_ && ! input_gamma_ == output_gamma_) { ! if (!is_multiplied_input_ && is_multiplied_output_) ! modules_.push_back( ! new GammaMultiplicationModule(num_input_order_, input_gamma_)); ! if (!is_normalized_input_ && is_normalized_output_) ! modules_.push_back( ! new GainNormalizationModule(num_input_order_, input_gamma_)); ! if (is_normalized_input_ && !is_normalized_output_) ! modules_.push_back(new InverseGainNormalizationModule(num_output_order_, ! output_gamma_)); ! if (is_multiplied_input_ && !is_multiplied_output_) ! modules_.push_back( ! new GammaDivisionModule(num_output_order_, output_gamma_)); ! } else { ! if (is_multiplied_input_) ! modules_.push_back( ! new GammaDivisionModule(num_input_order_, input_gamma_)); ! if (!is_normalized_input_) ! modules_.push_back( ! new GainNormalizationModule(num_input_order_, input_gamma_)); ! modules_.push_back(new GeneralizedCepstrumTransformModule( ! num_input_order_, num_output_order_, input_gamma_, output_gamma_)); ! if (!is_normalized_output_) ! modules_.push_back(new InverseGainNormalizationModule(num_output_order_, ! output_gamma_)); ! if (is_multiplied_output_) ! modules_.push_back( ! new GammaMultiplicationModule(num_output_order_, output_gamma_)); } } else { ! if (is_multiplied_input_) ! modules_.push_back( ! new GammaDivisionModule(num_input_order_, input_gamma_)); ! if (is_normalized_input_) ! modules_.push_back( ! new InverseGainNormalizationModule(num_input_order_, input_gamma_)); ! modules_.push_back(new FrequencyTransformModule( ! num_input_order_, num_output_order_, alpha_transform_)); ! if (is_normalized_output_ || input_gamma_ != output_gamma_) ! modules_.push_back( ! new GainNormalizationModule(num_output_order_, input_gamma_)); ! if (input_gamma_ != output_gamma_) ! modules_.push_back(new GeneralizedCepstrumTransformModule( ! num_output_order_, num_output_order_, input_gamma_, output_gamma_)); ! if (!is_normalized_output_ && input_gamma_ != output_gamma_) ! modules_.push_back( ! new InverseGainNormalizationModule(num_output_order_, output_gamma_)); ! if (is_multiplied_output_) ! modules_.push_back( ! new GammaMultiplicationModule(num_output_order_, output_gamma_)); } ! for (std::vector<GeneralizedCepstrumTransform::ModuleInterface *>::iterator ! itr(modules_.begin()); ! itr != modules_.end(); ++itr) { ! if (!(*itr)->IsValid()) { ! is_valid_ = false; ! break; } ! } ! } ! bool GeneralizedCepstrumTransform::Run( ! const std::vector<double> &input, std::vector<double> *output, ! GeneralizedCepstrumTransform::Buffer *buffer) const { ! if (!is_valid_ || ! static_cast<std::size_t>(num_input_order_ + 1) != input.size() || ! NULL == output || NULL == buffer) { ! return false; ! } ! if (modules_.empty()) { ! if (output->size() < static_cast<std::size_t>(num_output_order_ + 1)) { ! output->resize(num_output_order_ + 1); } ! std::copy(input.begin(), input.end(), output->begin()); ! return true; } ! for (std::vector<GeneralizedCepstrumTransform::ModuleInterface ! *>::const_iterator itr(modules_.begin()); ! itr != modules_.end(); ++itr) { ! if (itr != modules_.begin()) { ! output->swap(buffer->temporary_generalized_cepstrum_); } ! if (!(*itr)->Run((itr == modules_.begin()) ! ? input ! : buffer->temporary_generalized_cepstrum_, ! output, &(buffer->frequency_transform_buffer_))) { return false; } } Index: generalized_cepstrum_transform.h =================================================================== RCS file: /cvsroot/sp-tk/SPTK4/src/generalized_cepstrum_transform.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** generalized_cepstrum_transform.h 24 Oct 2016 08:20:30 -0000 1.2 --- generalized_cepstrum_transform.h 16 Dec 2016 09:36:32 -0000 1.3 *************** *** 63,77 **** private: - std::vector<double> inverse_gain_normalized_input_; - std::vector<double> gamma_divided_input_; - std::vector<double> frequency_transformed_input_; FrequencyTransform::Buffer frequency_transform_buffer_; ! std::vector<double> gain_normalized_input_; ! std::vector<double> generalized_cepstrum_transformed_output_; ! std::vector<double> inverse_gain_normalized_output_; friend class GeneralizedCepstrumTransform; DISALLOW_COPY_AND_ASSIGN(Buffer); }; // GeneralizedCepstrumTransform(int num_input_order_, double input_alpha_, --- 63,82 ---- private: FrequencyTransform::Buffer frequency_transform_buffer_; ! std::vector<double> temporary_generalized_cepstrum_; friend class GeneralizedCepstrumTransform; DISALLOW_COPY_AND_ASSIGN(Buffer); }; + class ModuleInterface { + public: + virtual ~ModuleInterface() { + } + virtual bool IsValid() const = 0; + virtual bool Run( + const std::vector<double> &input, std::vector<double> *output, + FrequencyTransform::Buffer *frequency_transform_buffer) const = 0; + }; + // GeneralizedCepstrumTransform(int num_input_order_, double input_alpha_, *************** *** 84,87 **** --- 89,97 ---- // virtual ~GeneralizedCepstrumTransform() { + for (std::vector<GeneralizedCepstrumTransform::ModuleInterface *>::iterator + itr(modules_.begin()); + itr != modules_.end(); ++itr) { + delete (*itr); + } } *************** *** 142,147 **** // ! bool Run(const std::vector<double>& input, std::vector<double>* output, ! GeneralizedCepstrumTransform::Buffer* buffer) const; private: --- 152,157 ---- // ! bool Run(const std::vector<double> &input, std::vector<double> *output, ! GeneralizedCepstrumTransform::Buffer *buffer) const; private: *************** *** 180,183 **** --- 190,196 ---- // + std::vector<GeneralizedCepstrumTransform::ModuleInterface *> modules_; + + // bool is_valid_; |