I was wondering if it is possible or viable to add a yield callback in Csound WASM, via a listener.
My use case:
- I am working with firing off events in Csound at certain times. For this I am using a combination of
the JS timer adjusted with the AudioContext time. This works for about a minute or two, but then it starts to
go wrong as setTimeout() gets called more irregularly than at the start. While my corrections keep the overall
pulse going, the rhythm breaks down. In other words, this is unusable
See what I have here:
- If I had a callback from Csound, then I could fire the events more or less around the time they should
start, give or take a few ms, which is not too bad for me (as it is even at the start setTimeout can be late
by several ms). I could then modify the current scheme and drop setTimeout() and the AudioContext clock,
to just use the yield callback.
Another possibility is to implement a csound.setTimeout() that is timed by the Csound clock. That would
actually be even simpler to use.
There was also a feature request for setOutputChannelCallback, I think I will implement that and this on the develop branch. But on design level, the latency of the callbacks should be the most accurate with sharedArrayBuffers and script-procesor-node setups. For all other cases, the signaling from csound to the main thread will need to go through message channels in order to call a registered callback. The only downside is potential delays, but we’ll need to see if that’s even something to worry about in the first place. But I imagine for script-processor-node, where all the processing is taking place on one thread, a slow callback could cause underruns is performKsmps.
So the inherent problem is that it’s not possible to pass a function pointer from one thread to another. So a setTimeout, which accepts a callback, can’t be passed from user to the csound clock directly. There will always need to be some sort of signaling between the worker and the main thread. Even with “singlethread” worklets, since csound runs in that case in a worklet worker.
Perhaps the base of all these callback api functionalities would be that csound sends subscribeable “onKsmps” events and with those events, it’s possible to do most things on the main thread, also if it’s subscribeable event-listener, then user could do whatever they want with those events.
Unless the callback can be passed from the main thread to Csound, none of what I was thinking would work.
Since it is not possible to fire events (like I am doing with midiMessage) accurately in time with a main thread timer, then I will need
to change this to schedule events instead. Then if I refer to an accurate clock like the one from AudioContext, I can schedule things
in the future accurately and use the JS timer to call the scheduling function regularly.
I solved my timing problem by using Csound to schedule ahead and so not relying anymore
on the timing of JS setTimeout calls. It seems solid now (at least for several minutes)
it is so interesting that you use the p5js editor for this! do you plan to start visual elements in parallel? and what is behind the code, for instance how do you start csound?
I am actually using it as a JS IDE, and it works very well for that. You can even do live coding in it, you can work with or without visuals (but I’m not doing visuals at the moment).
fascinating. but how do you load csound? i don't see anything in your code, so i am wondering what is "behind the curtain". i should describe it for he floss manual or the website --- so important ...
thanks -
j
I have Csound loaded by the start() function in the GMPlay.js file which I am preparing to be a module.
The idea of this particular work is to make a real simple live coding system for absolute beginners (with Csound completely hidden).
But in general, all you need is to load and start Csound as shown in the p5.js editor examples I put in Vanilla Guide to Csound WASM
for example,
Rory has also been doing some work to facilitate loading Csound by providing the start() function in a p5Csound.js module that you
can just drop in.
In fact, yesterday I was looking at other possible online JS IDEs and to me the p5.js editor was on balance the best one to use with Csound.
So I would recommend that even if you are not using the graphics side.
The p5 module I’m writing simplifies creating Csound and kissing assets. But after that it’s vanilla Csound.
Slightly off topic, but has anyone had any success running Csound wasm examples from a git repo using the online VS code editor? That would be a nice setup. Last time I tried I couldn’t serve anything, but I probably just messed it up.
wow ---
now i get it, and you already established the connection with the processing javascript ...
i have added a post on the csound website for yours and stevens/hlodvers tutorial.
looking forward to more, also from rory -
j