Braidsは、フランスのMutable Instruments社がかつて販売していたユーロラックモジュールのデジタルシンセサイザです。今回、これをlogue SDKを使ってdrumlogueに移植してみました。名前は「Lillian」です。
Mutable Instruments社とBraids
Mutable Instrument社はÉmilie Gilletがほぼ個人で運営していた会社です。
私は今のところユーロラックには手を出していないのですが、その界隈では、同社も同社の製品もカリスマ的な人気があったようです。
Mutable Instrument社は、惜しまれつつ昨年会社としてはシャットダウンされましたが、それ以前から同社の製品のハード、ソフトはオープンソースでMITライセンスで公開されていました。そのため、製品を含めさまざまなプロダクトがここから派生しています。
ユーロラックのシミュレータであるVCV RackではMutable Instrumentsの多くのモジュールが無料で利用可能ですし、logue SDK関連では、Plaitsというモジュールのオシレータがlogue SDKに移植されています。
このPlaitsの前身(前バージョン)となるのが、今回drumlogueに移植したBraidsです。Braidsは単体で完結したシンセサイザというよりは、主にオシレータとしてユーロラックモジュールのシステムの中で使われるモジュールとなります。とはいえADタイプのエンベロープを内蔵していますので、CV/Gate入力をシーケンサ等に接続すれば、単音のシンセサイザとしても使えます。
Braidsの波形生成手法
Braidsはすべてソフトウェアで構成されており、40以上のシンセシスアルゴリズムがSTM32F103の128KBのフラッシュに実装されています。Mutable Instrumentsのすべてのハード・ソフトを開発しているÉmilie Gillet氏は大変勉強熱心な方のようで、信号処理関係の国際会議などのProceedingsを読み漁っていたそうですし、Googleで働いていたこともあったそうです(そのため、OSS文化にも慣れ親しんでいたようです)。
今回、移植の対象としてPlaitsではなくBraidsを選んだのはあまり深い理由は無いですが、あえて言えば見た目にアルゴリズムの数が多いこと(40以上vs.16、しかしPlaitsのアルゴリズムが少ないのは類似のアルゴリズムをまとめるなどして整理したためのようです)と、内蔵のエンベロープがADタイプ(PlaitsはDecayのみ)というあたりです。上にリンクしたインタビューを見ると、Émilie Gillet自身はBraidsはパラメータの整理が良くないと思ってPlaitsを開発したようですね。
アルゴリズムと言いましたが、実はBraidsのシンセシスは2段構えになっています。一段目は通常のバーチャルアナログオシレータ(鋸波や矩形波、三角波、ノイズなど)やデジタルオシレータ(FM音源、Karplus-Strong等の物理モデリング、ウエーブテーブル音源など)、それにデジタルフィルタなどです。二段目は、これらを1つ以上組み合わせて作った「マクロオシレータ」です。
マクロオシレータは、例えば鋸波を3つ重ねてデチューンするといった比較的簡単なものから、2つの波形をシンクさせる、リングモジュレーションさせる、フィルタをかける、といった比較的複雑な操作まで、さまざまな組み合わせがあります。いわばマクロオシレータがそれぞれ異なるシンセサイザのようなものです。なお、音色を変化させるパラメータは基本的にどのマクロオシレータも「ティンバー」と「カラー」の2つですが、音色に与える効果の統一性はありません。
複数のオシレータをただミックスするのではなく、あるアルゴリズムに基づいて組み合わせた音色が40種類以上用意されているのがBraidsということになります。ちなみにBraidsというのは編んだ髪、ないしは編み紐・組み紐というような意味で、それぞれの紐が基本のオシレータという見立てでしょうか。
なお、Lillianの名は日本の組紐を作る玩具「リリヤン」からの連想です。もっとも、リリヤンの由来はユリの花で、玩具の形状がユリの花の花芯に似ているからこの名になったと思われるので、名称と組紐とのつながりは直接にはありません。
Braidsの移植
Braidsはもともと専用のハードウェアとセットで開発されてはいますが、ハードウェア依存部分はきれいに切り分けられています。そのため、移植はそれほど難しくはありません。
下図はソフトウェアの大まかな構成を示したものです。(低レイヤは除いています。)
メインはbraids.ccです。内部の計算はサンプリングレート96KHzで、一度に24サンプルずつデータを計算するようになっています。braids.ccから下位のmacro_oscillator.ccを呼び出して、この計算をタイマ割込で定期的に実行するような構成です。
マクロオシレータはアナログオシレータやデジタルオシレータをいくつか組み合わせて作られています。音源生成時に用いる各種テーブル類はresources.ccに集められています。また、ADタイプのエンベロープが1つ用意されています。
移植は、主にbraids.ccの内容をlogue SDK向けに焼き直します。その下位のオシレータのコードには手を入れる必要は全くありません。ただし、drumlogueのサンプリングレートは48KHzなので、デフォルトでは96KHz用になっているresources.ccの内容は修正する必要があります。resource.ccは波形テーブルなどを含んでいますが、Pythonスクリプトで生成されているので、このスクリプトのサンプリングレートを修正して実行します。
また、コードの一部に、サンプルを24個ずつ生成することを前提としている部分(サンプリングレートを下げて音を汚す処理)がありますが、drumlogueでは24サンプルずつの生成ではないので、移植の際には対応が必要です。
図右のユーザインタフェース関連はハードウェアへの依存が高めですが、パラメータの値域などの情報はここから読み取ることができます。
図左のquantizer、jitter、signatureは、外部からのピッチCVを各種スケールの周波数にクオンタイズしたり、オシレータに外乱を与えたり、MPUの固有IDから求めた変換関数で波形を歪ませたりするためのオプション機能ですが、今回は一応移植はしてみたものの、drumlogueで利用できるパラメータ数の制限から、利用していません。
なお、オリジナルのBraidsはFPUが無いSTM32F103が使われているため、演算には固定小数点演算が駆使されています。後継のPlaitsはハードウェアはSTM32F373でFPUが搭載されているので、演算も浮動小数点演算になっています。
Braidsにない機能の追加
Drumlogueへの移植にあたっては、Braidsには無い機能として2つのエンベロープを追加しました。Braidsはユーロラックモジュールで、他のモジュールと組み合わせることができます。しかしdrumlogueではシンセユニットの外部にあるのはエフェクトとシーケンサーだけで、LFOやフィルタやエンベロープはありません。
Braidsの一つの大きな魅力は、よくあるバーチャルアナログシンセ、つまり鋸波や矩形波+ローカルフィルタ+エンベロープという構成とは違った形の音色変化が得られるところだと思います。そのため、
・フィルタは使わず、オシレータのパラメータを使った音色変化を楽しめるようにする
・複数のパラメータに複雑な時間変化を与えられるようにする
・なるべくモジュラーシンセ的な自由度を与える
といった方向で開発することにしました。
Braidsのパラメータはいろいろあって、マクロオシレータの選択自体も外部からの信号で操作できたりするのですが、今回の移植ではdrumlogueが使えるパラメータ数の制約もあり、エンベロープで揺らす効果が高いと思われる4つのパラメータ(音量、ピッチ、ティンバー、カラー)だけを操作対象にしました。それ以外のパラメータは、シーケンサーのモーションシーケンス機能を使えば値をいじることは可能です。
BraidsにはADエンベロープが1つ内蔵されていますが、これだとあまり複雑な変化は出せません。そのため、このエンベロープを拡張し、かつ個数をもう1つ追加しました。
エンベロープのカーブはリニアからEXPまで可変とし、2つのエンベロープの信号から加算や乗算などの演算を行って得られる信号もエンベロープの一種として使えるようにしました。
また、エンベロープをトリガする信号として、ゲートオン・ゲートオフ・アタックフェーズ終了・ディケイフェーズ終了の中から選べるようにしました。ディケイフェーズ終了をトリガ信号にすると、エンベロープは繰り返しトリガされるのでLFOになります。(このエンベロープ周辺は実はVolca Modularのエンベロープやユーティリティモジュールから着想しています。)
感想など
とにかくコードが勉強になりますね。ハード依存部分の切り分けや全体的な設計など、組み込みだとついついごちゃごちゃしがちなのですが、このコードは綺麗です。音源部分の実装はホスト上で動作を確認しながら進めているそうです。
今回はあまり踏み込みませんでしたが、braidsのコードは様々なアルゴリズムの実装が含まれていて、かつ読みやすいので、ソフトウェアシンセサイザの実装を勉強するのにも良さそうです。(ちなみにちょっとしたバグを見つけたので報告しました。)
コメント