0123456789
list icon
list icon

NTS-1 digital kit

SoundCloud

Share

[DOTEC-AUDIO x Nu:Tekt] NTS-1用カスタム・エフェクトの作成方法

logue-SDK カスタム・プラグインを作るのは難しそう? でもご安心を!
DOTEC-AUDIO様ご協力のもと、NTS-1用カスタム・エフェクトの作成方法を全5回の記事で完全解説いたします。

第1回 NTS-1で自作エフェクターを動かそう

皆様こんにちは。DOTEC-AUDIO(ドーテック・オーディオ)というプラグインメーカーの飯島進仁と申します。

普段はこのようなPCやiPhone、iPad向けのオーディオ・プラグインの開発・販売を行っています。
https://dotec-audio.com/

Nu:Tekt NTS-1 digital kit(以下NTS-1)は組み立て式のデジタルシンセサイザーという大変面白い製品なのですが、なぜ普段PC向けのプラグインを開発しているDOTEC-AUDIOがこのシンセサイザーに興味をもったのかといいますと、それは自分でプログラムを書いて開発した音色(オシレーター)やエフェクターをNTS-1にインストールできてしまうからなんです。

またNTS-1のもう一つ面白いところは「ステレオのAUDIO入力(ライン入力)も持っている」というところで、そこに音源や楽器を繋げればシンセサイザーだけでなく独立したコンパクトエフェクターとして機能してしまうんです。

つまり「自由にプログラム可能なシンセサイザー&コンパクトエフェクターが手に入ってしまう」というわけで、そう聞いてみたら是非チャレンジしてみよう、と思う方もいらっしゃるのではないでしょうか?

ということで早速ですがこちらの動画を御覧ください!

こちらは「ビットクラッシャー」と呼ばれる音の粒子を荒くするエフェクターです。

そして
こちらはヴァイナルストップという、レコード(ヴァイナル)を手で抑えて止めたようなエフェクターです。

どちらもDOTEC-AUDIOの製品である「DeeFX」というマルチエフェクターの機能の一部をNTS-1向けに移植したものです。
ご覧のようにNTS-1のオシレーターだけでなく、入力した音声にもエフェクトをかけられてしまうんですから面白いですよね!

さて今回の連載では、これら2つのエフェクターを題材にしてNTS-1のエフェクター開発についてご紹介していきたいと考えています。

本連載の中でこれらのエフェクターはソースコードも公開&解説予定ですが、まずはこれら2つのエフェクターをダウンロードしてNTS-1にインストールをするところを説明いたします。 NTS-1を既にお持ちの方は是非ダウンロードして実際に試してみてくださいね!

インストール手順

  • 1/ NTS-1 Sound Librarianのインストール

    まず NTS-1 Sound Librarian をPCにインストールします(Win/Mac) こちらを説明に従ってインストールしてNTS-1とPCのの接続を確認します。
  • 2/ エフェクターファイルのダウンロード

    次に今回DOTEC-AUDIOが開発したエフェクターファイルをダウンロードします。

    「Bitcrusher」のダウンロードはこちら
    「Stop FX」のダウンロードはこちら

    ファイルを解凍すると「bitcrusher.ntkdigunit」と「stopfx.ntkdigunit」というファイルが出てきます。
  • 3/ Sound Librarianで読み込む

    読み込み方はですが、メニューの「ファイル」の「ユーザー・ユニットのインポート」から解凍したファイルを選択してください。 すると「USER MODULATION FX」というカテゴリに「bitcrusher」というエフェクターが、そして「USER DELAY FX」というカテゴリに「stopfx」というエフェクターが追加されると思います。 あとは「送信・受信」の「ユーザー・データを書き込み」を選べばNTS-1にこれら2つのエフェクターが転送されます。

    無事転送されたら、NTS-1の「Mod」で「bitcrusher」、Delayとして「stopfx」が選択できるようになっていますので、是非遊んでみてください。
それでは次回をお楽しみに!

第2回 NTS-1のエフェクター開発をする準備をしよう

