【TidalCycles】再生中の音にエフェクトをかける

# はじめに

TidalCyclesはHaskellライクなコードによってリズムパターンを生成できるソフトウェアです。

https://qiita.com/mynkit/items/620082b82a4bbe475823

もちろんエフェクトをかけることもできますが、どの音にどんなエフェクトをどれくらいかけるのか指定してから再生されるため、一度生成した音のエフェクトを変更したりすることができません。

http://tidalcycles.org/docs/reference/audio_effects

ただ、panやボリュームなどエフェクトを少しずつ変えたり、という願望はあります。forumを探していると同じことを聞いている方がいました。

https://forum.toplap.org/t/change-effects-parameters-without-re-triggering-a-sample-instrument/1240

ここでmunshkrさんがSuperDirtModという拡張機能を紹介しているのでつかってみます。

# SuperDirtMod

## インストール方法

https://github.com/munshkr/SuperDirtMod

インストール方法は、READMEにも書いてある通りSuperColliderのエディタで以下を実行してから、アプリを再起動することで使えるようになります。(再起動したくない場合は、[Recompileすればいいみたい](https://scsynth.org/t/solved-when-using-the-atk-command-error-class-not-defined-is-displayed/5648/6?u=mynkit)です)

```supercollider
Quarks.install("https://github.com/munshkr/SuperDirtMod");
```

## セットアップ

まずTidalCycles側です。
BootTidal.hsに以下を記載します。(BootTidal.hsについては[こちらの記事](https://qiita.com/mynkit/items/10c32ff7cac1ed8a636d)を参考にしてください。)

```haskell
--
-- == SuperDirtMod BEGIN ==
--

-- Define mod target
modTarget = superdirtTarget {oName = "SuperDirtMod", oAddress = "127.0.0.1", oPort = 57130 }
oscSet = OSC "/set" Named {requiredArgs = []}
modMap = [(modTarget, [oscSet])]
-- Define mod stream
-- Total latency = oLatency + cFrameTimespan
modu <- startStream (defaultConfig {cCtrlAddr = "0.0.0.0", cCtrlPort = 6061}) modMap

getStatem = streamGet modu
setIm = streamSetI modu
setFm = streamSetF modu

-- Define pmod stream replacer and orbit helper functions
pmod = streamReplace modu
mod1 = pmod "mod1" . (|< orbit 0)
mod2 = pmod "mod2" . (|< orbit 1)
mod3 = pmod "mod3" . (|< orbit 2)
mod4 = pmod "mod4" . (|< orbit 3)
mod5 = pmod "mod5" . (|< orbit 4)
mod6 = pmod "mod6" . (|< orbit 5)
mod7 = pmod "mod7" . (|< orbit 6)
mod8 = pmod "mod8" . (|< orbit 7)
mod9 = pmod "mod9" . (|< orbit 8)
mod10 = pmod "mod10" . (|< orbit 9)
mod11 = pmod "mod11" . (|< orbit 10)
mod12 = pmod "mod12" . (|< orbit 11)

-- Reset functions
reset = pI "reset" 1
modResetAll = streamOnce modu reset

putStrLn "SuperDirtMod enabled"

--
-- == SuperDirtMod END ==
--
```

ちなみに私の環境は

```
tidal: 1.7.10
ghc: 9.2.2
```

です。

次にSuperCollider側のセットアップです。

こちらはSuperDirtの起動後に、

```supercollider
SuperDirtMod.start(superDirt: ~dirt)
```

を実行するだけです。

# テスト

```haskell
d1
  $ s "superhammond/2"
  # n "[0,2,5]"
  # gain 0.6
  # room 0.7 # size 0.6

mod1
  $ segment 64
  $ pF "vibrato" (range 0 2 $ slow 2 saw)
  # pF "vrate" (range 2 8 $ slow 1.5 rand)
```

上を実行後、下を実行するとエフェクトが再生されている音にリアルタイムにかかっているのが分かると思います(試しにパラメータを変えて実行すると即座にエフェクトが変わるのがわかるはずです)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">TidalCyclesの再生中にエフェクトを変更できるSuperDirtMod<br>たのしい<a href="https://t.co/XR5JewCosT">https://t.co/XR5JewCosT</a> <a href="https://t.co/kNMncZyj0p">pic.twitter.com/kNMncZyj0p</a></p>&mdash; Keita Miyano 宮野恵太 (@keitamiyano_) <a href="https://twitter.com/keitamiyano_/status/1601197241481326594?ref_src=twsrc%5Etfw">December 9, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 停止方法

superdirtとsuperdirtmodを停止したくなったら以下のコマンド実行

```supercollider
(
SuperDirtMod.stop;
Server.killAll;
~dirt.free;
)
```