はじめに
TidalCyclesはシンセや音源を用いてトラックを気軽に作れるためとても便利です。
ただ、個人的には
- 0サイクル目から再生する方法
- サイクル数を表示する方法
が公式ページで明示されていないため、少し使いづらいところがありました。
今回は「0サイクル目から再生する方法」について紹介したいと思います。(「サイクル数を表示する方法」については別記事で紹介しています。)
※バージョン1.8からは、
以下の方法でresetCyclesTo関数を定義できます
streamResetCyclesTo s n = streamSetCycle s n
resetCyclesTo n = streamResetCyclesTo tidal (n+1)
サイクル数について
SuperCollier上でSuperDirtを起動してから、TidalCyclesのサイクル数のカウントが始まります(0サイクルスタート)。
d1
$ every' 8 7 (ply "1 1 1 12" . (|* gain 0.9))
$ s "{808sd:11*3,808oh*4}"
上のコードのように
$ every' 8 7 (ply "1 1 1 12" . (|* gain 0.9))
と設定すると、8サイクル周期で7サイクル目のときplyエフェクトがかかるわけですが、「今何サイクル目か?」がわからないと意図通りのタイミングで音が出せないわけです。
また、曲の始まりも意図していない位置から再生される可能性があります。
そこで、Tidalに標準で用意されているresetCycles
というサイクル数を0に戻す関数を使ってみよう、という発想になりますが、実はこれを実行するとうまくいきません
-- 本来d3のシンセの音が1音目に出てほしいのに、出てこない
do
resetCycles
d1
$ every' 8 7 (ply "1 1 1 12" . (|* gain 0.9))
$ s "{808sd:11*3,808oh*4}"
d2 $ s "~ 909 ~ 909"
d3 $ s "superhammond" # n "<d4,e4,a4,cs5>" # sustain 0.2 # voice 1
これにはTidalのissueでも言及されていて、サイクルが0に戻るのと音が再生されるのにレイテンシがあるのが問題で、以下のようにresetCyclesTo
関数を定義してあげるとうまくいくみたいです。
import qualified Sound.Tidal.Tempo as T
resetCyclesTo n = T.changeTempo (sTempoMV tidal) (\t tempo -> tempo {T.atTime = t, T.atCycle = n})
do
resetCyclesTo (-0.05)
d1
$ every' 8 7 (ply "1 1 1 12" . (|* gain 0.9))
$ s "{808sd:11*3,808oh*4}"
d2 $ s "~ 909 ~ 909"
d3 $ s "superhammond" # n "<d4,e4,a4,cs5>" # sustain 0.2 # voice 1
うまくいきました。
開始時に実行したら、直後にresetCyclesTo部分をコメントアウトしてあげるといいです。(でないと、また実行したときに0サイクルに戻ってしまうので)
import qualified Sound.Tidal.Tempo as T
resetCyclesTo n = T.changeTempo (sTempoMV tidal) (\t tempo -> tempo {T.atTime = t, T.atCycle = n})
do
-- resetCyclesTo (-0.05)
d1
$ every' 8 7 (ply "1 1 1 12" . (|* gain 0.9))
$ s "{808sd:11*3,808oh*4}"
d2 $ s "~ 909 ~ 909"
d3 $ s "superhammond" # n "<d4,e4,a4,cs5>" # sustain 0.2 # voice 1