ボコーダーを作ってみる(1)

この週末は少し時間が取れたので、気晴らしに少しコードを書いてみました。実は、このところ仕事もプライベートも多忙で、疲労回復の必要もあり、あまり課外活動ができない状態になっています。

今回作ってみたのは、NTS-1 mkII用のボコーダーです。YMOの「トキオ・・・トキオ・・・」で有名な、例のロボットボイスを出すやつですね。


まずはNTS-1 mkIIで動作させていますが、実は以前のKaoss Padシリーズにはあったボコーダーが、NTS-3には無いのでちょっと気になっていました。
ですので、いずれNTS-3にも移植してリリースしようと思っていますが、今回は途中経過報告です。来週はまた時間が取れない可能性が高いので・・・

ボコーダーの原理を下図に示します。図の下半分にFilter1からFilter Nまで並んでいますが、その1つを取り出したものが、図の上半分のブロック図になります。

入力はキャリアとモジュレータで、通常は声をモジュレータ、シンセの音をキャリアに入力します。

2つの入力はそれぞれ同じ設定のバンドパスフィルタ(BPF)に送られます。

モジュレータのBPFの出力はエンベロープフォロワに送られます。エンベロープフォロワはVCAの逆の処理を行います。つまり、音声信号からエンベロープ値を出力します。

そのエンベロープ値で、キャリア側のBPFの出力の音量をコントロールします。すると、モジュレータの音量でキャリアの音量をコントロールできるわけです。

で、これを図の下半分のように並列にたくさん(10~20個)並べます。BPFの周波数はそれぞれ変えて、全体でモジュレータの周波数領域をカバーできるようにします。

最後にこれらの出力をミックスすれば、下図のようにモジュレータの周波数分布(緑)でキャリアの信号(青)の周波数分布を変調した信号(赤)が得られます。

人の声、特に「アイウエオ」のような母音には、フォルマントといって特徴的な周波数分布がありますが、ボコーダーはこの周波数分布をBPFとエンベロープフォロワで抽出し、それを使ってキャリアの音にフィルタをかけることで、シンセサイザで声のような音を出しているわけです。

上記の方式はチャンネルボコーダーとも呼ばれるフィルターをたくさん使う(フィルターバンク)方式ですが、他にもLPC(linear predictive coding)という手法でモジュレータの信号の周波数分布を直接求めて、それをキャリアの信号に適用する方式もあります。

以下は、ChatGPTに書いてもらったPython版のフィルターバンク式ボコーダーです。carrier.wavとmodulator.wavという二つのWAVファイルを置いて実行すると、ボコーダーをかけた音声がoutput.wavに出力されます。

上のコードは、モジュレータ信号を通すBPFを5つの周波数帯に分けています(「# フィルターバンクの設定」とある部分)。これだとちょっとフィルタの数が少なくて、もっと増やせばそれだけ音質が向上しますが、その分、計算負荷も高くなります。

とはいえ、今回試しに作ったNTS-1 mkII版は16バンドにしていますが、コーラス、ディレイ、リバーブをかけても特に問題ありませんでした。16バンドくらいならNTS-1 mkII/NTS-3の処理能力の範囲内のようです。

今日はここまでです。logue SDK版は、まだ試作段階ですので、もう少しコードやUIを整理したらリリースしたいと思います。

コメント