I'm using PortAudio's callback API for designing a signal processing loopback library.
I'd like to add a branch that depends on a flag inside the callback, so like
int pa_callback(const void *inputuffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
if (do_something_flag) {
do_something(inputBuffer, outputBuffer, frameCount);
} else {
do_something_else(inputBuffer, outputBuffer, frameCount);
}
return paContinue;
}
Where do_something_flag
is set elsewhere in my program at regular intervals.
The PortAudio callback documentation states:
Before we begin, it's important to realize that the callback is a delicate place. This is because some systems perform the callback in a special thread, or interrupt handler, and it is rarely treated the same as the rest of your code. For most modern systems, you won't be able to cause crashes by making disallowed calls in the callback, but if you want your code to produce glitch-free audio, you will have to make sure you avoid function calls that may take an unbounded amount of time to execute. Exactly what these are depend on your platform but almost certainly include the following: memory allocation/deallocation, I/O (including file I/O as well as console I/O, such as printf()), context switching (such as exec() or yield()), mutex operations, or anything else that might rely on the OS. If you think short critical sections are safe please go read about priority inversion.
I don't care about the atomicity of the do_something_flag
. That is, I don't care how many cycles it takes to get a correct value (within reason).
According to the documentation, it looks like I can't use mutexes for setting/reading that variable.
1) What are my options?
2) If I make it global and set it in another part of my program (another thread), what is the absolute worst that will happen? Again, I mean in terms of corrupting data to the point of program failure/etc.
Is there a right way to do this?