皆様こんにちは。DOTEC-AUDIO(ドーテック・オーディオ)の飯島です。

前回ではNTS-1のエフェクターを実際に作ったものを紹介しましたが、皆さま実際に触ってみて頂けたでしょうか? 今回は「NTS-1のオリジナルエフェクター(&オシレーター)を作るのに必要な開発環境」について解説したいと思います。
といっても基本的にすべてのことは「logue SDK」のページで説明されていますので、今回はその補足的なことを説明していきます。 なお今から説明するものはすべて無料です。 また、Windows、Mac、Linuxそれぞれの環境で開発が可能となっていますので、ほとんどの方が開発可能であることも魅力です。
(インストール手順はそれぞれ違うのでご注意ください)

logue SDK
https://korginc.github.io/logue-sdk/

まず「SDK」というものについてですが、これは「Software Development Kit」の略で、特定のソフトウェアを開発するのに必要なツールなどをセットにしたものです。 例えばWindowsアプリを開発するのにはWindows SDKが、iPhoneアプリを開発するにはiOS SDKというものを使って開発を行いますが、NTS-1に関してはこの「logue SDK」というものを利用して開発することになります。 https://github.com/korginc/logue-sdk

ここで公開されているのはそのlogue SDK本体です。 一番良いのは「Git(ギット)」というツールを使って最新版を取得することですが、Gitの使い方を理解する必要がありますので、上記のページにある「Clone or Download」という緑色のボタンからZIP形式でダウンロードする形でも構いません。 ただ、SDKもバージョンアップをすることがあり、常に最新版を取得しておきたい場合にはGitを使って取得するほうが得策です。

MSYS2 (Windows用)
https://www.msys2.org/

WindowsでNTS-1の開発環境を構築しようと思う際に一番の難関になると思われるのはおそらくこの「MSYS2」だと思われますので、そちらの解説をします。 まずlogue-SDKで使われるGNUのコマンド群はすべてUnixというOSでのコマンド実行を前提としています。そのためUnixそのものであるLinuxや、同じくUnixをベースとするmacOSの場合は最小限のツールのインストールで済むのですが、Windowsの場合はUnixのコマンドを実行するための追加の環境が必要になります。

MSYS2というのは、簡単に言ってしまえば「UnixのコマンドをWindows内で実行するためのプラットフォーム」です。 そのため、Windows & MSYS2で開発を行うためには「MSYS2」のウィンドウ内でコマンドを実行することになります。 「NTS-1 MSYS2」などでネット検索すると具体的な手順を解説されている記事などがヒットしますので是非参考にしてみてください。

GNU Arm Embedded Toolchain
https://github.com/korginc/logue-sdk/tree/master/tools/gcc

そしてプログラムを開発するには人間が書いたプログラムをコンピューターが読める機械語に変換するための「コンパイラー」というものが必要になりますが、logue SDKでは「GNUコンパイラコレクション(通称:GCC)」というものを利用します。 GCCについてはそれだけで分厚い本が1冊書けてしまうほど奥の深いものですので詳しい説明は割愛しますが、このページで説明されている「GNU Arm Embedded Toolchain」というのはそのGCCを含めたプログラミングツール群の名前です。 「Arm Embedded」と付いていますがこれはNTS-1で使っているCPUが「Arm系」と言われる「STM32F4」というチップですので、そのCPUで動くプログラムを開発するためのツールチェーンということになります。 インストールにつきましては、Readmeに記載の通り、用意されているシェルスクリプトを実行すればOKです。

GNU Make
https://github.com/korginc/logue-sdk/tree/master/tools/make

Makeとは「毎回たくさんのコマンドを実行してファイルをコンパイルしたりするの大変なので、それらを設定して1つのコマンドで実行するためのツール」というものです。 (Makeもまた本1冊になるほど奥の深いものです) Mac、Linux、Windows(& MSYS2)では特別追加でインストールする必要はありませんが、そうでない場合のみインストールする必要があることが説明されています。

Info-ZIP
https://github.com/korginc/logue-sdk/tree/master/tools/zip

