TidalCycles 変数とfitと{}%とeveryの使い方

本記事では、TidalCyclesの初心者から一歩先に進めるような機能をまとめました。

動画

コード

let pat = "{0 1 1 0 2*2 1 0 2 0 1*4 0 1*5? 2 0*4 ~ 1}%16"

d1
$ whenmod 16 14 (# hpf (slow 2 $ rangex 100 4000 saw)). (# hpq 0.5)
$ whenmod 8 6 (# n (choose[1,2,3]))
$ every 4 (jux (0.125 <~))
$ every 5 ((# speed 3).(# room 0.9))
$ every 6 ((# n 5).(# speed 0.8).(# coarse (choose[16,32,4])))
$ stack[
s (fit 0 ["Kick:3","Snare:1","Chord:6"] pat) # cut 1 # shape 0.6 # gain 1.2,
note pat # s "bass1" # n 3 # cut 2 # legato (choose[0.4,0.6,1])
# lpf (rangex 200 3000 $ rand) # lpq 0.3 # gain 1 # shape 0.5
]

hush

変数の使い方

変数が使えると、コーディングで作曲するメリットを存分に活かせるようになると思います。

私も頑張ってマスターしたいと思います。

letの使い方

letを使うと、変数を取り扱うことができるようになります。

let x = "bd sn bd sn"

d1 $ sound x

上記コードでは、letの行でxに”bd sn bd sn”を代入し、d1 $ sound x でxを呼び出しています。

そのため、上記を実行すると、以下と同じように再生されます。

d1 $ sound "bd sn bd sn"

xの文字列は、基本的に何でもいいです。

変数にパターンを代入するのが便利なのですが、その場合はpatという変数名をつける人をよく見かけます。

注意1:行開け

letの行とd1の行は1行空けないと、エラーがでるので注意してください。

let x = "bd sn bd sn"
d1 $ s x
これだとエラーが出るのでNG

注意2:再生方法

letの行を実行してからと、d1の行をそれぞれ実行すると、再生されます。

どちらか片方だけ実行しても、再生されません。

それが面倒な場合は、doを頭につけて、行をまとめると、一度の実行で再生開始できます。

do
let x = "bd sn bd sn"
d1 $ s

これはOK

doを使う場合は、letとd1の行を開けると、エラーが出ますので、行を空けないようにします。

do
let x = "bd sn bd sn"

d1 $ s x

これだとエラーが出るのでNG

doを使うと、やたらとエラーが出るなあと思ったのですが、インデントを揃える必要があるようでした。

下記の場合、letとd1のインデントが揃っている必要があるのと、xのインデントがletより右にある必要があるようでした。

do
 let
  x = "bd*5 sn bd sn"
 d1 $ s x
これだとOK

以下のようなエラーが出る場合は、インデントを疑ってみてください。

parse error (possibly incorrect indentation or mismatched brackets)
 Parse error in pattern: do let
                               x

詳細はHaskellの仕様に詳しくないので、正直よくわかりません。

個人的にはdoを使おうとするとエラーが多く、なぜエラーなのかもよくわからない場合が多いです。

doはめんどくさい、という印象が植え付けられたので、まずはletだけで使いこなせるようになろうと思います。

letのさらなる使い方

letを使って変数を使えるようになると、これまで説明したように、「パターンを格納する」ことももちろん便利なのですが、パターンだけでなく、よく使う関数やエフェクトを変数に格納しておくことで、さらに面白いことができそうです。

例えば以下のように関数をx,yに格納します。

let
 x = every 4 (rev . jux (0.065<~) . fast 4)
 y = every 2 (fast 8)

d1
$ x
$ y
$ sound "bd sn hc sn"

上記のように、xやyにはevery~が格納されているので、実行するコードを短くできます。

まとめ

これまでの説明をまとめます。

以下のように、変数pat1,pat2,x,yにそれぞれパターンと関数を代入して、使用することができます。

let
 pat1 = "bd sn hc sn"
 pat2 = "arpy*8"
 x = every 4 (rev . jux (0.065<~) . fast 4)
 y = every 2 (fast 4)

d1 $ stack[
x $ s pat1,
y $ s pat2
]

事前によく使うパターンや関数を変数として定義しておけば、ライブコーディング時に簡単に呼び出すことができるので、ライブコーディングがスムーズにできると思います。

この動画に、さらに詳しい変数の使い方が説明されています。

仮引数

上記のYoutube動画では、変数を定義するときに「仮引数」を設定して、変数を呼び出すときに仮引数も一緒に入力することで、さらに使い勝手をよくしています。

let
 x = every 4 (rev . jux (0.065<~) . fast 8)

d1
$ x
$ sound "bd sn hc sn"
let
 x number1 number2 = every number1 (rev . jux (0.065<~) . fast number2)
--変数xを定義し、number1とnumber2という仮引数を定義

d1
$ x 4 8   --ここでnumber1とnumber2に4と8を代入
$ sound "bd sn hc sn"

上記2つの例を実行すると、どちらも同じ音が再生されます。

ただ下のコードは、number1とnumber2という仮引数を定義していて、$ x 4 4にて、number1とnumber2に、それぞれ4と8を代入しています。

こうすると、例えば $ x 2 2としたり、$ x 1 4としたりするだけで、number1とnumber2に値を入力できるので、変数xをさらに便利に使うことができます。

もちろん、仮引数はnumber1とnumber2という文字である必要はなく、なんでもOKです。

https://employment.en-japan.com/engineerhub/entry/2017/08/25/110000
引用:エンジニアHUB Haskellらしさって?「型」と「関数」の基本を解説!【第二言語としてのHaskell】
https://employment.en-japan.com/engineerhub/entry/2017/08/25/110000

fitの使い方

fitを使うと、fitでリストを作成し、そのリスト内のサンプルを数値で指定する形で簡単にパターンを作成することができます。

以下の場合、fit 0 [“bd:3″,”hh”,”sn:1″]でリストを作成しています。

d1 $ sound (fit 0 ["bd:3","hh","sn:1"] "0 1 2 ~ 0 1 2 ~")

その次の “0 1 2 ~ 0 1 2 ~”がパターンを表しているのですが、0はbd:3、1はhh、2はsn:1を表しているので、数字を入れ替えるだけで簡単にパターンを変化させることができます。

上記コードは、下記コードと同じ音が再生されます。

d1 $ sound "bd:3 hh sn:1 ~ bd:3 hh sn:1 ~"

fitの便利なところは、数字でパターンを作れるので、パターンが見やすくなること、また一つのパターンで複数の音色のサンプルを使えることです。

例えば以下のように変数patを定義すると、パターンとfitが分けて表現できるので、さらに見やすくなります。

パターンを変更するのも、サンプルを差し替えるのも簡単です。

let pat = "{0 1 1 0 2 1 0 2 0 1*4 0 1 2 0*4 ~ 1}%16"

d1 $ s (fit 0 ["bd:3","hh:0","sn:1"] pat) 

ちなみに、fit 0の0という数値は、パターンの数値のオフセットを表しています。

d1 $ sound (fit 1 ["bd:3","hh","sn:1"] "0 1 2 ~ 0 1 2 ~")

この場合、1サイクル目は”0 1 2 ~ 0 1 2 ~”、2サイクル目は”1 2 0 ~ 1 2 0 ~”、3サイクル目は”2 0 1 ~ 2 0 1 ~”、4サイクル目は”0 1 2 ~ 0 1 2 ~”となります。

この 数値を変えるだけでも大きく音が変わって面白いですね。

{ }%とは

{}%の使い方

{“patternA”}%x は、patternA内の1つのサウンドはx分音符になる、という意味になります。

例えば以下のd1とd2を再生してみてください。

d1 $ sound "{bd sn:1 drum notes can}%4"

d2 $ sound "alphabet"

d2のalphabetはサイクルの頭になるたびに「エー」という音声がでますね。

d1の方は、{ }の中のパターンの1つのサウンドは4分音符扱いになるので、bd,sn:1,drum,notes,canは一つ一つが4分音符の長さで再生され続けます。

そのため、1サイクルで4分音符4つまでしか再生できないので、1サイクル目はbd,sn:1,drum,notesまで再生されます。

2サイクル目は、notesの次のcanから始まり、can,bd,sn:1,drumが再生されます。

3サイクル目は、notes,can,bd,sn:1が再生され…というふうに、だんだんスライドしていきます。

{ }の中身が4分音符となるので、{ }の中のサウンドが4つの場合はきれいに繰り返されますが、5つやそれ以上の場合は、そうなりません。

一方、以下はどうなるでしょうか。

d1 $ sound "bd sn:1 drum notes can"

d2 $ sound "alphabet"

この場合、d1は、1サイクル内にbd,sn:1,drum,notes,canの5つのサウンドがあるので、1サイクルを5分割したタイミングでそれぞれの音が再生されます。

これは5連符という扱いになりますので、先程の{}%との違いがわかるかと思います。

{}%のメリット

では、{}%xの何が良いかというと、{}の中身は必ずx分音符になるので、リズムをキープできるというメリットがあります。

“bd sn hc sn”に対して、bdを間違えて追加して、”bd sn hc sn bd”というパターンにすると、突然5連符となりリズムがかなりカオスになってしまいます。

しかし”{bd sn hc sn}”%4を”{bd sn hc sn bd}”%4に変更したとしても、{}の中身は必ず4分音符ですから、リズムはキープすることができます。

例えば”{ bd sn hc sn bd*4 <bd sn hc> hc}”%16とすれば、{ }の中身をどんなに変えても16分音符で再生され続けるので、全体の雰囲気を壊すことなく、思い切って{ }の中身を変えられますね。

もちろん、%5とか%20とかにして、5分音符や20分音符にして不規則なリズムで遊ぶこともできますね。

個人的には、{}%8か{ }%16として、{ }の中身を8個か16個にするのがシンプルで汎用的かと思います。

一方、ライブコーディングでリアルタイムにコードを書き換えて遊びたい場合は、{}%16としつつ、{}の中身を積極的に追加・削除して、不規則なリズムにするというやり方も面白そうです。

everyの複数使い

everyの複数使い

everyを複数使うと、関数がサイクルごとに次々に入れ替わるので、聴いていて飽きさせない流れを作ることができます。

今回は、以下のように、everyを4,5,6にしつつ、それぞれ違う関数を用いて、次々に関数が入れ替わるようにしました。

$ every 4 (jux (0.125 <~))
$ every 5 ((# speed 3).(# room 0.9))
$ every 6 ((# n 5).(# speed 0.8).(# coarse (choose[16,32,4])))

その場合、every 4とevery 6は、12サイクルや24サイクルで重複します。everyがどの程度重複するかを表にまとめました。

参考までに、よく使うwhenmodも表に入れてみました。

tidalcycles every whenmod

この表を見る限り、every 3,4,5を使うと、かなりの頻度で重複しますが、意外と2サイクルの空白ができる区間もあることがわかります。

every6,7,8をつかうと、重複の頻度は少なくなり、空白の区間が多いことがわかります。

個人的には、every4,5,6とかevery5,6,7くらいが空白区間と重複のバランスがとれているので、使いやすそうだと感じました。

every’の使い方

every’ x y (functions) とすると、xサイクルごとにfunctionsを実行する、ただしyだけオフセット(ずれる)する、という意味です。

具体例を見ていきます。

every’ 4 0 (functions)とすると、0サイクル目、4サイクル目、8サイクル目にfunctionsが実行。

every’ 4 1(funcitons)とすると、1サイクル目、5サイクル目、9サイクル目にfunctionsが実行。

以下の表のようになります。

tidalcycles every whenmod

これを使えば、every’だけで、狙った順番でfunctionsを実行させることができます。

例えば、以下のようにします。

d1
$ every' 4 0 (fast 2)
$ every' 4 1 (# room 0.8)
$ every' 4 2 (rev)
$ every' 4 3 (# speed 4)
$ s "bd sn:1 bd*2 sn:1"

こうすると、0サイクル目はfast 2、1サイクル目は# room 0.8、2サイクル目はrev、3サイクル目は# speed 4、4サイクル目はfast 2、5サイクル目は# room 0.8 …

というように、常に何かしらのfuncitonsを実行させ続けることができますね。

コメントを残す

CAPTCHA