TidalCyclesでパターンを簡単に変更するアイデア

この記事では、TidalCyclesでライブを行う時に向けて、パターンを簡単に変更して本番でのミスを減らすアイデアを記載します。

動画

コード

setcps(140/240)

do
 let par1 = "{0 1 2}%8"              --bass pattern  default:"{0 1 2}%16"  
 let par2 = (scale "minor" "{0}%16") -- bass pitch default:(scale "minor" "{0}%16")
 let par3 = "{0 1 2 3}%4"            -- main bite 4 default:"{0 1 2 3}%4" 
 let mx = [1,1,1,1]                  -- mixer
 let fill = "f"                      -- t: fill on  f: fill off
 let sfillen = "t" 
 let sfill = struct "f t f <t t([3|3|4],4,[0|1|2|3])>"
 let bd_pattern = 3 -- 1-4
 let hh_pattern = 3 -- 1-4
     bdpat = case bd_pattern of
        1 -> "t*4" ; 2 -> "t t t [t ~ ~ <f t>]"; 3 -> "t t t [t <f t>]"; 4 -> "~"; _ -> "~" 
     hhpat = case hh_pattern of
        1 -> "[f t]*4" ; 2 -> "[f t t t]*4"; 3 -> "t*16"; 4 -> "t*8"; _ -> "~" 
 d1
  $ jswing $ bite 4 par3 
  $ whenmod 4 3 (while fill (const (struct "t*16" $ s "midi" # midichan "9*16" # n 0 # amp "0.1 0.3 0.5 0.7 0.9 1")))
  $ stack[
  struct bdpat $ s "[midi]"  # midichan 8 |+ n "c5"  # amp (mx !! 0*1.5)
  , while sfillen (sfill) $ s "midi(2,4,1)"  # midichan 9 # n 0      # amp (mx !! 1*1.0)
  ,s "midi*16"      # midichan par1 # n par2 # amp "[1|0.8|0.6]*16" # legato "[1|0.8|0.6]*16" # amp (mx !! 2*1.0)
  -- ,s "midi*16" # midichan "{0 1 2 3   4 5 6 7}%16" # n 0 # amp "[1|0.8|0.6]*16" # legato "[1|0.8|0.6]*16" 
  ,struct hhpat $ s "midi"  # midichan 11 # n 0 # ccv "[20 <80 70 60 100> 0 40]*4" # ccn 19 # amp "[0.5 0.9 1 0.8]*4" # amp (mx !! 3*1.0)
  ]
 d2
  $ progNum "38" # s "midi" # midichan 15

注:オリジナル関数定義があるのでそのままでは実行できません。また外部機器syntakt用にmidi出力しています。

解説1

do
 let bd_pattern = 1 -- バスドラムのパターン選択。1から4のどれかを入力する
     bdpat = case bd_pattern of
       1 -> "t*4"
       2 -> "t t t [t ~ ~ <f t>]"
       3 -> "t f f f f t f f"
       4 -> "~"
       _ -> "~"  -- 1から4以外の値が来た場合
 d1
  $ stack[
   struct bdpat $ s "bd",
   s "sn:2(2,4,1)",
   s "hc(4,8,1)" 
  ]

2行目のbd_patternの値を1,2,3,4に入れ替えてみてください。バスドラムのパターンが変わります。

このようにcase文を使ってbd_patternの値を判定して、事前に用意したパターンから選択することができます。

また、以下のように1行にまとめることも可能です。

       1 -> "t*4"
       2 -> "t t t [t ~ ~ <f t>]"
       3 -> "t f f f f t f f"
       4 -> "~"

以下のように";"を使えば1行にまとめられる

       1 -> "t*4";2 -> "t t t [t ~ ~ <f t>]"; 3 -> "t f f f f t f f"; 4 -> "~"

次のコードでは、バスドラム、スネア、ハイハットの3つを1箇所にまとめてみました。こうすれば、上から2-4行目の数値を変更するだけでパターンを変えられますね。

do
 let bd_pattern = 1 -- バスドラムのパターン選択。1から4のどれかを入力する
     sn_pattern = 1 -- スネアのパターン選択。1から4のどれかを入力する
     hc_pattern = 1 -- ハイハットのパターン選択。1から4のどれかを入力する
     bdpat = case bd_pattern of
       1 -> "t*4"; 2 -> "t t t [t ~ ~ <f t>]"; 3 -> "t f f f f t f f"; 4 -> "~"
     snpat = case sn_pattern of
       1 -> "f f t f"; 2 -> "t(2,4,1)"; 3 -> "f t f [t f f t] "; 4 -> "~"
     hcpat = case hc_pattern of
       1 -> "t(4,8,1)"; 2 -> "t(8,8)"; 3 -> "t*16"; 4 -> "~"
 d1
  $ stack[
   struct bdpat $ s "bd",
   struct snpat $ s "sn:2",
   struct hcpat $ s "hc" 
  ]

解説2

do
 let sroll = "f"                      -- t: snare roll on  f: off
 let sfillenable = "f"                    -- t: snare fill on  f: off
 let sfill = struct "f t f <t t([3|3|4],4,[0|1|2|3])>"
 d1
  $ whenmod 4 3 (while sroll (const (struct "t*16" $ s "sn:2" )))
  $ stack[
    s "bd*4" 
  , while sfillenable (sfill) $ s "sn:2(2,4,1)" 
  ]

2行目のfをtに変更すると、4サイクル目にスネアロールが再生されます。これは6行目のwhile srollのt or fを制御していて、tの時にはconstによりsnareがt*16で再生されます。

3行目のfをtにすると、9行目のsfillenableがtとなり、sfillが有効になってスネアのフィルインが入るようになります。

このように、while x (y) のxの部分をletで定義することで、スイッチのON/OFFを制御するような仕組みを作ることができました。