I'm working on an independent study for my Master's program where I make a port of Tidalcycles to another language (in the style of Strudel, Vortex, and Kidal). I picked lua because I think there are some interesting things that could be done down the road given the way lua can be embedded in c or cpp programs and the environments it runs in (monome's norns platform, game engines). I wanted to announce it here so I could get feedback from whoever is interested as I go along. https://github.com/XiNNiW/tranquility
Disclaimer: It is currently under heavy construction and non-functional...
On that topic, I wanted to ask for a little advice. Tidal and vortex both utilize a separate thread for their clock process. This thread periodically queries Streams causing their pattern data to be converted into OSC messages and sent over the network. Lua does not have a built in way to do preemptive multitasking but does have a way to do cooperative multitasking using its co-routines. A puzzle I'm thinking about is how control could be cooperatively shared between the two main responsibilities of the program: 1. interpret user entered strings as patterns and store them in streams, 2. cause those streams to output OSC messages every 1/20th of a second.
I'm thinking that there has to be a control structure like the following somewhere:
while coroutine.resume(Clock._notifyCoroutine) do
--[[ poll for user input and set interpret strings as patterns]]
--[[ set patterns on streams]]
--[[ subscribe streams to the clock]]
In the above, the clock sleeps the process until it reaches the next time its supposed to notify the Streams and then calls their notify method which queries the pattern and sends its data over OSC. This means that the process spends most of its time sleeping which feels wrong. Is there a better way to do this?
Oh wow i didn't know that renoise was lua based! That's really interesting... My gut feeling is that, once Tranquility is working, why not? I also wonder if it would be possible to integrate Tidal and renoise currently with the mainline Tidal by sending OSC messages to renoise. Does renoise speak OSC?
As far as I understand, the renoise itself is written in C++ or a similar language. and lua is integrated in it for extensions.
There have already been topics enlightened by connecting tidal cycles through osc. but it was not a very working solution. but if it were possible to make such a console in the renoise itself, then this would significantly help change the rule of the game and make renoise an ideal environment for livecoding.
to be honest i imagined if it would be in renoise and it blows my mind. I am madly in love with renoise and fell in love with tidal cycles and its concept. How cool could it be to have such a tool in my favorite tracker. hope to see it someday!
I guess I'm worried that the program will be unresponsive to user input while the clock is sleeping and might miss a user sending in a new pattern to be parsed. I think its trying to think about how those two responsibilities (clocking and parsing user input) could share a thread cooperatively without one messing with the function of the other.
Would there need to be a queue of user input that the process comes around to collect so that input isn't missed? Would the clock need to poll for the time instead of sleep? Or am I wayy overthinking this and no one will miss the fraction of a fraction of a second that will go missing when the clock goes to bed?
As I'm thinking about it more.. I think I just don't understand how tidal gets new user input into the program...
commands like d1 $ s "whatever" get executed by ghci. Implementation uses streamReplace (Tidal/Stream.hs at main · tidalcycles/Tidal · GitHub) to set the "current" pattern. This is the pattern that is queried for current events by the back-end (running in a separate thread).
I saw there was a 'gabba zero' commit (whoop), and thought I'd try it out.. Running gabba_zero.lua, it looks like it's working, although I don't hear anything from superdirt, and can't see the OSC in a packet sniffer. Looking at the code, I'm not sure why..
Interesting that no sound is coming out. My first guess is that something might be wrong with the dependencies. I've downloaded a bunch of luarocks globally so its possible my copy is working because of that and I stuff missing from the rockspec. Or- it might be that the code fails silently when dependencies are missing. (If losc was not working it might explain why no OSC is making it to localhost)
Looking at the docs for luarocks one of the following might need to be run before luarocks build to install dependencies. luarocks make luarocks install --only-deps rockspecs/tranquility-dev-1.rockspec
If you do get the chance to kick the tires again let me know and I'll add what works to the README.md
I'm not sure what I really did different (I'm on a different computer from before).
My o/s (pop/os, which I think is based on ubuntu) has lua5.4.4, but the packaged luarocks is built with lua5.2, which seems too old for tranquility (the fraction module didn't build). I managed to compile the latest luarocks from a tarball, but had to install the liblua5.4-dev, openssl, libssl-dev, and libasio-dev packages first.
Well these were system-level packages so I guess out of scope for lua. I've been lucky to be working with Realtalk lately, which is quite lua-based, so am looking forward to exploring tranquility with that when I get some time.