これはZIPファイルを作成するためのツールですが、こちらもGNU Makeと同じくほとんどの環境では特別インストールする必要はありません。

logue-cli (任意)
https://github.com/korginc/logue-sdk/tree/master/tools/logue-cli

こちらは「任意」となっているとおり、全員が必要なものではありません。
前回ご説明した「Sound Librarian」というツールのコマンドライン版と考えていただければいいでしょう。 ただし、Windows版、Mac版はありますが、Linux版のSoound Librarianはないようですので、Linuxで開発をしようという方はこちらのツールが必要になると思います。

以上のツールが無事インストールできればSDKに含まれるサンプルコードをビルド(プログラムの作成)してみましょう。
https://korginc.github.io/logue-sdk/
の「デモプロジェクトのビルド (Waves)」にある手順でビルドを行います。 

無事これらのコマンドが実行できれば「waves.ntkdigunit」というファイルが出来ますので、これをまたSound Libarianで読み込めば「USER OSCILLATORS」に「waves」という名前で読み込まれるはずです。

ここまでくれば次は実際のプログラミングになりますが、無事動くまでは大変だとおもいます。
しかしながら幸いこれらのツールに関してネット上に情報はたくさんあふれていますので、是非ネット検索等を駆使して環境を作ってくださいね!

それでは次回をお楽しみに!

第3回 オリジナルエフェクターを作ろう その1

こんにちは、DOTEC-AUDIOでサウンドプロデューサーをしているフランク重虎です。
いよいよエフェクターを作っていきますので、今回からDSPの設計をしている僕が担当します。

さて前回までの開発環境は準備できましたでしょうか?
初めてコマンドラインを使ったよとかプログラム環境を作るよって方でも進められるように少しフォローしますね。

MSYS2はマウスではなく「cd フォルダ名」でフォルダを移動しますので、そのときに少し楽になる方法を教えます!
なが~いフォルダ名とかは初めのいくつかの文字をいれて「TAB」キーを押すと前方一致で自動入力してくれます。補完ですね。
そして今いるフォルダ内容の一覧を出したいときは「ls」とコマンドを入れてEnterすれば確認できます。
とりあえずフォルダを移動する「cd」一覧を出す「ls」を覚えておきましょう。
ちなみに一つ上に戻りたいときは「cd ..」とピリオドを二つ打ちましょう。
本当はUNIX上ではフォルダのことをディレクトリと呼ぶんですけど、WindosやMac上での操作もあるのでフォルダの方に統一して呼びます。と、断っておけば怒る人いないよな。。

あとMSYS2のユーザーホームにlogue SDKを入れちゃうと今後の作業が行いやすいですよ。
例:WindowsでCドライブ直下にMSYS2を入れた場合
C:\msys64\home\ユーザー名\korg

では本題。まずは こちらのファイルをダウンロードして
korg\v1.1\platform\nutekt-digital
の中に解凍してください。

Mod(モジュレーター)、Delay、Reverbエフェクトそれぞれを作る時のテンプ
レートが入ってます。
実はlogue SDKにもテンプレートは入っているのですが、今回の勉強が進めやすいようにシンプルにまとめてみました。慣れないとサンプルのフォルダ構成と混同しちゃったり、あれこれコピーに迷ってしまうと難しいですからね。

今回のテンプレートのフォルダ構造について

今回DOTEC-AUDIOで作成したテンプレートですが、それぞれ以下のような構造になっています。

・ld(フォルダ)
・tpl(フォルダ)
・main.c
・Makefile
・manifest.json
・projuect.mk

最初の「ld」フォルダは作るエフェクターの定義ファイルが置かれている場所です。
詳しい説明は割愛しますが、作るエフェクターがMod、Delay、Reverbでこのフォルダの中身が変わると覚えていてください。
「tpl」も同様に各種エフェクターのテンプレートとなるファイルが置かれているフォルダです。
「ld」も「tpl」も作りたいエフェクターの種類によって正しく選択する必要がありますが、皆さんが何か編集する必要はありません。

