-
Notifications
You must be signed in to change notification settings - Fork 26
/
pitch_extraction_by_harvest.cc
94 lines (80 loc) · 3.6 KB
/
pitch_extraction_by_harvest.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// ------------------------------------------------------------------------ //
// 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/analysis/pitch_extraction_by_harvest.h"
#include <algorithm> // std::copy, std::fill
#include <cmath> // std::ceil
#include "WORLD/world/harvest.h"
namespace sptk {
PitchExtractionByHarvest::PitchExtractionByHarvest(int frame_shift,
double sampling_rate,
double lower_f0,
double upper_f0,
double voicing_threshold)
: frame_shift_(frame_shift),
sampling_rate_(sampling_rate),
lower_f0_(lower_f0),
upper_f0_(upper_f0),
voicing_threshold_(voicing_threshold),
is_valid_(true) {
if (frame_shift_ <= 0 || sampling_rate_ / 2 <= upper_f0_ ||
(sampling_rate_ <= 6000.0 || 98000.0 < sampling_rate_) ||
(lower_f0_ <= 10.0 || upper_f0_ <= lower_f0_)) {
is_valid_ = false;
return;
}
}
bool PitchExtractionByHarvest::Get(
const std::vector<double>& waveform, std::vector<double>* f0,
std::vector<double>* epochs,
PitchExtractionInterface::Polarity* polarity) const {
// Check inputs.
if (!is_valid_ || waveform.empty()) {
return false;
}
if (NULL != f0) {
world::HarvestOption option;
world::InitializeHarvestOption(&option);
const double frame_period((1000.0 * frame_shift_) / sampling_rate_);
option.frame_period = frame_period;
option.f0_floor = lower_f0_;
option.f0_ceil = upper_f0_;
option.allowed_range = voicing_threshold_;
const int tmp_length(world::GetSamplesForHarvest(
static_cast<int>(sampling_rate_), static_cast<int>(waveform.size()),
frame_period));
std::vector<double> time_axis(tmp_length);
std::vector<double> tmp_f0(tmp_length);
world::Harvest(waveform.data(), static_cast<int>(waveform.size()),
static_cast<int>(sampling_rate_), &option, time_axis.data(),
tmp_f0.data());
const int target_length(static_cast<int>(
std::ceil(static_cast<double>(waveform.size()) / frame_shift_)));
if (target_length < tmp_length) {
tmp_f0.resize(target_length);
}
f0->resize(target_length);
std::copy(tmp_f0.begin(), tmp_f0.end(), f0->begin());
std::fill(f0->begin() + tmp_f0.size(), f0->end(), tmp_f0.back());
}
if (NULL != epochs) {
// nothing to do
}
if (NULL != polarity) {
// nothing to do
}
return true;
}
} // namespace sptk