はじめに
TidalCyclesはシンセや音源を用いてトラックを気軽に作れるためとても便利です。
ただ、個人的には
- 0サイクル目から再生する方法
- サイクル数を表示する方法
が~~公式ページで明示されていないため、少し使いづらいところがありました。~~(公式でサイクル数をPop-up windowで表示する方法が紹介されてました。後述します)
今回は「サイクル数を表示する方法」について紹介したいと思います。(「0サイクル目から再生する方法」については別記事で紹介しています。)
泥臭すぎるやり方
※ここで紹介する手法は割と泥臭く拡張性のないやりかたなので、直接サイクル数を知れる方法をご存知の方がいれば教えてください!(※後述)
StateValueの中身を表示する方法
TidalCyclesのversion1.7.2からはStateValueというものが使えるようになっています。詳細は公式ページを確認してみてください。
このStateValueなんですが、中身を確認する方法があるみたいです。
https://club.tidalcycles.org/t/working-with-tidal-state-values-tidal-can-count/2955/7
import Control.Concurrent.MVar
import Data.Map as Map
d2 $ every 2 (+ nCount "i") $ s "sn*3"
fmap (Map.lookup "i") (readMVar $ sStateMV tidal)
上のように、d2が再生されている間はStateValueであるi
が再生されるごとに増えていきます。
fmap (Map.lookup "i") (readMVar $ sStateMV tidal)
を実行するたびにコンソールにi
の値が表示されます
サイクル数を表示する方法
これと、0サイクル目から再生する方法で紹介したresetCyclesTo
関数を用いることによってサイクル数が取得できそうです。
do
resetCyclesTo (-0.05)
setF "i" 0
d16 $ (+ nCount "i") $ s "sn" # gain 0
これを実行することによって、
- 0サイクル目からスタート
- StateValue
i
を0に初期化 - 1サイクルごとに
sn
がVolume0で再生され、その度にi
が1ずつ増えていく
ということになります。
したがって、fmap (Map.lookup "i") (readMVar $ sStateMV tidal)
を実行すると、サイクル数を確認することができます。
全体のコードはこんな感じになります(d1,d2,d3はサンプルとして載せただけなのでお好きなトラックを作ってください!)
import qualified Sound.Tidal.Tempo as T
resetCyclesTo n = T.changeTempo (sTempoMV tidal) (\t tempo -> tempo {T.atTime = t, T.atCycle = n})
import Control.Concurrent.MVar
import Data.Map as Map
fmap (Map.lookup "i") (readMVar $ sStateMV tidal)
do
-- resetCyclesTo (-0.05)
-- setF "i" 0
d1 $ s "{808sd:11*3,808oh*4}"
d2 $ s "~ 909 ~ 909"
d3 $ s "superhammond" # n "<d4,e4,a4,cs5>" # sustain 0.2 # voice 1
d16 $ (+ nCount "i") $ s "sn" # gain 0
resetCyclesTo (-0.05)
とsetF "i" 0
は再生開始時のみ実行で、再生直後にはコメントアウトしてください(でないと、次の実行時に再生がリセットされて0サイクル目から再生されます)
この手法の弱点
弱点というか注意点がいくつかあるのでまとめておきます
- 再生直後に
resetCyclesTo (-0.05)
とsetF "i" 0
をコメントアウトするの忘れると次の実行時に恥ずかしい - d16を占領してしまう
- d16が再生停止すると、Tidal内部におけるサイクル数は増えていくのに、
i
は更新されなくなる
エディタから表示させる方法
streamGetnow tidal
で、小数点付きのサイクル数が得られる
【公式のやり方】サイクル数をPop-up windowで表示する方法
公式のreferenceページが更新され、もっと良い方法が紹介されていました。
superdirtを起動させてから、
(
var clockMods, clockBeats, screenW, screenH, clockW, clockH, clockX, clockY, resizable, border;
clockMods = [4,6];
clockBeats = 4;
screenW = 1440;
screenH = 900;
clockW = 120;
clockH = 22;
clockX = screenW - clockW;
clockY = screenH - 1;
resizable = false;
border = false;
~clockText = StaticText()
.string_("[clock]")
.font_(Font.defaultMonoFace)
.align_(\center)
.stringColor_(Color(1,1,1))
.minHeight_(20);
~updateClock = { |cycle|
var text, beat;
text = clockMods.collect { |m| "" ++ (cycle.floor.asInteger.mod(m) + 1) ++ "/" ++ m; }.join(" ");
beat = (cycle.mod(1)*clockBeats).round.asInteger + 1;
text = text ++ " " ++ clockBeats.collect { |i| if(i < beat, ".", " "); }.join;
~clockText.string_(text);
};
~clockWindow = Window("clock", Rect(clockX, clockY, clockW, clockH), resizable, border)
.background_(Color(0.3,0.3,0.3))
.layout_(
HLayout(
~clockText
).margins_(0!4)
);
~clockWindow.alwaysOnTop_(true);
~clockWindow.visible_(true);
SynthDef(\tick, { |cycle|
SendReply.kr(Impulse.kr(0), "/tick", [cycle]);
FreeSelf.kr(Impulse.kr(0));
}).add;
OSCdef(\tick, { |msg|
var cycle;
#cycle = msg[3..];
Routine {
{ ~updateClock.(cycle); }.defer;
}.play(SystemClock);
}, "/tick");
)
を実行して、TidalCyclces側で
p "tick" $ "0*4" # s "tick"
を実行するだけです。
個人的には16サイクルのうちのサイクル数がみたいことが多いので、clockMods = [4,6];
をclockMods = [16];
に変えれば知りたいものが見れました。
文字サイズは割と小さく、右上にこんな感じで表示されます。
こんな感じで、リアルタイムでサイクル数を確認できます。