Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
F0推定アルゴリズムHarvestは中で何をしているのか
Search
nagiss
September 25, 2023
Technology
3
1.2k
F0推定アルゴリズムHarvestは中で何をしているのか
DeNAの2023/5/24の音声トークの発表資料を焼き直したものです。
nagiss
September 25, 2023
Tweet
Share
More Decks by nagiss
See All by nagiss
F0推定の手法を色々試してみる
nagiss
1
380
音信号の電子透かし
nagiss
0
220
ヒューリスティックコンテストで機械学習しよう
nagiss
8
5.1k
XNNPACKを直接使ってみた
nagiss
0
530
SantaとAHCと遺伝的アルゴリズム
nagiss
8
3.6k
Kaggleシミュレーションコンペの動向
nagiss
1
980
Other Decks in Technology
See All in Technology
watsonx.ai Dojo #5 ファインチューニングとInstructLAB
oniak3ibm
PRO
0
170
普通のエンジニアがLaravelコアチームメンバーになるまで
avosalmon
0
110
終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024
yositosi
17
16k
Oracle Cloud Infrastructure:2024年12月度サービス・アップデート
oracle4engineer
PRO
0
210
KubeCon NA 2024 Recap: How to Move from Ingress to Gateway API with Minimal Hassle
ysakotch
0
210
事業貢献を考えるための技術改善の目標設計と改善実績 / Targeted design of technical improvements to consider business contribution and improvement performance
oomatomo
0
100
あの日俺達が夢見たサーバレスアーキテクチャ/the-serverless-architecture-we-dreamed-of
tomoki10
0
460
スタートアップで取り組んでいるAzureとMicrosoft 365のセキュリティ対策/How to Improve Azure and Microsoft 365 Security at Startup
yuj1osm
0
230
WACATE2024冬セッション資料(ユーザビリティ)
scarletplover
0
210
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
270
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
ハイテク休憩
sat
PRO
2
160
Featured
See All Featured
Embracing the Ebb and Flow
colly
84
4.5k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.1k
Gamification - CAS2011
davidbonilla
80
5.1k
KATA
mclloyd
29
14k
Six Lessons from altMBA
skipperchong
27
3.5k
Designing for Performance
lara
604
68k
Speed Design
sergeychernyshev
25
670
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.5k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Scaling GitHub
holman
458
140k
GraphQLとの向き合い方2022年版
quramy
44
13k
Transcript
© DeNA Co., Ltd. 1 nagiss ソリューション事業本部データ統括部AI技術開発部 株式会社ディー・エヌ・エー F0 推定アルゴリズム
Harvest は 中で何をしているのか
© DeNA Co., Ltd. 2 1 • Harvest のコードをある程度読み解いたので、せっかくなら公開しておこうと資料の形にしたもの ◦
隅々まで読み解こうとはしていないので所々「よくわからない」があります • 参考にしたもの ◦ 実装 https://github.com/mmorise/World/blob/master/src/harvest.cpp ◦ 森勢将雅, “高い雑音耐性と推定精度を両立する基本周波数推定法の提案と評価,” 信学技報, 2016 http://www.isc.meiji.ac.jp/~mmorise/lab/publication/paper/SP2016-62.pdf この資料は何?
© DeNA Co., Ltd. 3 2 • Harvest では内部的に 1ms
を 1 フレームとして扱っている。 ◦ 1ms 以外で出力する場合は最後に最近傍補間している。 • 例として JVS003 UT-PARAPHRASE-sent239-phrase2 を分析 人生は結局、孤独を和らげるために、生きているようなもんだ ◦ 下線部の 1 秒間 ◦ 「き」が無声化している 前置き 分析対象とした音声のスペクトログラム
© DeNA Co., Ltd. 4 3 コード概観 - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0
© DeNA Co., Ltd. 5 4 • 入力音声を帯域の異なるバンドパスフィルタに通して複 製し、それぞれを正弦波と見做してゼロ交叉・山と谷の 時間間隔により
F0 を求めることで、F0の候補とする。 ◦ 1 オクターブあたり 40ch、71Hz ~ 800Hz なら計 140ch の信号になる。 ◦ 求めた F0 がその帯域の中心から 10% 以上離れて いたら候補としない。 ◦ バンドパスフィルタは次スライド ▪ FFT を使って畳み込んでいるが、ちょっとずつやらないで入力 音声全体を FFT しているので計算量は線形時間より大きい、と はいえここが律速することはなさそう GetRawF0Candidates - Harvest - HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0
© DeNA Co., Ltd. 6 5 GetRawF0Candidates - バンドパスフィルタ cos
関数とナットール窓を掛け合わせて作られた線形位相バンドパスフィルタと、 その周波数応答 (ピークの周波数が 200Hz の場合) sr = 24000 freq = 200 # バンドパスフィルタのピーク周波数 period = sr // freq # 周期 n_fft = 1 << 16 win = np.zeros(n_fft) win[:4 * period] = scipy.signal.nuttall(4 * period) win[:4 * period] *= np.cos(np.linspace(0.0, 8.0 * np.pi, 4 * period)) plt.figure(figsize=(10, 4)) plt.plot(win[:4 * period]) plt.grid(color="gray") plt.show() f = np.fft.rfft(win) w = 20 * np.log10(np.abs(f)) w -= w.max() plt.figure(figsize=(10, 4)) plt.plot(np.arange(n_fft // 2 + 1) / n_fft * sr, w) plt.grid(color="gray") plt.xlabel("frequency [Hz]") plt.ylabel("[dB]") plt.xlim(0, 1000) plt.ylim(-120, 0) plt.show() 左の図の描画コード • 200Hz の cos 関数は周波数領域で 200 Hz にピークの立つデルタ関数になる • 長さ 4/200 秒のナットール窓は周波数領域でメインローブの半径が 200Hz になる • 時間領域の掛け算は周波数領域の畳み込みなので、上記の周波数応答が得られる
© DeNA Co., Ltd. 7 6 GetRawF0Candidates - 結果の例 得られた
F0 候補
© DeNA Co., Ltd. 8 7 • 帯域を横軸、得られた周波数を縦軸に取ったグラフを書 くと、いくつかの台ができる。 ◦
論文中の図 • 各台の周波数を平均をとることで 1 つにまとめてしま う。細い台は除去する。 DetectOfficialF0Candidates - Harvest - HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0
© DeNA Co., Ltd. 9 8 DetectOfficialF0Candidates - 結果の例 F0
候補
© DeNA Co., Ltd. 10 9 RefineF0Candidates - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • F0 候補を、瞬時周波数を求めることで再計算する。 • よくわからない方法で求めていた。 ◦ 窓関数をかけて DFT をすると複素スペクトルが得ら れるが、予め時間微分した窓関数をかけて DFT をす ると複素スペクトルの時間微分が得られ、この 2 回の DFT の結果から瞬時周波数を求めているらしい。 • F0 候補の信頼度もここでよくわからない式で求めてい た。 • とても重い ◦ F0 に対して適応的な (3 周期分の) 窓を使うので、毎 回窓関数を計算している ▪ 入力サンプリングレートが 8000Hz の倍数なら窓は 300 種類くらいになり そうなので、それを全部前計算するとかで高速化できるかも ◦ FFT が候補の数 * 2 回走る
© DeNA Co., Ltd. 11 10 RefineF0Candidates - 結果の例 精緻化された
F0 候補とその信頼度
© DeNA Co., Ltd. 12 11 RemoveUnreliableCandidates - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 前後どちらのフレームにも差が 5% 以内の F0 候補が無い ような F0 候補を削除する。
© DeNA Co., Ltd. 13 12 RemoveUnreliableCandidates - 結果の例 F0
候補とその信頼度
© DeNA Co., Ltd. 14 13 SearchF0Base - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 各フレームで最もスコアの高い F0 候補を抽出する。 • 注: F0 候補は後 (FixStep3) でまた使うことになる
© DeNA Co., Ltd. 15 14 SearchF0Base - 結果の例 各フレームで最も信頼度の高いF0
候補
© DeNA Co., Ltd. 16 15 FixStep1 - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 前フレームの F0 と前 2 フレームから線形予測した F0 の 両方から 0.8% 以上の差がある場合は F0 を 0 にする。
© DeNA Co., Ltd. 17 16 FixStep1 - 結果の例 F0
軌跡
© DeNA Co., Ltd. 18 17 FixStep2 - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除する - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 5 フレーム以下しか連続しない有声区間を削除する。
© DeNA Co., Ltd. 19 18 FixStep2 - 結果の例 F0
軌跡
© DeNA Co., Ltd. 20 19 FixStep3 - GetMultiChannelF0 -
Harvest - HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 有声区間ごとに分けて別の配列にする。 • 有声区間の個数が入力音声の長さに比例すると考えると、入力音声の長さの 2 乗に比例する大きさ のメモリを確保していることになる
© DeNA Co., Ltd. 21 20 FixStep3 - GetMultiChannelF0 -
結果の例 有声区間ごとに分けられた F0 軌跡
© DeNA Co., Ltd. 22 21 FixStep3 - Extend -
Harvest - HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 各有声区間を前後に伸ばす。 ◦ F0 が近いものを辿っている、多分 ◦ 自身との差が 18% より大きい F0 候補は無視して いる、多分
© DeNA Co., Ltd. 23 22 FixStep3 - Extend -
結果の例 伸ばされた F0 軌跡たち
© DeNA Co., Ltd. 24 23 FixStep3 - MergeF0 -
Harvest - HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 短い有声区間は削除し、各有声区間をマージする。 ◦ 削除の基準 … 波長の長さの 2.2 倍 ▪ 区間の平均が 100Hz なら 22 フレーム未 満、200Hz なら 11 フレーム未満で削除 • 区間が重なる場合には、重なった部分の信頼度の和が大 きい方を選ぶ。
© DeNA Co., Ltd. 25 24 FixStep3 - MergeF0 -
結果の例 マージされた F0 軌跡
© DeNA Co., Ltd. 26 25 FixStep4 - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • 短い無声区間を線形補間で埋める。
© DeNA Co., Ltd. 27 26 FixStep4 - 結果の例 F0
軌跡
© DeNA Co., Ltd. 28 27 SmoothF0Contour - Harvest -
HarvestGeneralBody - GetWaveformAndSpectrum ... 直流成分の除去、後の畳み込みのための FFT - GetWaveformAndSpectrumSub - HarvestGeneralBodySub - GetRawF0Candidates - (number_of_bands) GetF0CandidateFromRawEvent - GetFilteredSignal ... FFT でその帯域の BPF を畳み込む - (2) fft_execute - GetFourZeroCrossingIntervals ... ゼロ交叉/ピークの点を列挙、間隔から f0 を計算 - GetF0CandidateContour - (4) interp1 ... f0 を時間方向に補間 - GetF0CandidateContourSub ... 4 つの平均を計算、ばらけていたら 0 - DetectOfficialF0Candidates - (f0_length) DetectOfficialF0CandidatesSub1 ... 台を検出 - (f0_length) DetectOfficialF0CandidatesSub2 ... 各台の平均 f0 を計算、細い台は無視 - OverlapF0Candidates ... 前後 3 フレームに f0 候補をコピー - RefineF0Candidates ... f0 候補を瞬時周波数で修正 - (f0_length * num_candidates) GetRefinedF0 ... 窓長の計算、GetMeanF0 - GetMeanF0 - GetBaseIndex ... 窓をかける場所を求める - GetMainWindow ... 地味に重い - GetDiffWindow ... MainWindow の微分した窓を求める - GetSpectra ... 2 つの窓で FFT する、ここが重い - (2) fft_execute - FixF0 ... 瞬時周波数の計算 - RemoveUnreliableCandidates ... 前後どちらのフレームにも差が 5% 以内の f0 候補が無いような f0 候補を削除 - ((f0_length - 2) * number_of_candidates) RemoveUnreliableCandidatesSub ... 前後 1 フレームに対して SelectBestF0 - (2) SelectBestF0 ... 自身に最も近い f0 を得る - FixF0Contour - SearchF0Base ... 各フレームで最もスコアの高い f0 候補を抽出する - FixStep1 ... 前フレームの f0 と前2フレームから線形で予測した f0 の両方から 0.8% 以上の差がある場合は f0 を 0 にする - FixStep2 ... 5 フレーム以下しか連続しない有声区間を削除 - GetBoundaryList ... 有声部の閉区間のリストを作る - FixStep3 ... - GetBoundaryList - GetMultiChannelF0 ... 有声区間ごとに分けて別の配列にする - Extend ... 各有声区間を前後に伸ばす - (number_of_sections * 2) ExtendF0 - (distance + 1) SelectBestF0 ... 18% 以内の差なら採択する - ExtendSub ... 有声区間が十分な長さ (平均 100Hz なら 22 フレーム、200Hz なら 11 フレーム) ないものを削除 - MergeF0 ... 有声区間をマージする - MakeSortedOrder ... 有声区間たちを開始時刻の昇順にソート - MergeF0Sub ... 区間が重なる場合に、重なった部分のスコアの和が大きい方を選ぶ - (2) SearchScore - FixStep4 ... 短い無声区間を線形補間で埋める - GetBoundaryList - SmoothF0Contour ... F0 軌跡に LPF をかけて滑らかにする - GetBoundaryList - GetMultiChannelF0 ... 2 回目 - (number_of_boundaries) FilteringF0 • F0 軌跡に LPF をかけて滑らかにする。
© DeNA Co., Ltd. 29 28 最終的な結果の例 アルゴリズム全体を通して得られた F0 軌跡
© DeNA Co., Ltd. 30 29 スペクトログラムと重ねてみる スペクトログラムと F0 軌跡
© DeNA Co., Ltd. 31 こうして私たちの元へ届けられる——
© DeNA Co., Ltd. 32