はじめに
提案している周期性解析を応用したピッチ検出手法を開発してきたのですが、時系列の考慮をしない解析方法で解析を行ってきました。
しかし、ピッチ検出は、pYINに代表されるように、時系列の確率を用いて精度を上げる事が一般的に行われています。
勉強がてら、提案手法に確率論を適用して、出力結果を安定させるため検討を行いました。
提案手法では、周期性解析スコアを算出し、そのピーク位置から基本周波数を推定しています。従来は各フレームを独立に処理していましたが、今回はフレーム間の連続性を考慮した推定を導入します。
ピッチ検出そのものは pYIN などの成熟した手法が存在しますが、提案している周期性解析との組み合わせがどの程度有効か確認したくなり検討を行いました。
また、スパイク状のノイズに対しては、強いピッチ検出となっているので、利点はちゃんとあるので、そこはご留意ください。
課題
周期性解析のスコア自体は比較的安定しており、少なくとも私が確認した範囲ではYINより滑らかに見えるケースもありました。しかし、YINをpYINにした手法をそのまま使うとうまくピッチ検出ができませんでした。
オクターブ違いの場所に遷移してしまう事が多くなります。そこがメインの課題です。
アルゴリズムでは、主に、
- 周期性解析のスコアを確率分布に変換
- 確率分布からピッチ追跡アルゴリズムを用いて追跡
を行うのですが、どちらにオクターブ違いのミスがあるのか特定する事が、難しい作業となりました。
また、ギターの楽器と歌声を同じパラメータで両方正確なピッチを取得する事も課題です。音色が違うため、倍音成分に違いが出るため、同じパラメータでのピッチ検出が難しくなります。
この点については今回十分に解決できておらず、今後の課題となっています。
原因の特定
ピッチ検出に失敗した箇所を分析したところ、周期性解析スコア自体は正しい周波数付近でピークを持っていることが多く、問題は確率分布変換や時系列追跡側にあることが分かりました。
周期性解析スコアの確率分布変換についての注意点
周期性解析スコアは、周期が0での値をピークとして、周期が短い所の値が、高いので、最初の谷までは、確率を0として、そのほかをそのまま総和で割った値を採用しました。
この処理を行わないと、必ず一番高い周波数の確率が高くなってしまいます。
ピッチ追跡アルゴリズムについて
下記の2パターンの追跡方法を試しています
- ベイズ的な推定(オンライン推定用)
周期性解析から得られる尤度分布と、前フレームから予測される周波数分布をベイズ更新によって統合し、周波数を推定します。逐次的に処理できるためリアルタイム処理に適しており、一時的な誤検出に対しても安定した追跡が可能です。
- Viterbi(オフライン推定用)
各フレームで得られた尤度分布を用いて、音声全体で最も尤もらしい周波数遷移経路を探索します。全フレームの情報を利用するため、単純なフレーム毎の推定よりも滑らかで一貫した周波数系列を得ることができますが、音声全体が必要となるためオフライン処理向けの手法です。
Viterbiについてはまだ理解が浅い部分もあり、今後さらに検証していきたいと考えています。
どちらの手法も状態遷移行列を用いて周波数候補間の遷移確率を定義し、そのスコアを用いて推定を行っています。
状態遷移をガウス関数で定義しているのですが、状態移動がうまくいっていなかったので、状態移動の関数を人の耳になじみがある、距離を$log2$のスケールに変更して実装しています。
状態遷移の距離は周波数差ではなく、音高差を考慮するため対数周波数空間で定義しました。
$$
d = |\log_2(f_1/f_2)|
$$
※追加説明です。計算しているのは、時間領域の計算なので、$-log2(T_1/T_2)$となり、絶対値をとると同じ計算となります。
これによりオクターブ差を自然に扱えるようになります。
なお、オンライン推定、オフライン推定とあるように、ベイズ的な推定は、リアルタイム処理用で、Viterbiは後処理用のアルゴリズムとして開発しています。
ピッチ検出アルゴリズムに入れた工夫
現状の尤度関数と過去の尤度関数どちらを優先して判断するか、パラメータを設けることにしました。
現在フレームの尤度と過去フレームからの予測の重みを調整できるようにしたところ、オクターブ誤りが減少し、ピッチ追跡が安定することが分かりました。
ベイズ的な推定方法(オンライン推定)では、アドバンスドな課題である、楽器の音と歌声の両方を同じパラメータで処理する事は、難しいですが、パラメータ調整をすれば、どちらもある程度対応できそうなくらいになりました。
Viterbi(オフライン推定)では、高周波域を候補として残していれば、同じパラメータで歌声、楽器の音ともに推定できる事が確認できました。
楽器での結果
この例ではViterbiの方がオクターブ誤りが少なく、滑らかな推定結果が得られました。
※bayesでオクターブズレが出ていますが、パラメータを調節すると発生しません。(パラメータ導入前の画像を貼ってしまいました。)
結果
- ベイズ推定では歌声と楽器でパラメータ調整が必要
- Viterbiでは同一パラメータでも比較的安定
- 問題の原因は周期性解析スコアではなく追跡処理側にあった
おわりに
今後は無声音判定や評価データセットによる定量評価を進めていきたいと思います。
また、ベイズ推定とViterbiの実装整理ができた段階でリポジトリへの反映も検討しています。
今回試したベイズ推定およびViterbiについては、まだ整理段階のためリポジトリには反映していません。
現在は基本的な周期性解析ベースのピッチ検出のみ実装しています。
今回の紹介した処理の実装を公開しています。
興味のある方はリポジトリをご覧ください。
