diff --git a/CMakeLists.txt b/CMakeLists.txt index d83dc5c..83dadd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,6 +141,7 @@ set(CC_SOURCES ${SOURCE_DIR}/filter/all_pole_digital_filter.cc ${SOURCE_DIR}/filter/all_pole_lattice_digital_filter.cc ${SOURCE_DIR}/filter/all_zero_digital_filter.cc + ${SOURCE_DIR}/filter/all_zero_lattice_digital_filter.cc ${SOURCE_DIR}/filter/infinite_impulse_response_digital_filter.cc ${SOURCE_DIR}/filter/inverse_mglsa_digital_filter.cc ${SOURCE_DIR}/filter/inverse_pseudo_quadrature_mirror_filter_banks.cc @@ -313,6 +314,7 @@ set(MAIN_SOURCES ${SOURCE_DIR}/main/ifft.cc ${SOURCE_DIR}/main/ifft2.cc ${SOURCE_DIR}/main/ignorm.cc + ${SOURCE_DIR}/main/iltcdf.cc ${SOURCE_DIR}/main/imglsadf.cc ${SOURCE_DIR}/main/impulse.cc ${SOURCE_DIR}/main/imsvq.cc diff --git a/doc/main/iltcdf.rst b/doc/main/iltcdf.rst new file mode 100644 index 0000000..301d8e2 --- /dev/null +++ b/doc/main/iltcdf.rst @@ -0,0 +1,11 @@ +.. _iltcdf: + +iltcdf +====== + +.. doxygenfile:: iltcdf.cc + +.. seealso:: :ref:`lpc2par` :ref:`ltcdf` + +.. doxygenclass:: sptk::AllZeroLatticeDigitalFilter + :members: diff --git a/doc/main/ltcdf.rst b/doc/main/ltcdf.rst index 1c03c0d..2bb7248 100644 --- a/doc/main/ltcdf.rst +++ b/doc/main/ltcdf.rst @@ -5,7 +5,7 @@ ltcdf .. doxygenfile:: ltcdf.cc -.. seealso:: :ref:`lpc2par` +.. seealso:: :ref:`lpc2par` :ref:`iltcdf` .. doxygenclass:: sptk::AllPoleLatticeDigitalFilter :members: diff --git a/include/SPTK/filter/all_zero_lattice_digital_filter.h b/include/SPTK/filter/all_zero_lattice_digital_filter.h new file mode 100644 index 0000000..9a154ec --- /dev/null +++ b/include/SPTK/filter/all_zero_lattice_digital_filter.h @@ -0,0 +1,111 @@ +// ------------------------------------------------------------------------ // +// Copyright 2021 SPTK Working Group // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ------------------------------------------------------------------------ // + +#ifndef SPTK_FILTER_ALL_ZERO_LATTICE_DIGITAL_FILTER_H_ +#define SPTK_FILTER_ALL_ZERO_LATTICE_DIGITAL_FILTER_H_ + +#include // std::vector + +#include "SPTK/utils/sptk_utils.h" + +namespace sptk { + +/** + * Apply all-zero lattice filter for speech synthesis. + * + * Given the @f$M@f$-th order PARCOR coefficients, + * @f[ + * \begin{array}{cccc} + * K, & k(1), & \ldots, & k(M), + * \end{array} + * @f] + * an output signal is obtained by applying the all-zero lattice filter to an + * input signal in time domain. + */ +class AllZeroLatticeDigitalFilter { + public: + /** + * Buffer for AllZeroLatticeDigitalFilter class. + */ + class Buffer { + public: + Buffer() { + } + + virtual ~Buffer() { + } + + private: + std::vector d_; + + friend class AllZeroLatticeDigitalFilter; + DISALLOW_COPY_AND_ASSIGN(Buffer); + }; + + /** + * @param[in] num_filter_order Order of filter coefficients, @f$M@f$. + */ + explicit AllZeroLatticeDigitalFilter(int num_filter_order); + + virtual ~AllZeroLatticeDigitalFilter() { + } + + /** + * @return Order of coefficients. + */ + int GetNumFilterOrder() const { + return num_filter_order_; + } + + /** + * @return True if this object is valid. + */ + bool IsValid() const { + return is_valid_; + } + + /** + * @param[in] filter_coefficients @f$M@f$-th order PARCOR coefficients. + * @param[in] filter_input Input signal. + * @param[out] filter_output Output signal. + * @param[in,out] buffer Buffer. + * @return True on success, false on failure. + */ + bool Run(const std::vector& filter_coefficients, double filter_input, + double* filter_output, + AllZeroLatticeDigitalFilter::Buffer* buffer) const; + + /** + * @param[in] filter_coefficients @f$M@f$-th order PARCOR coefficients. + * @param[in,out] input_and_output Input/output signal. + * @param[in,out] buffer Buffer. + * @return True on success, false on failure. + */ + bool Run(const std::vector& filter_coefficients, + double* input_and_output, + AllZeroLatticeDigitalFilter::Buffer* buffer) const; + + private: + const int num_filter_order_; + + bool is_valid_; + + DISALLOW_COPY_AND_ASSIGN(AllZeroLatticeDigitalFilter); +}; + +} // namespace sptk + +#endif // SPTK_FILTER_ALL_ZERO_LATTICE_DIGITAL_FILTER_H_ diff --git a/include/SPTK/input/input_source_preprocessing_for_filter_gain.h b/include/SPTK/input/input_source_preprocessing_for_filter_gain.h index 5e29cb2..60bdb02 100644 --- a/include/SPTK/input/input_source_preprocessing_for_filter_gain.h +++ b/include/SPTK/input/input_source_preprocessing_for_filter_gain.h @@ -35,6 +35,7 @@ class InputSourcePreprocessingForFilterGain : public InputSourceInterface { enum FilterGainType { kLinear = 0, kLog, + kInverse, kUnity, kUnityForAllZeroFilter, }; diff --git a/src/filter/all_zero_lattice_digital_filter.cc b/src/filter/all_zero_lattice_digital_filter.cc new file mode 100644 index 0000000..4634f16 --- /dev/null +++ b/src/filter/all_zero_lattice_digital_filter.cc @@ -0,0 +1,80 @@ +// ------------------------------------------------------------------------ // +// Copyright 2021 SPTK Working Group // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ------------------------------------------------------------------------ // + +#include "SPTK/filter/all_zero_lattice_digital_filter.h" + +#include // std::fill +#include // std::size_t + +namespace sptk { + +AllZeroLatticeDigitalFilter::AllZeroLatticeDigitalFilter(int num_filter_order) + : num_filter_order_(num_filter_order), is_valid_(true) { + if (num_filter_order_ < 0) { + is_valid_ = false; + return; + } +} + +bool AllZeroLatticeDigitalFilter::Run( + const std::vector& filter_coefficients, double filter_input, + double* filter_output, AllZeroLatticeDigitalFilter::Buffer* buffer) const { + // Check inputs + if (!is_valid_ || + filter_coefficients.size() != + static_cast(num_filter_order_ + 1) || + NULL == filter_output || NULL == buffer) { + return false; + } + + // Prepare memories. + if (buffer->d_.size() != static_cast(num_filter_order_)) { + buffer->d_.resize(num_filter_order_); + std::fill(buffer->d_.begin(), buffer->d_.end(), 0.0); + } + + if (0 == num_filter_order_) { + *filter_output = filter_input * filter_coefficients[0]; + return true; + } + + const double* k(&(filter_coefficients[1])); + double* d(&buffer->d_[0]); + double sum(filter_input); + double next_d(filter_input); + + // Apply all-zero lattice filter. + for (int m(0); m < num_filter_order_; ++m) { + const double tmp(d[m] + k[m] * sum); + sum += k[m] * d[m]; + d[m] = next_d; + next_d = tmp; + } + + // Save result. + *filter_output = sum * filter_coefficients[0]; + + return true; +} + +bool AllZeroLatticeDigitalFilter::Run( + const std::vector& filter_coefficients, double* input_and_output, + AllZeroLatticeDigitalFilter::Buffer* buffer) const { + if (NULL == input_and_output) return false; + return Run(filter_coefficients, *input_and_output, input_and_output, buffer); +} + +} // namespace sptk diff --git a/src/input/input_source_preprocessing_for_filter_gain.cc b/src/input/input_source_preprocessing_for_filter_gain.cc index 5f0d78c..7a96e36 100644 --- a/src/input/input_source_preprocessing_for_filter_gain.cc +++ b/src/input/input_source_preprocessing_for_filter_gain.cc @@ -48,6 +48,11 @@ bool InputSourcePreprocessingForFilterGain::Get(std::vector* buffer) { (*buffer)[0] = std::exp((*buffer)[0]); break; } + case kInverse: { + if (0.0 == (*buffer)[0]) return false; + (*buffer)[0] = 1.0 / (*buffer)[0]; + break; + } case kUnity: { (*buffer)[0] = 1.0; break; diff --git a/src/main/iltcdf.cc b/src/main/iltcdf.cc new file mode 100644 index 0000000..54daea4 --- /dev/null +++ b/src/main/iltcdf.cc @@ -0,0 +1,267 @@ +// ------------------------------------------------------------------------ // +// Copyright 2021 SPTK Working Group // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ------------------------------------------------------------------------ // + +#include // std::ifstream +#include // std::setw +#include // std::cerr, std::cin, std::cout, std::endl, etc. +#include // std::ostringstream +#include // std::vector + +#include "GETOPT/ya_getopt.h" +#include "SPTK/filter/all_zero_lattice_digital_filter.h" +#include "SPTK/input/input_source_from_stream.h" +#include "SPTK/input/input_source_interpolation.h" +#include "SPTK/input/input_source_preprocessing_for_filter_gain.h" +#include "SPTK/utils/sptk_utils.h" + +namespace { + +const int kDefaultNumFilterOrder(25); +const int kDefaultFramePeriod(100); +const int kDefaultInterpolationPeriod(1); +const bool kDefaultGainFlag(true); + +void PrintUsage(std::ostream* stream) { + // clang-format off + *stream << std::endl; + *stream << " iltcdf - all-zero lattice digital filter for speech synthesis" << std::endl; // NOLINT + *stream << std::endl; + *stream << " usage:" << std::endl; + *stream << " iltcdf [ options ] kfile [ infile ] > stdout" << std::endl; + *stream << " options:" << std::endl; + *stream << " -m m : order of filter coefficients ( int)[" << std::setw(5) << std::right << kDefaultNumFilterOrder << "][ 0 <= m <= ]" << std::endl; // NOLINT + *stream << " -p p : frame period ( int)[" << std::setw(5) << std::right << kDefaultFramePeriod << "][ 0 < p <= ]" << std::endl; // NOLINT + *stream << " -i i : interpolation period ( int)[" << std::setw(5) << std::right << kDefaultInterpolationPeriod << "][ 0 <= i <= p/2 ]" << std::endl; // NOLINT + *stream << " -k : filtering without gain ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(!kDefaultGainFlag) << "]" << std::endl; // NOLINT + *stream << " -h : print this message" << std::endl; + *stream << " kfile:" << std::endl; + *stream << " filter (PARCOR) coefficients (double)" << std::endl; // NOLINT + *stream << " infile:" << std::endl; + *stream << " filter input (double)[stdin]" << std::endl; // NOLINT + *stream << " stdout:" << std::endl; + *stream << " filter output (double)" << std::endl; // NOLINT + *stream << " notice:" << std::endl; + *stream << " if i = 0, don't interpolate filter coefficients" << std::endl; // NOLINT + *stream << std::endl; + *stream << " SPTK: version " << sptk::kVersion << std::endl; + *stream << std::endl; + // clang-format on +} + +} // namespace + +/** + * @a iltcdf [ @e option ] @e kfile [ @e infile ] + * + * - @b -m @e int + * - order of coefficients @f$(0 \le M)@f$ + * - @b -p @e int + * - frame period @f$(1 \le P)@f$ + * - @b -i @e int + * - interpolation period @f$(0 \le I \le P/2)@f$ + * - @b -k + * - filtering without gain + * - @b kfile @e str + * - double-type PARCOR coefficients + * - @b infile @e str + * - double-type input sequence + * - @b stdout + * - double-type output sequence + * + * In the below example, an excitaion signal generated from pitch information is + * reconstructed using the synthesis and analysis filters built from PARCOR + * coefficients. + * + * @code{.sh} + * excite < data.pitch | ltcdf data.rc | iltcdf data.rc > data.e + * @endcode + * + * @param[in] argc Number of arguments. + * @param[in] argv Argument vector. + * @return 0 on success, 1 on failure. + */ +int main(int argc, char* argv[]) { + int num_filter_order(kDefaultNumFilterOrder); + int frame_period(kDefaultFramePeriod); + int interpolation_period(kDefaultInterpolationPeriod); + bool gain_flag(kDefaultGainFlag); + + for (;;) { + const int option_char(getopt_long(argc, argv, "m:p:i:kh", NULL, NULL)); + if (-1 == option_char) break; + + switch (option_char) { + case 'm': { + if (!sptk::ConvertStringToInteger(optarg, &num_filter_order) || + num_filter_order < 0) { + std::ostringstream error_message; + error_message << "The argument for the -m option must be a " + << "non-negative integer"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + break; + } + case 'p': { + if (!sptk::ConvertStringToInteger(optarg, &frame_period) || + frame_period <= 0) { + std::ostringstream error_message; + error_message + << "The argument for the -p option must be a positive integer"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + break; + } + case 'i': { + if (!sptk::ConvertStringToInteger(optarg, &interpolation_period) || + interpolation_period < 0) { + std::ostringstream error_message; + error_message << "The argument for the -i option must be a " + << "non-negative integer"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + break; + } + case 'k': { + gain_flag = false; + break; + } + case 'h': { + PrintUsage(&std::cout); + return 0; + } + default: { + PrintUsage(&std::cerr); + return 1; + } + } + } + + if (frame_period / 2 < interpolation_period) { + std::ostringstream error_message; + error_message << "Interpolation period must be equal to or less than half " + << "frame period"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + // Get input file names. + const char* filter_coefficients_file; + const char* filter_input_file; + const int num_input_files(argc - optind); + if (2 == num_input_files) { + filter_coefficients_file = argv[argc - 2]; + filter_input_file = argv[argc - 1]; + } else if (1 == num_input_files) { + filter_coefficients_file = argv[argc - 1]; + filter_input_file = NULL; + } else { + std::ostringstream error_message; + error_message << "Just two input files, kfile and infile, are required"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + if (!sptk::SetBinaryMode()) { + std::ostringstream error_message; + error_message << "Cannot set translation mode"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + // Open stream for reading filter coefficients. + std::ifstream ifs1; + ifs1.open(filter_coefficients_file, std::ios::in | std::ios::binary); + if (ifs1.fail()) { + std::ostringstream error_message; + error_message << "Cannot open file " << filter_coefficients_file; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + std::istream& stream_for_filter_coefficients(ifs1); + + // Open stream for reading input signals. + std::ifstream ifs2; + if (NULL != filter_input_file) { + ifs2.open(filter_input_file, std::ios::in | std::ios::binary); + if (ifs2.fail()) { + std::ostringstream error_message; + error_message << "Cannot open file " << filter_input_file; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + } + std::istream& stream_for_filter_input(ifs2.is_open() ? ifs2 : std::cin); + + // Prepare variables for filtering. + const int filter_length(num_filter_order + 1); + std::vector filter_coefficients(filter_length); + sptk::InputSourceFromStream input_source(false, filter_length, + &stream_for_filter_coefficients); + sptk::InputSourceInterpolation interpolation( + frame_period, interpolation_period, true, &input_source); + const sptk::InputSourcePreprocessingForFilterGain::FilterGainType gain_type( + gain_flag ? sptk::InputSourcePreprocessingForFilterGain::FilterGainType:: + kInverse + : sptk::InputSourcePreprocessingForFilterGain::FilterGainType:: + kUnity); + sptk::InputSourcePreprocessingForFilterGain preprocessing(gain_type, + &interpolation); + if (!preprocessing.IsValid()) { + std::ostringstream error_message; + error_message << "Failed to initialize InputSource"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + sptk::AllZeroLatticeDigitalFilter filter(num_filter_order); + sptk::AllZeroLatticeDigitalFilter::Buffer buffer; + if (!filter.IsValid()) { + std::ostringstream error_message; + error_message << "Failed to initialize AllZeroLatticeDigitalFilter"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + double signal; + + while (sptk::ReadStream(&signal, &stream_for_filter_input)) { + if (!preprocessing.Get(&filter_coefficients)) { + std::ostringstream error_message; + error_message << "Cannot get filter coefficients"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + if (!filter.Run(filter_coefficients, &signal, &buffer)) { + std::ostringstream error_message; + error_message << "Failed to apply all-zero lattice digital filter"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + + if (!sptk::WriteStream(signal, &std::cout)) { + std::ostringstream error_message; + error_message << "Failed to write a filter output"; + sptk::PrintErrorMessage("iltcdf", error_message); + return 1; + } + } + + return 0; +} diff --git a/src/main/lspdf.cc b/src/main/lspdf.cc index b2ddac1..dd5cf10 100644 --- a/src/main/lspdf.cc +++ b/src/main/lspdf.cc @@ -29,12 +29,17 @@ namespace { +enum LocalGainType { + kLinear = 0, + kLog, + kUnity, + kNumGainTypes, +}; + const int kDefaultNumFilterOrder(25); const int kDefaultFramePeriod(100); const int kDefaultInterpolationPeriod(1); -const sptk::InputSourcePreprocessingForFilterGain::FilterGainType - kDefaultGainType( - sptk::InputSourcePreprocessingForFilterGain::FilterGainType::kLinear); +const LocalGainType kDefaultGainType(kLinear); void PrintUsage(std::ostream* stream) { // clang-format off @@ -90,8 +95,8 @@ void PrintUsage(std::ostream* stream) { * - @b stdout * - double-type output sequence * - * In the below example, an exciation signal generated from pitch information is - * passed through the synthesis filter built from LSP coefficients. + * In the below example, an excitation signal generated from pitch information + * is passed through the synthesis filter built from LSP coefficients. * * @code{.sh} * excite < data.pitch | lspdf data.lsp > data.syn @@ -105,8 +110,7 @@ int main(int argc, char* argv[]) { int num_filter_order(kDefaultNumFilterOrder); int frame_period(kDefaultFramePeriod); int interpolation_period(kDefaultInterpolationPeriod); - sptk::InputSourcePreprocessingForFilterGain::FilterGainType gain_type( - kDefaultGainType); + LocalGainType local_gain_type(kDefaultGainType); for (;;) { const int option_char(getopt_long(argc, argv, "m:p:i:k:h", NULL, NULL)); @@ -148,8 +152,7 @@ int main(int argc, char* argv[]) { } case 'k': { const int min(0); - const int max(static_cast( - sptk::InputSourcePreprocessingForFilterGain::kUnity)); + const int max(static_cast(kNumGainTypes) - 1); int tmp; if (!sptk::ConvertStringToInteger(optarg, &tmp) || !sptk::IsInRange(tmp, min, max)) { @@ -159,8 +162,7 @@ int main(int argc, char* argv[]) { sptk::PrintErrorMessage("lspdf", error_message); return 1; } - gain_type = static_cast< - sptk::InputSourcePreprocessingForFilterGain::FilterGainType>(tmp); + local_gain_type = static_cast(tmp); break; } case 'h': { @@ -230,6 +232,25 @@ int main(int argc, char* argv[]) { } std::istream& stream_for_filter_input(ifs2.is_open() ? ifs2 : std::cin); + sptk::InputSourcePreprocessingForFilterGain::FilterGainType gain_type; + switch (local_gain_type) { + case kLinear: { + gain_type = sptk::InputSourcePreprocessingForFilterGain::kLinear; + break; + } + case kLog: { + gain_type = sptk::InputSourcePreprocessingForFilterGain::kLog; + break; + } + case kUnity: { + gain_type = sptk::InputSourcePreprocessingForFilterGain::kUnity; + break; + } + default: { + return 1; + } + } + // Prepare variables for filtering. const int filter_length(num_filter_order + 1); std::vector filter_coefficients(filter_length); diff --git a/src/main/ltcdf.cc b/src/main/ltcdf.cc index 46fe139..fa82c2c 100644 --- a/src/main/ltcdf.cc +++ b/src/main/ltcdf.cc @@ -81,8 +81,8 @@ void PrintUsage(std::ostream* stream) { * - @b stdout * - double-type output sequence * - * In the below example, an exciation signal generated from pitch information is - * passed through the synthesis filter built from PARCOR coefficients. + * In the below example, an excitation signal generated from pitch information + * is passed through the synthesis filter built from PARCOR coefficients. * * @code{.sh} * excite < data.pitch | ltcdf data.rc > data.syn diff --git a/src/main/mglsadf.cc b/src/main/mglsadf.cc index f915cd1..049646e 100644 --- a/src/main/mglsadf.cc +++ b/src/main/mglsadf.cc @@ -193,8 +193,8 @@ class InputSourcePreprocessingForMelCepstrum * - @b stdout * - double-type output sequence * - * In the below example, an exciation signal generated from pitch information is - * passed through the MLSA filter built from mel-cepstral coefficients + * In the below example, an excitation signal generated from pitch information + * is passed through the MLSA filter built from mel-cepstral coefficients * @c data.mcep. * * @code{.sh} diff --git a/src/main/poledf.cc b/src/main/poledf.cc index 90be788..9c664a8 100644 --- a/src/main/poledf.cc +++ b/src/main/poledf.cc @@ -85,8 +85,8 @@ void PrintUsage(std::ostream* stream) { * - @b stdout * - double-type output sequence * - * In the below example, an exciation signal generated from pitch information is - * passed through the standard form synthesis filter built from LPC + * In the below example, an excitation signal generated from pitch information + * is passed through the standard form synthesis filter built from LPC * coefficients. * * @code{.sh} diff --git a/src/main/window.cc b/src/main/window.cc index 5a9d0ab..ed70017 100644 --- a/src/main/window.cc +++ b/src/main/window.cc @@ -40,7 +40,7 @@ enum LocalWindowType { const int kDefaultFrameLength(256); const sptk::DataWindowing::NormalizationType kDefaultNormalizationType( sptk::DataWindowing::NormalizationType::kPower); -const LocalWindowType kDefaultLocalWindowType(kBlackman); +const LocalWindowType kDefaultWindowType(kBlackman); void PrintUsage(std::ostream* stream) { // clang-format off @@ -56,7 +56,7 @@ void PrintUsage(std::ostream* stream) { *stream << " 0 (none)" << std::endl; *stream << " 1 (power)" << std::endl; *stream << " 2 (magnitude)" << std::endl; - *stream << " -w w : window type ( int)[" << std::setw(5) << std::right << kDefaultLocalWindowType << "][ 0 <= w <= 5 ]" << std::endl; // NOLINT + *stream << " -w w : window type ( int)[" << std::setw(5) << std::right << kDefaultWindowType << "][ 0 <= w <= 5 ]" << std::endl; // NOLINT *stream << " 0 (Blackman)" << std::endl; *stream << " 1 (Hamming)" << std::endl; *stream << " 2 (Hanning)" << std::endl; @@ -117,7 +117,7 @@ int main(int argc, char* argv[]) { bool is_output_length_specified(false); sptk::DataWindowing::NormalizationType normalization_type( kDefaultNormalizationType); - LocalWindowType local_window_type(kDefaultLocalWindowType); + LocalWindowType local_window_type(kDefaultWindowType); for (;;) { const int option_char(getopt_long(argc, argv, "l:L:n:w:h", NULL, NULL)); diff --git a/src/main/zerodf.cc b/src/main/zerodf.cc index 78fafd0..25a57f7 100644 --- a/src/main/zerodf.cc +++ b/src/main/zerodf.cc @@ -85,12 +85,12 @@ void PrintUsage(std::ostream* stream) { * - @b stdout * - double-type output sequence * - * In the below example, an exciation signal generated from pitch information is - * passed through the standard form synthesis filter built from FIR filter + * In the below example, an excitation signal generated from pitch information + * is passed through the standard form synthesis filter built from FIR filter * coefficients. * * @code{.sh} - * excite < data.pitch | poledf data.fir > data.syn + * excite < data.pitch | zerodf data.b > data.syn * @endcode * * @param[in] argc Number of arguments. diff --git a/test/test_iltcdf.bats b/test/test_iltcdf.bats new file mode 100755 index 0000000..f9e8cc5 --- /dev/null +++ b/test/test_iltcdf.bats @@ -0,0 +1,55 @@ +#!/usr/bin/env bats +# ------------------------------------------------------------------------ # +# Copyright 2021 SPTK Working Group # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +# ------------------------------------------------------------------------ # + +sptk3=tools/sptk/bin +sptk4=bin +tmp=test_iltcdf +data=asset/data.short + +setup() { + mkdir -p $tmp +} + +teardown() { + rm -rf $tmp +} + +@test "iltcdf: reversibility" { + $sptk3/x2x +sd $data | $sptk3/frame -l 400 -p 80 | + $sptk3/window -l 400 -w 1 -n 1 | + $sptk3/lpc -l 400 -m 24 | + $sptk3/lpc2par -m 24 > $tmp/1 + + opt=("" "-k") + for o in $(seq 0 1); do + # shellcheck disable=SC2086 + $sptk3/nrand -l 19200 | + $sptk3/ltcdf -m 24 -p 80 ${opt[$o]} $tmp/1 | + $sptk4/iltcdf -m 24 -p 80 ${opt[$o]} $tmp/1 | + $sptk3/vstat > $tmp/2 + echo 0 1 | $sptk3/x2x +ad > $tmp/3 + run $sptk4/aeq -t 1e-2 $tmp/2 $tmp/3 + [ "$status" -eq 0 ] + done +} + +@test "iltcdf: valgrind" { + $sptk3/nrand -l 10 > $tmp/1 + $sptk3/nrand -l 10 > $tmp/2 + run valgrind $sptk4/iltcdf -m 1 -i 0 -p 1 $tmp/1 $tmp/2 + [ "$(echo "${lines[-1]}" | sed -r 's/.*SUMMARY: ([0-9]*) .*/\1/')" -eq 0 ] +}