「Makefile」「manifest.json」「project.mk」はそれぞれ定義ファイルですが、自分が作りたいエフェクターに合わせて書き換える必要があるのは「manifest.json」と「project.mk」です。
この回の最後に編集箇所を解説しています。

そして「main.c」というのがエフェクターのプログラム本体です。

今回はデモにあるbitcrusherをつくります。このエフェクトはDeeFXにあるビットクラッシャーを勉強用にシンプルにしたものです。

何はともあれ先に完成形で遊んでみましょう。
bitcrusherのデモをダウンロードしてテンプレートと同じ場所
korg\v1.1\platform\nutekt-digital
の中に解凍してください。

MSYS2を使って
korg\v1.1\platform\nutekt-digital\bitcrusher
に入ります(移動します)、前述のTABキーをうまく使うと楽ですよ。
cdコマンドを使ってbitcrusherまで入ったら前回のようにmakeしてください。
覚えてますか?makeと打ってEnterキーです。
ズラズラ~と文字が流れて最後に

Packaging to ./bitcrusher.ntkdigunit

Done


と出れば成功です。buildフォルダとbitcrusher.ntkdigunitファイルができてますので、前回のようにNTS-1に転送してみましょう。ツマミAで強くかかります。

ではソースコードを解説していきます!
メモ帳でも秀丸でもなんでも良いですのでテキストエディターでbitcrusherフォルダ内のmain.cを開いてください。

  初めの

#include "usermodfx.h"
#include "float_math.h"


この1行目はmodfxを作る時に必ず必要です。続いて2行目は浮動小数点演算を行うときに必須となります。

デジタルの音声データは数の大きさを表すのに固定小数点と浮動小数点という二つの方法があります。このうち普段生活で見る「1.5倍に増量!」などと同じ使い方ができるのが浮動小数点です。人間が理解しやすいということですね。でもその反面で処理が重くなるという欠点があります。

固定小数点は処理が速いけど人間が理解しづらく、整数と少数の桁数を決める様々なフォーマット(Qフォーマット)があって取り扱いの難易度もあがります。

ですが喜んでください!NTS-1には浮動小数点を専門に扱うプロセッサも内蔵されているのです!
これを活用しない手は無いので、遠慮なく使います。

その次を見てみましょう。

static float rate, lastSampleL,lastSampleR;
static uint32_t count;


これは変数というデータが入る箱にラベルを貼って用意した状態です。
staticでfloat型のrate,lastSampleL,lastSampleRという3つの変数と、staticでuint32_t型のcountという変数を作ってます。
これを「(グローバル)変数の宣言」というのですが、プログラムの基本ですので
「C言語 変数 宣言」
などで調べておきましょう!staticの意味や型についてもわかります。
簡単には処理するたびに中身が消えたら困る変数は、staticをつけると保持されます。
他にも役割がありますが「static 静的な変数」を調べてみましょう。

  さて次は
void MODFX_INIT(uint32_t platform, uint32_t api)
{
 lastSampleL = 0.f;
 lastSampleR = 0.f;
 count = 0;
}

これは関数と呼ばれる一括りです。
プログラム処理を機能ごとに関数名というラベルを付けてまとめたもので、プログラムのあらゆる場所から関数名で呼び出して組み合わせ、連携した結果が一つのソフトウェアになります。自動車の各部品みたいなものです。

  戻り値 関数名(引数)
{
処理内容
}


のフォーマットで書かれます。戻り値というのは関数の処理結果をどのようなデータで呼び出し元に戻すか、引数は呼び出すときに関数に与えるデータと種類のことです。

 今回は初期化処理を書いてます。さきほど用意した変数の内容を0にリセットしているのですが、0.fのfって何?と思いますよね。これは単にfloat型の約束ですので調べてみましょう。
ちなみに戻り値のところのvoidですが、これは結果を何も戻さないという意味で初期化処理は初めの一回実行して終わりだからvoidとなっています。
投げっぱなし上等!

