Context
I am working on a application that has a Qt GUI and does audio processing with Jack in C++.
In order to decouple the GUI from audio processing, I want them to run in different threads.
Potentially, there may be other additional threads involved.
Question
How does the system determine, in which thread the audio callback registered via jack_set_process_callback is being run?
Knowing this decisive, ie. if there are more threads involved.
Simplified Pseudocode
JackClient::run
starts a seperate thread that is sets itself to sleep but is used to handle the audio callback registered via jack_set_process_callback
.
It seems to work – the audio callback is handled by the sleeping dedicated audio thead – but why?
main.cpp:
#include ".../model/model.h"
#include ".../view/mainwindow.h"
#include "controller.h"
#include ".../audio/jack.h"
#include <QApplication>
int main(int argc, char *argv[])
{
// 1. Init Jack Client
// and start dedicated
// dummy thread to process
// audio:
JackClient jack(...);
{
jack.init();
jack.run(); // <- start audio thread
}
// 2. Start GUI
// and run GUI mainloop
// in main thread:
QApplication a(argc, argv);
auto model = Model(...);
auto view = MainWindow();
Controller controller(
&model,
&view,
&jack,
viewResolution
);
controller.run(); <- GUI main loop
auto ret = a.exec();
// stop audio thread:
jack.exit();
return ret;
}
jack.cpp:
// the audio callback:
int processAudio(
jack_nframes_t nframes,
void* arg
);
MaybeError JackClient::init() {
{
jack_status_t status;
jack_options_t options = JackNullOption;
client = jack_client_open(
clientName,
options,
&status
);
if( !client ) {
throw QString("error opening client");
}
}
// set process callback:
jack_set_process_callback(
client,
&processAudio,
this
);
// create ports:
...
return {};
}
MaybeError JackClient::run() {
if( jack_activate(client) ) {
return "cannot activate client";
}
workerStop = false;
worker = std::thread([this]{
while(!workerStop) {
sleep(1);
};
});
return {};
}
void JackClient::exit() {
if(!client) {
return;
}
workerStop = true;
worker.join();
jack_client_close(
client
);
}
I read the Jack documentation and looked into the official example clients, but couldn’t find any good explanation or even a hint where to search.