I’m developing my first VCV rack module vcvrack-mienophone which is meant to:
capture pictures from a webcam
trade the pictures for emotion parameters using Azure Face API
map emotion parameters onto module outputs.
The current state of the module: It sends a local image to HTTP API using curl.c and maps the result set to 8 module outputs. Shameless green early development state.
The issue I face is that the API requests are synchronous, blocking the whole rack while curl is waiting for the HTTP response.
Could you please share your ideas how to implement this asynchonous? Is there an API in VCV rack core I could use? I am quite a C/C++ beginner.
There are only two ways. Find a non blocking http client that you can poll. Or make a worker thread to do all the work. Threads are pretty easy to get wrong…
For multithreading where you are sharing the same variable across multiple threads, you will probably find mutex and locks very useful to avoid race conditions.
I know, me 2. I didn’t even believe the pops and dropouts would happen until I saw it in action. We don’t tend to do this kind of real time programming outside of music,
std::async should work great with cURL. Just be sure to wait() on your tasks/futures in your ~Module destructor, so the tasks are guaranteed to be able to access your Module resources if the user quits Rack or deletes your module while an HTTP request is resolving.
that’s pretty cool. Is there any way to get the result from the future without doing a blocking wait? I can’t tell if std::future::wait_until() has a guaranteed non-blocking form.
Not really (in C++11), but you can just ignore the return value of std::async() and modify your state inside the async function instead of use the future object.
Some kind of function that returns bool indicating if something got done with an anonymous function as a parameter would be good for many lock-free algorithms. Quite often the process thread would not mind a lack of sample-accurate process completion.