Algorithmic Music on iOS with TidalCycles
Caveat
This is a writeup for my mobile setup for Emacs music composition - but iOS being iOS, this does require access to a Linux machine for most of the heavy lifting, with something like Blink on the phone as a thin client.
Previously: funktor + PulseAudio streaming
Song composition in Emacs in Blink on iOS
For a while now I’ve wanted a fully mobile programmatic music generation solution. I’d previously set this up using my own Haskell library funktor, which is an interpretive layer on top of `csound-expression` allowing terse music creation in a Haskell DSL.
I’d use Blink on iOS to connect to Emacs-in-tmux running on my VPS, with ghcid
watching for changes, constantly reloading my track when saving the file. To stream audio, I’d transcode the VPS’s PulseAudio output on-the-fly, expose it to the internet, and connect to it using the iOS VLC app in the background. This gives about a second of latency.
For posterity, I’m streaming Pulse via:
Moving to TidalCycles
I recently realised I had more or less made a TidalCycles lookalike with this setup. I’d wanted to try out Tidal for a while, and given its extreme terseness and focus on transience and experimentation rather than song composition, I figured it’d be an even better fit for the mobile interaction use-case.
I followed the Linux Installation instructions on my VPS, installing the Emacs Tidal package and getting to the point where I could get Supercollider/Superdirt/Tidal-in-Emacs talking.
Streaming JACK over the Network
The sticking point for me was that as I understand it, starting SuperDirt also suspends PulseAudio - the Tidal stack uses JACK instead. Thankfully, it was relatively straightforward to stream SuperCollider’s JACK output over the network via VLC:
With this running (and SuperDirt running in the background), one can open a .tidal
file in Emacs, C-c C-s
to bring up Tidal, and play around with very little latency.
We need to open SuperDirt first before streaming JACK, otherwise we end up with a race for port 57120.
The end result looks something like:
TidalCycles in Emacs in Blink on iOS