さぁ次はいよいよメイン処理ですが、ちょっと飛ばして先に一番下にある関数を解説します。

  void MODFX_PARAM(uint8_t index, int32_t value)
{
 const float valf = q31_to_f32(value);
  switch (index) {
  case k_user_modfx_param_time:
rate = valf;
break;
  default:
break;
  }
}


  うわー、いきなり難しい!
これは何をしてるかといえば、A,Bのツマミからデータを受け取って変数に入れてるんです。
ツマミを回すとNTS-1のシステムからこの関数が呼ばれます。呼ばれたときにツマミの種類indexとその値valueが引数としてもらえます。
さてこのvalueが先ほど出てきた固定小数点で入ってるので、まずはそれを浮動小数点に変換します。ここではQ31フォーマットの固定小数点を32bit浮動小数点に変換してvalfという変数に入れました。constはデータ内容を変えられたくないときに使いますが、詳しくは検索してみましょう。

  それをswitch case文という文法で処理します。簡単にはswitchで指定した変数がそれぞれのcaseだった場合の処理が並んでます。
今回はツマミAのデータのみ使いますので、k_user_modfx_param_time(ツマミAのindex名)のデータが来た時に変数rateにvalfの内容を入れてます。
このrateを使ってメイン処理をしますので、この関数を先に解説しました。

  つぎこそメインです。

  void MODFX_PROCESS(const float *main_xn, float *main_yn,
                const float *sub_xn,  float *sub_yn,
                uint32_t frames)


  MODFX_PROCESSという関数名で、もらえる引数は

メイン入力main_xn
メイン出力main_yn
オシレーターからのサブ入力 sub_xn
オシレーターからのサブ出力 sub_yn
総フレーム数 frames


の6つです。

  変数名についてる*はポインタの参照渡しというもので、この関数で中の値を変更したら呼び出し元の変数も変わることを示します。もらってるデータはコピーじゃなくて原本ですよって意味に近いです。参照渡し、値渡しで調べて勉強してみましょう!

  引数をみてピンと来たかもしれませんが、ようするにmain_xnにフレーム数だけ入ってるデータを色々とエフェクト処理をして、出力としてmain_ynに書き込めば良いんです。
