Tidalでライブコーディング! - 応用編 : SuperColliderとの連携

**注意!! : TidalCycles 0.8からSuperDirtが標準となり、SuperColliderとの連携も大幅に簡略化されました。新しいバージョンでの連携方法は下記を参照してください。**

- [TidalCyclesとSuperColliderの連携 - 改訂版](http://qiita.com/yoppa/items/261755e7f82d3387251f)

前回の「[Tidalでライブコーディング! - 実践編](http://qiita.com/yoppa/items/5f1f9a033f1273e33242)」に引き続いて、応用編です。

Tidalは、基本は[Dirt](https://github.com/tidalcycles/Dirt)というサンプルファイルを再生する専用のプログラムでサンプルを再生しています。しかし、TidalにはOSC (Open Sound Control) を送出する機能があります。このOSC機能を利用することで、SuperColliderやMax/MSP、Pdなど様々な外部の音源を使用してTidalで作成したパターンを再生することが可能です。

今回は、TidalをSuperColliderを連携してみます。

# 基本: 簡単なサンプル

まずは簡単なサンプルで試してみます。Sin波を生成する楽器をSuperCollider側に作成します。

```cpp
(
//単純な楽器の定義
SynthDef("scsine", {
    arg freq;
    var out, env;
    out = SinOsc.ar(freq).dup();
    env = EnvGen.ar(Env.perc(), doneAction:2);
    Out.ar(0, out*env);
}).add;
);
```

ここで1つ注意すべき点は、Tidalから演奏する楽器は一度鳴らし始めると自動的に停止することはありません。ですので、あらかじめエンベロープを設定しておき、一定の時間で音が終了するよう、doneAction:2を設定したエンベロープを適用しておく必要があります。

SynthDefの作成が完了したら、SuperColliderをBootして、作成したSynthDefを実行しておきます。

これに対応するTidal側のプログラムを作成します。まず、SuperColliderで作成した楽器と連携する準備をします。まず楽器 "scsine" を定義して、引数の初期値を設定しています。その上で、SuperColliderに渡すTidal側の変数を定義します。

```hs
-- 楽器 "scsine" を定義して、引数の初期値を設定
(sc, shape) <- scStream "scsine" [ F "freq" (Just 440.0)] 0

-- SuperColliderに値を渡す変数を定義
let freq = makeF shape "freq"
```

あとは、変数を使用してパターンを作成していきます。

```hs
-- パターン生成
sc $ freq "440 660 110 220"

sc $ freq "440 [660 110] [220 880] 330"

sc $ jux(iter 8) $ freq "440 [660 110] [220 880] 330"

sc $ jux(iter 8) $ jux (iter 4) $ freq "440 [660 110] [220 880] 330"

sc silence
```

# 応用: 2つの楽器を定義して演奏

少し複雑なサンプルをみてみましょう。まず2つの楽器 "schh" と "scbass" を用意します。

```cpp
(
// 1つ目の楽器 "schh" の定義
SynthDef("schh", {
    arg vol=1.2, freq=3000, atk=0.01, rel=0.2, pos=0;
    var  sig, rev, filt, env, pan, out;
    sig=WhiteNoise.ar(0.5);
    filt=RHPF.ar(sig, freq, LFDNoise3.kr(0.5).range(0.001, 2) );
    rev=FreeVerb.ar(filt, 0.7, 1);
    pan=Pan2.ar(rev, pos, vol);
    env=EnvGen.ar(Env.perc(atk, rel), doneAction:2);
    out=pan*env;
    Out.ar(0, out);
}).add;

// 2つ目の楽器 "scbass" の定義
SynthDef("scbass", {
    arg freq = 52.8, pos = 0.0, vol = 1.0;
    var bass =
    SinOsc.ar(0, (Sweep.ar(1.0, 2pi * [freq, 740]) + (pi/3)).wrap(-pi, pi), [2, 0.05]).mean.tanh *
    EnvGen.ar(Env([0, 0.5, 0.4, 0], [0, 0.2, 0.01], -5), doneAction: 2);
    bass = Pan2.ar(bass, pos) * vol;
    bass = CompanderD.ar(bass);
    Out.ar(0, bass);
}).add;
);
```

この楽器を演奏するためのTidal側のプログラムは以下のようになります。

```hs
(sc1, shape1) <- scStream "schh"
  [ F "vol" (Just 1.2),
    F "freq" (Just 3000),
    F "atk" (Just 0.01),
    F "rel" (Just 0.2),
    I "pos" (Just 0)
  ] 0

(sc2, shape2) <- scStream "scbass"
  [ F "freq" (Just 50),
    F "pos" (Just 0.0),
    F "vol" (Just 1.0)
  ] 0

let vol1   = makeF shape1 "vol"
    freq1  = makeF shape1 "freq"
    atk1   = makeF shape1 "atk"
    rel1   = makeF shape1 "rel"
    pos1   = makeF shape1 "pos"
    freq2  = makeF shape2 "freq"
    pos2   = makeF shape2 "pos"
    vol2   = makeF shape2 "vol"

cps(150/120)

sc1 $ freq1 "8000 [0 12000] 300 9000" |+| vol1 "4.0"

sc2
$ every 2 (jux (iter 4))
$ stack [
freq2 "50 [60 40] 10 80" |+| pos2 "-1 1 -0.6 0.6" |+| vol2 "2.0",
freq2 "40 80" |+| pos2 "-0.6 0.6" |+| vol2 "2.0"
]

sc1 silence

sc2 silence
```