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.3k
F0推定アルゴリズムHarvestは中で何をしているのか
DeNAの2023/5/24の音声トークの発表資料を焼き直したものです。
nagiss
September 25, 2023
Tweet
Share
More Decks by nagiss
See All by nagiss
F0推定の手法を色々試してみる
nagiss
1
500
音信号の電子透かし
nagiss
0
280
ヒューリスティックコンテストで機械学習しよう
nagiss
9
5.3k
XNNPACKを直接使ってみた
nagiss
0
590
SantaとAHCと遺伝的アルゴリズム
nagiss
8
3.7k
Kaggleシミュレーションコンペの動向
nagiss
2
1.1k
Other Decks in Technology
See All in Technology
Raycast AI APIを使ってちょっと便利な拡張機能を作ってみた / created-a-handy-extension-using-the-raycast-ai-api
kawamataryo
0
150
N=1から解き明かすAWS ソリューションアーキテクトの魅力
kiiwami
0
130
Moved to https://speakerdeck.com/toshihue/presales-engineer-career-bridging-tech-biz-ja
toshihue
2
830
クラウドサービス事業者におけるOSS
tagomoris
3
940
2024.02.19 W&B AIエージェントLT会 / AIエージェントが業務を代行するための計画と実行 / Algomatic 宮脇
smiyawaki0820
14
4k
データマネジメントのトレードオフに立ち向かう
ikkimiyazaki
6
1.1k
データ資産をシームレスに伝達するためのイベント駆動型アーキテクチャ
kakehashi
PRO
2
600
白金鉱業Meetup Vol.17_あるデータサイエンティストのデータマネジメントとの向き合い方
brainpadpr
7
890
利用終了したドメイン名の最強終活〜観測環境を育てて、分析・供養している件〜 / The Ultimate End-of-Life Preparation for Discontinued Domain Names
nttcom
2
300
The Future of SEO: The Impact of AI on Search
badams
0
240
君も受託系GISエンジニアにならないか
sudataka
2
450
RSNA2024振り返り
nanachi
0
610
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
10
1.3k
KATA
mclloyd
29
14k
Facilitating Awesome Meetings
lara
52
6.2k
Building a Scalable Design System with Sketch
lauravandoore
461
33k
The Cult of Friendly URLs
andyhume
78
6.2k
Being A Developer After 40
akosma
89
590k
Bootstrapping a Software Product
garrettdimon
PRO
306
110k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
Making the Leap to Tech Lead
cromwellryan
133
9.1k
How to train your dragon (web standard)
notwaldorf
91
5.8k
Speed Design
sergeychernyshev
27
800
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