この記事では、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を制御するような仕組みを作ることができました。