KORG NTS-1 digital kit mkII で Rust のカスタムオシレータ制作

KORG の組み立てシンセキットである NTS-1 digital kit mkII は、C/C++ の SDK が公開されており、自分でプログラミングしたオシレータやエフェクタを本体に転送して動作させられる、とても面白いシンセサイザーです。

NTS-1 digital kit mkII – PROGRAMMABLE SYNTHESIZER KIT | KORG (Japan)

作って、繋いで、触って、手のひらサイズの強力なシンセサイザーが帰ってきた !! 進化したカスタマイズにより解き放たれるパワー

かねてより、API が公開されていてカスタムソフトシンセが発音できるハードウェアが欲しいなと考えていましたので、購入して遊んでみました。

PC との接続

本機には USB-C ポートがあり、PC からは MIDI IN/OUT デバイスとして見えます。

ユーティリティとして提供されている KORG KONTROL でカスタムオシレータやエフェクタの転送が MIDI SysEx 経由で行えます。

なお、Windows 接続で他に多くの MIDI 機器が接続されている環境では、KORG MIDI ドライバーが上位の方にいないと、ファームウェアアップデートや KORG KONTROL から本機を認識できないと思われる事象がうちの環境ではありました。(いったん他の MIDI ポートドライバを削除して入れ替えるなどしていたら修正されました)

また、公式の SDK (louge-sdk) で提供されているコマンドライン版の louge-cli は本機には未対応のようです。もしサウンドユニットの開発でコマンドライン転送が使いたい場合は、Python によるオープンソース実装の py-logue-tools を使わせていただくと便利です。

https://github.com/TarkanAl-Kazily/py-logue-tools

Implements a basic python-based MIDI librarian for the Korg NTS-1 Mk2 and similar family of Korg logue-sdk devices. This project is not affiliated with Korg.

サウンドユニットの開発

前述の louge-sdk の README 通りに環境設定し、API に従い C/C++ プログラミングして、できたサウンドユニットを USB-C 経由で転送して試す、というワークフローでうまくいくと思います。

ファームウェアの Ver1.2 未満であると API にいくつか不具合がありますのでアップデートしてからの開発がお勧めです。

本機のサウンドユニットの特徴としては、バイナリに ELF 形式を採用していて USB-C 転送後にダイナミックにユニットをロードしていることです。また、おそらく API のシステムコール先は Arm7 の短縮命令(Thumb)が用いられています。

このことから、普通に SDK でプログラミングしている分には遭遇しないかとは思いますが、いくつかのトラブルシューティングがありますので、ここに列挙しておきます。

音源 Import 時に KORG KONTROL が「ELF が間違っています」エラーでサウンドユニットを受け付けてくれない:

  • ELF バイナリから動的リンクをするダイナミックリンクテーブル rel.ptl エントリに、NTS-1 以外のシステムコールが入っている。
  • SDK の sysroot に入っていない関数がリンクされるとこの状態になります。Linux などに含まれる readelf -a コマンドで中を確認して呼び出しをなんとか解決してあげます。
  • また、ELF ヘッダーの先頭のマジックフラグも KORG KONTROL がバリデートしているようです。

音源 Import から転送までうまくいくもののサウンドユニットが認識されない:

  • 正常に初期化できないユニットは無効にされるようです。KORG KONTROL の状態と不一致して、その後の処理もおかしくなるようなので、いったん本機も KORG CONTROL もリセットしましょう。
  • なお本機のリセットは DELAY ボタンを押しながら電源投入です。(その後の操作はマニュアル参照のこと)
  • header.c で定義する unit_header 値がおかしい。例えば設定パラメータ数 num_params: 2, 項目を 2未満にすると無効になるようです。
  • 転送直後のサウンドウニットの初期化がうまくいかないことがある?
    いったん別ユニットを選択して、自分のユニットに再度設定すると初期化コードが走ったような経験があります。(気のせいかもです)

Rust によるサウンドユニットの制作

C/C++ でかけばいいのですが、完全に趣味、勉強もかねて Rust でつくってみました。リンカー部分でいろいろはまって時間がかかりましたが、以下のリポジトリにビルド手順やソースコードとサウンドユニットのバイナリを配置しています。

https://github.com/h1romas4/nts1mkii-rust-wave

This repository is a Rust ported build of the WAVES(osc) synthesizer for the NTS-1 digital kit mkII included in logue-sdk. If you are interested in creating an NTS-1 Digital Kit mkII sound source in Rust, perhaps this repository may be of some use to you.

README には新しいユニットの追加方法や、はまった部分をメモしてありますので、気になる方はご覧ください。

SDK のサンプルで入っている Waves オシレータをフィルター部分を除いて移植したものと、試しにつくってみた 32byte * 32 音色の波形メモリーオシレータを入れています。

プログラムは C/C++ SDK が提供する関数を bindgen でバインドする方式をとって動作しています。

SDK がインライン展開指定の関数が多いため、Rust 版は速度的、バイナリサイズ的にも若干不利になっており、また no_std 環境で unsafe コード多数で、Rust である意味あるかと言われると現状そうでなさそうな気もしますがw、いったん動くことの勇気として。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です