LoginSignup
27
22

More than 5 years have passed since last update.

TidalCyclesとSuperColliderの連携 - 改訂版

Posted at

TidalCycles 0.8からは、SuperColliderをベースにしたSuperDirtが標準の音響生成エンジンとなりました。そのため、以前は少し面倒だったSuperColliderで独自に作成した楽器(Synth)との連携が簡単になりました。

以下のチュートリアルは、SuperDirtのGithubリポジトリ内にあるチュートリアルをベースにしています。

セットアップ

以降のサンプルを動かすには、TidalCycles 0.8のセットアップが完了している必要があります。セットアップの手順は下記を参照してください。

基本 - 440Hzのサイン波

まず、シンプルなサンプルを作成してみましょう。440Hzのサイン波を生成するシンプルな楽器を定義します。

SynthDef("testsynth", {
    arg out;
    var sound = SinOsc.ar(440.0);
    OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, 0.5));
}).add;

これを、Tidalから演奏するには、SuperDirtを起動した状態で以下のように呼び出します。

d1 $ sound "testsynth"

「sound」省略して「s」だけでも大丈夫です。

d1 $ s "testsynth"

Tidal向けに定義されたSynthdefの特徴として、最終出力で、Out.ar(...) ではなく OffsetOut.ar(...) を使用していることに気付きます。これは、Tidalで複雑なリズムを生成する際に、できるだけ正確なタイミングでトリガーされるための工夫です。また、最終出力で、DirtPan.ar(...) を使用しています。これは、Tidalで設定したPanの指定を反映するためのものです。ただし、現状ではまだ反映されていません。また、現在の状態では音がずっと持続してしまい、リズムの切れ目が不明確です。

定位(Pan)と持続時間(Sustain)を設定

もう少し改良して、定位(pan)と音の持続時間(sustain)を設定できるようにしてみましょう。以下のようにSynthdefを修正します。

SynthDef("testsynth", {
    arg out, sustain=1, pan;
    var env = EnvGen.ar(Env.linen(0.01, 0.98, 0.01, 1,-3), timeScale:sustain, doneAction:2);
    var sound = SinOsc.ar(440.0);
    OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan, env));
}).add;

引数に、sustainとpanが追加されました。設定したsustainの値でエンベロープを生成しています。またpanの値をDirtPan.ar()に指定しています。

では、以下のようにTidalから演奏してみましょう。

d1 $ s "testsynth*2" # sustain "0.2" # pan "0 1"

左右交互に、0.2秒の長さで音が鳴るようになりました。

音程を設定

次に音程を指定できるようにしましょう。以下のように修正します。

SynthDef("testsynth", {
    arg out, sustain=1, pan, accelerate, freq;
    var env = EnvGen.ar(Env.linen(0.01, 0.98, 0.01, 1, -3), timeScale:sustain, doneAction:2);
    var sound = SinOsc.ar(freq * Line.kr(1,1+accelerate, sustain));
    OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan, env));
}).add;

Tidalからは、「n (またはnote)」という指定で音程を設定できます。nが9の時、A5(ピアノの中心のラ)の音程になります。例えば以下のようにして音程を指定します。

d1 $ s "testsynth*2" # sustain "0.2" # pan "0 1" # n "9 21"

エンベロープを変更

エンベロープのカーブを調整することで、音の表情が変化します。例えば、よりパーカッシブなエンベロープに変更してみましょう。

SynthDef("testsynth", {
    arg out, sustain=1, pan, accelerate, freq;
    var env = EnvGen.ar(Env.perc(0.001, 0.999, 1, -4), timeScale:sustain, doneAction:2);
    var sound = SinOsc.ar(freq * Line.kr(1,1+accelerate, sustain));
    OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan, env));
}).add;

持続時間を調整します。

d1 $ s "testsynth*2" # sustain "0.5" # pan "0 1" # note "9  21"

応用

あとは、SuperColliderの様々なUGens(ユニットジェネレイター)を使用して複雑な音を生成していくことが可能です。例えば、Roland TR-808風のバスドラム。

SynthDef("super808", {
    arg out, speed=1, sustain=1, pan, voice=0, n;
    var env, sound, freq;
    n = ((n>0)*n) + ((n<1)*3);
    freq = (n*10).midicps;
    env = EnvGen.ar(Env.linen(0.01, 0, 1, 1, -3), timeScale:sustain, doneAction:2);
    sound = LPF.ar(SinOscFB.ar(XLine.ar(100*freq, freq, 0.025/speed), voice), 9000);
    OffsetOut.ar(out, DirtPan.ar(sound, ~dirt.numChannels, pan, env))
}).add;

これを、Tidalから演奏します。

d1 $ s "super808*8" # sustain "0.5" # pan "1 0.5 0" # gain "1 0.5 0.75 0 1"

さらに、先程の"testsynth"と同時に鳴らしてみましょう。

d1
$ stack[
s "super808*8" # sustain "0.5" # pan "1 0.5 0" # gain "1 0.5 0.75 0 1",
s "testsynth*8" # sustain "0.25" # pan "0 0.7 0.3 0.5 1" # note "52 40 47" # gain "1 0.5 0.8 1"
]

さらに、juxや、gapなどで操作してみます。

d1
$ jux (iter 8)
$ every 4 (gap 16)  
$ stack[
s "super808*8" # sustain "0.5" # pan "1 0.5 0" # gain "1 0.5 0.75 0 1",
s "testsynth*8" # sustain "0.25" # pan "0 0.7 0.3 0.5 1" # note "52 40 47" # gain "1 0.5 0.8 1"
]

徐々に複雑なリズムが生成されるようになりました。様々な工夫でオリジナルな表現が可能となりそうです!

27
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
22