今回サブ入出力は使いません。
その始まりとなるのが

   for(uint32_t i = 0; i < frames; i++){

  これは{}で囲った内容を指定した数だけ繰り返すという意味です。for文と言いましてこれでフレーム数だけ処理を繰り返します。

      //LとRの音を用意する
  const float inL = main_xn[i * 2];
  const float inR = main_xn[i * 2 + 1];


  初めの//はコメントといって、これをつけるとプログラムに影響なくメモを残せます。
さて入力main_xnですが、ステレオの音声(の粒)がLとR交互に入ってます。
それぞれ交互に処理をしても良いですが、わかりやすく毎回inLとinRという変数に入れなおします。
改めてmain_xnの構造を解説しますとLRLRLR…という並びでLRのセットがフレーム数だけ入っています。データ数としてはフレーム数の2倍入っています。配列変数で調べるとわかりますが複数のデータが入る変数を配列変数といいまして、そのデータ数を要素数と呼んでいます。main_xnの要素数はframesに書かれてるフレーム数の倍あるんですね。

  その要素の何番目というのを[]で指定します。ややこしいのが0から始まるのでmain_xn[0]だと1番目なんです。
それでこのfor文では1ループごとに1つ増える変数名iの値が、framesより小さい間だけループします。
iは0から始まりますのでframesより一つ小さい値で終われば回数としてはフレーム数と同じになります。
なんで1からはじめないの?!って思いますよね。その場合はframesと同じ数になったら終わりにすると思います。でも「同じ」ってチャンスとして1回なので、うっかりプログラムミスをして飛び越えちゃったら無限ループが始まっちゃいます。
そうなるとフリーズしちゃったり、その後の処理も0から始まるから便利だったりするんでしょ。それがまさに次の話。

  [i * 2]とか[i * 2 + 1]となってますね。LRが交互に入ってるので0番目はL、1番目はRが入ってます。iが0のときは[0 * 2][0 * 2 + 1]で0と1、iが1,2…と考えると、なるほど~。

  どや顔で解説させて頂いたあとはビットクラッシャーのタネあかし部分です。
先に仕組みを説明すれば、サンプリングデータは細かいほど音質が良くなりますので荒くします。荒くするとはサンプリングデータの更新頻度が低いとか段階(解像度)が大雑把になることです。今回は更新頻度をさげて、何回かに一回だけデータ出力を入れ替える作りにします。12345678と連続した入力データが11335577という感じになります。
これでサンプリングレートが落ちたような音になるのですが、それってビットクラッシャー(量子化を下げる)じゃねぇじゃん!と突っ込みが入るの、よーくわかります。
でもビット演算とかいきなり説明されても辛いですし、世の中でビットクラッシャーとされてる音ってビットを落とす地味な方でなくサンプリングレートを落とした派手な方なので、そっちの方が面白いと思いますので、このまま続けますよ!

    //大きくなるほどサンプルが粗くなる
  uint32_t skip = rate * 64;


  これは先ほどツマミから受け取ったデータを使うところです。やっとでてきた!
受け取ったデータは0~1の範囲で入ってるため、最大(1のとき)を64にしたい場合は64をかけます。
わかりやすいようにskipという変数に入れかえます。

    //countが0の時だけlastSampleを更新する
  if(count == 0){
lastSampleL = inL;
lastSampleR = inR;
  }


  ここの意味は先に進むとわかりますが、先に処理内容だけ解説します。
countという変数が0になった時だけ出力を保持する変数を更新します。つまり0以外はlastSmpleL/Rは前回の値のままです。
前述の初期化でcountは0から始まりますので、いきなりinL/Rの値に更新されます。

    //lastSampleの音を継続する
  main_yn[i * 2] = lastSampleL;
  main_yn[i * 2 + 1] = lastSampleR;
  count++;


入力をLとRに分けた時の逆で出力main_ynにLとRの音を書き込みます。つまりさっき入れたばかりのinL/Rと同じ音が書き込まれます。変化なし!
ところがその後にcount++というのがありまして、これはcountを一つ増やしてます。
つまり0から1になったんですね。この書き方はfor文のときもi++と書いて一周するごとにiを一つ増やしています。別の書き方をすれば count = count + 1 です。
1になったということは、次の周の頭でlastSampleL/Rが更新されません。同じサンプルデータを出力しつづけるのです。ではどこで0に戻るのか?!

    //skipを超えたらcountを0にリセット
  if(count > (int)skip) count = 0;


  はい、ここです。
さきほどツマミから貰って64倍した値をcountが超えたら0にリセットされます。
つまりはskipの数が大きいほどず~~っと同じデータを入力に関係なく出力しますので、サンプリングデータの更新頻度が低く落ちることになるわけです。
完成!

  あと最後の
 }
}

とあります。これが大事で上はfor文の終わり、下は関数の終わりを示します。基本的にいろんな処理を{}で囲みますので、内容が長くなるほど終わりの}を忘れたということが良くあります!たったこれだけでビルドは失敗しますのでよく気を付けてください。
またミスとして見つけにくいため、閉じ括弧一つで長時間悩み続ける話もよくあります。
もちろん僕も経験済みです!見つけた時にパソコンをぶん投げて頭で受けたくなりますね!

  今回のプログラムはModfxですのでテンプレートのtmpModを元に作ることができます。
是非main.cを見比べて何がどこに追加されているか調べてみてください。
skipのところに色んな値を入れてみて実験してみましょう!

  最後に作ったエフェクター名はmanifest.jsonのnameの項目、project.mkのPROJECTの項目にに記載しておきましょう。テキストエディターで編集できます。

  次回はStopFX
お楽しみに!
長文を読んで頂いてありがとうございました!

第4回 オリジナルエフェクターを作ろう その2

近日公開

第5回(最終回) ボコーダーを作ってみました

近日公開