Skip to content

Commit

Permalink
Merge pull request #48 from sp-nitech/update_pitch2sin
Browse files Browse the repository at this point in the history
Extend sinusoidal signal
  • Loading branch information
takenori-y committed Oct 13, 2023
2 parents f217d7c + 5d82675 commit a855827
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 45 deletions.
11 changes: 9 additions & 2 deletions include/SPTK/generation/sinusoidal_generation.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ namespace sptk {
class SinusoidalGeneration {
public:
/**
* @param[in] strict If true, strictly drop sinusoidal in an unvoiced region.
* @param[in] input_source Input source.
*/
explicit SinusoidalGeneration(
InputSourceInterpolationWithMagicNumber* input_source);
bool strict, InputSourceInterpolationWithMagicNumber* input_source);

virtual ~SinusoidalGeneration() {
}
Expand All @@ -58,13 +59,19 @@ class SinusoidalGeneration {
bool Get(double* sin, double* cos, double* pitch);

private:
const bool strict_;

InputSourceInterpolationWithMagicNumber* input_source_;

bool is_valid_;

// Phase value ranging from 0.0 to 2 x pi
// Phase value ranging from 0 to 2 x pi
double phase_;

// For strict = false
double voiced_pitch_;
bool extending_;

DISALLOW_COPY_AND_ASSIGN(SinusoidalGeneration);
};

Expand Down
26 changes: 24 additions & 2 deletions src/generation/sinusoidal_generation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
namespace sptk {

SinusoidalGeneration::SinusoidalGeneration(
InputSourceInterpolationWithMagicNumber* input_source)
: input_source_(input_source), is_valid_(true), phase_(0.0) {
bool strict, InputSourceInterpolationWithMagicNumber* input_source)
: strict_(strict),
input_source_(input_source),
is_valid_(true),
phase_(0.0),
voiced_pitch_(0.0),
extending_(false) {
if (NULL == input_source_ || !input_source_->IsValid()) {
is_valid_ = false;
return;
Expand All @@ -45,6 +50,12 @@ bool SinusoidalGeneration::Get(double* sin, double* cos, double* pitch) {
pitch_in_current_point = tmp[0];
}

const bool unvoiced(input_source_->GetMagicNumber() ==
pitch_in_current_point);
if (!strict_ && unvoiced && extending_) {
pitch_in_current_point = voiced_pitch_;
}

if (pitch) {
*pitch = pitch_in_current_point;
}
Expand All @@ -68,8 +79,19 @@ bool SinusoidalGeneration::Get(double* sin, double* cos, double* pitch) {
*cos = std::cos(phase_);
}

if (!strict_) {
extending_ = true;
voiced_pitch_ = pitch_in_current_point;
}

// Proceed phase.
const double prev_phase(phase_);
phase_ += sptk::kTwoPi / pitch_in_current_point;
if (!strict_ && unvoiced &&
((prev_phase <= sptk::kPi && sptk::kPi <= phase_) ||
(prev_phase <= sptk::kTwoPi && sptk::kTwoPi <= phase_))) {
extending_ = false;
}
if (sptk::kTwoPi < phase_) {
phase_ -= sptk::kTwoPi;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/excite.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ void PrintUsage(std::ostream* stream) {
* - @b -s @e int
* - seed for random number generation
* - @b infile @e str
* - pitch period
* - double-type pitch period
* - @b stdout
* - excitation
* - double-type excitation
*
* This command generates an excitation sequence from the pitch period in
* @c infile (or standard input), and sends the result to standard output.
Expand Down
55 changes: 16 additions & 39 deletions src/main/pitch2sin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// limitations under the License. //
// ------------------------------------------------------------------------ //

#include <fstream> // std::ifstream, std::ofstream
#include <fstream> // std::ifstream
#include <iomanip> // std::setw
#include <iostream> // std::cerr, std::cin, std::cout, std::endl, etc.
#include <sstream> // std::ostringstream
Expand All @@ -32,6 +32,7 @@ enum OutputFormats { kSine = 0, kCosine, kNumOutputFormats };
const int kDefaultFramePeriod(100);
const int kDefaultInterpolationPeriod(1);
const OutputFormats kDefaultOutputFormat(kSine);
const bool kDefaultStrictFlag(false);
const double kMagicNumberForUnvoicedFrame(0.0);

void PrintUsage(std::ostream* stream) {
Expand All @@ -47,8 +48,8 @@ void PrintUsage(std::ostream* stream) {
*stream << " -o o : output format ( int)[" << std::setw(5) << std::right << kDefaultOutputFormat << "][ 0 <= o <= 1 ]" << std::endl; // NOLINT
*stream << " 0 (sine)" << std::endl;
*stream << " 1 (cosine)" << std::endl;
*stream << " -V V : output filename of (string)[" << std::setw(5) << std::right << "N/A" << "]" << std::endl; // NOLINT
*stream << " double type vuv" << std::endl;
*stream << " -s : strictly drop signal ( bool)[" << std::setw(5) << std::right << sptk::ConvertBooleanToString(kDefaultStrictFlag) << "]" << std::endl; // NOLINT
*stream << " in unvoiced region" << std::endl;
*stream << " -h : print this message" << std::endl;
*stream << " infile:" << std::endl;
*stream << " pitch period (double)[stdin]" << std::endl;
Expand Down Expand Up @@ -76,12 +77,12 @@ void PrintUsage(std::ostream* stream) {
* - output format
* \arg @c 0 sine
* \arg @c 1 cosine
* - @b -V @e str
* - double-type voiced/unvoiced symbol
* - @b -s
* - strictly drop sinusoidal in unvoiced region
* - @b infile @e str
* - pitch period
* - double-type pitch period
* - @b stdout
* - sinudoisal sequence
* - double-type sinusoidal sequence
*
* The below is a simple example to generate sinusoidal from @c data.d.
*
Expand All @@ -97,10 +98,10 @@ int main(int argc, char* argv[]) {
int frame_period(kDefaultFramePeriod);
int interpolation_period(kDefaultInterpolationPeriod);
OutputFormats output_format(kDefaultOutputFormat);
const char* vuv_file(NULL);
bool strict(kDefaultStrictFlag);

for (;;) {
const int option_char(getopt_long(argc, argv, "p:i:o:V:h", NULL, NULL));
const int option_char(getopt_long(argc, argv, "p:i:o:sh", NULL, NULL));
if (-1 == option_char) break;

switch (option_char) {
Expand Down Expand Up @@ -141,8 +142,8 @@ int main(int argc, char* argv[]) {
output_format = static_cast<OutputFormats>(tmp);
break;
}
case 'V': {
vuv_file = optarg;
case 's': {
strict = true;
break;
}
case 'h': {
Expand Down Expand Up @@ -192,18 +193,6 @@ int main(int argc, char* argv[]) {
}
std::istream& input_stream(ifs.is_open() ? ifs : std::cin);

std::ofstream ofs;
if (NULL != vuv_file) {
ofs.open(vuv_file, std::ios::out | std::ios::binary);
if (ofs.fail()) {
std::ostringstream error_message;
error_message << "Cannot open file " << vuv_file;
sptk::PrintErrorMessage("pitch2sin", error_message);
return 1;
}
}
std::ostream& output_stream(ofs);

sptk::InputSourceFromStream input_source_from_stream(false, 1, &input_stream);
sptk::InputSourceInterpolationWithMagicNumber
input_source_interpolation_with_magic_number(
Expand All @@ -217,7 +206,7 @@ int main(int argc, char* argv[]) {
}

sptk::SinusoidalGeneration sinusoidal_generation(
&input_source_interpolation_with_magic_number);
strict, &input_source_interpolation_with_magic_number);
if (!sinusoidal_generation.IsValid()) {
std::ostringstream error_message;
error_message << "Failed to initialize SinusoidalGeneration";
Expand All @@ -226,27 +215,15 @@ int main(int argc, char* argv[]) {
}

double sinusoidal;
double pitch;
while (
sinusoidal_generation.Get(kSine == output_format ? &sinusoidal : NULL,
kCosine == output_format ? &sinusoidal : NULL,
NULL != vuv_file ? &pitch : NULL)) {
while (sinusoidal_generation.Get(
kSine == output_format ? &sinusoidal : NULL,
kCosine == output_format ? &sinusoidal : NULL, NULL)) {
if (!sptk::WriteStream(sinusoidal, &std::cout)) {
std::ostringstream error_message;
error_message << "Failed to write sinusoidal";
sptk::PrintErrorMessage("pitch2sin", error_message);
return 1;
}

if (NULL != vuv_file) {
const double vuv(kMagicNumberForUnvoicedFrame == pitch ? 0.0 : 1.0);
if (!sptk::WriteStream(vuv, &output_stream)) {
std::ostringstream error_message;
error_message << "Failed to write vuv symbol";
sptk::PrintErrorMessage("pitch2sin", error_message);
return 1;
}
}
}

return 0;
Expand Down

0 comments on commit a855827

Please sign in to comment.