はじめに
TidalCyclesは、Haskellライクなコードによってリズムパターンを生成できるソフトウェアです。
個人的にTidalCyclesで作曲していて、記事も書いているのでこちらもぜひみてください!
ある条件のサイクル数のときに処理を実行する
公式のドキュメントにいろいろな方法が紹介されています。
every
every
関数を用いるとevery n 処理
とした場合に、nの倍数サイクル
ごとに処理が適用されます。
たとえば以下の例だと0, 3, 6, 9, 12,...
サイクル目にrev
が適用されます
d1 $ every 3 rev $ n "0 1 [~ 2] 3" # sound "arpy"
every'
every
関数ではnの倍数サイクル
ごとに処理されましたが、every'
を用いることで、(nの倍数 + m)サイクル
ごとの処理が可能になります。
たとえば以下の例だと1, 4, 7, 10, 13,...
サイクル目にrev
が適用されます
d1 $ every' 3 1 rev $ n "0 1 [~ 2] 3" # sound "arpy"
when
when
関数ではwhen 条件 処理
としたときに、条件がTrueの場合
のみ処理が適用されます。
ちなみにwhen関数のドキュメントにおける使用例が最初みたときにすぐ理解できなかったため、これは別記事に詳細にかきました。
when関数の型定義は以下です。
Type: when :: (Int -> Bool) -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
この(Int -> Bool)部分は、Intを引数としてBoolを返す関数を設定してあげればいいので、たとえば>=2
などが使えます。ちなみにこのIntとはサイクル数のことを指しているので>=2
と設定すると「サイクル数が2以上のとき」という意味になります。
そのためたとえば
d1 $ when (>=2) (|> speed 2) $ s "notes:2*2 house:5*3"
のようにすれば、サイクル数が2以上になると、speedが2となるので音程が1オクターブあがるのがわかると思います。
whenmod
whenmod
関数を用いると、whenmod n m 処理
とした場合に、nサイクル中のmサイクル以降のみ処理が適用されます。
たとえば以下の例だと、fast 2
が適用されるのは4,5,6,7,12,13,14,15,...
サイクル目です。
d1 $ whenmod 8 4 (fast 2) (sound "notes:2*2 house:5*3")
具体的なサイクル数を指定して処理を実行
まず今回の処理はわかりやすいように0サイクル目からスタートさせたいのでresetCyclesTo
関数を定義します。
import qualified Sound.Tidal.Tempo as T
resetCyclesTo n = T.changeTempo (sTempoMV tidal) (\t tempo -> tempo {T.atTime = t, T.atCycle = n})
resetCyclesTo関数についてはこちらの記事をご覧ください。
上で紹介したwhen
関数を用いれば、「4サイクル目のみfast 2
させたい」ということも実現できます。
do
resetCyclesTo (-0.05)
d2 $ when (==4) (fast 2) $ sound "notes:2*2 house:5*3"
もう少し変わった要件として、「1, 2, 5, 6サイクル目のみfast 2
させたい」というときには以下のように実現できます。
do
resetCyclesTo (-0.05)
let
elem' xs x = elem x xs
d2 $ when (elem' [1,2,5,6]) (fast 2) $ sound "notes:2*2 house:5*3"
条件を「[1,2,5,6]
にサイクル数が含まれているとき」としたいので、elem
関数の第一引数と第二引数を入れ替えたelem'
関数を定義しています。