Thread-safety for the JACK client

This commit is contained in:
Jean Pierre Cimalando 2021-02-01 23:12:29 +01:00
parent e0a7fb1dbc
commit 62ec01a362
2 changed files with 17 additions and 4 deletions

View file

@ -1,6 +1,6 @@
if(SFIZZ_JACK) if(SFIZZ_JACK)
add_executable(sfizz_jack MidiHelpers.h jack_client.cpp) add_executable(sfizz_jack MidiHelpers.h jack_client.cpp)
target_link_libraries(sfizz_jack PRIVATE sfizz::sfizz sfizz::jack absl::flags_parse) target_link_libraries(sfizz_jack PRIVATE sfizz::sfizz sfizz::jack sfizz::spin_mutex absl::flags_parse)
sfizz_enable_lto_if_needed(sfizz_jack) sfizz_enable_lto_if_needed(sfizz_jack)
install(TARGETS sfizz_jack DESTINATION ${CMAKE_INSTALL_BINDIR} install(TARGETS sfizz_jack DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT "jack" OPTIONAL) COMPONENT "jack" OPTIONAL)

View file

@ -26,6 +26,7 @@
#include <absl/flags/parse.h> #include <absl/flags/parse.h>
#include <absl/flags/flag.h> #include <absl/flags/flag.h>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <SpinMutex.h>
#include <atomic> #include <atomic>
#include <cstddef> #include <cstddef>
#include <ios> #include <ios>
@ -38,11 +39,14 @@
#include <string_view> #include <string_view>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include <mutex>
#include <algorithm>
static jack_port_t* midiInputPort; static jack_port_t* midiInputPort;
static jack_port_t* outputPort1; static jack_port_t* outputPort1;
static jack_port_t* outputPort2; static jack_port_t* outputPort2;
static jack_client_t* client; static jack_client_t* client;
static SpinMutex processMutex;
int process(jack_nframes_t numFrames, void* arg) int process(jack_nframes_t numFrames, void* arg)
{ {
@ -51,6 +55,16 @@ int process(jack_nframes_t numFrames, void* arg)
auto* buffer = jack_port_get_buffer(midiInputPort, numFrames); auto* buffer = jack_port_get_buffer(midiInputPort, numFrames);
assert(buffer); assert(buffer);
auto* leftOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort1, numFrames));
auto* rightOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort2, numFrames));
std::unique_lock<SpinMutex> lock { processMutex, std::try_to_lock };
if (!lock.owns_lock()) {
std::fill_n(leftOutput, numFrames, 0.0f);
std::fill_n(rightOutput, numFrames, 0.0f);
return 0;
}
auto numMidiEvents = jack_midi_get_event_count(buffer); auto numMidiEvents = jack_midi_get_event_count(buffer);
jack_midi_event_t event; jack_midi_event_t event;
@ -96,9 +110,6 @@ int process(jack_nframes_t numFrames, void* arg)
} }
} }
auto* leftOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort1, numFrames));
auto* rightOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort2, numFrames));
float* stereoOutput[] = { leftOutput, rightOutput }; float* stereoOutput[] = { leftOutput, rightOutput };
synth->renderBlock(stereoOutput, numFrames); synth->renderBlock(stereoOutput, numFrames);
@ -112,6 +123,7 @@ int sampleBlockChanged(jack_nframes_t nframes, void* arg)
auto* synth = reinterpret_cast<sfz::Sfizz*>(arg); auto* synth = reinterpret_cast<sfz::Sfizz*>(arg);
// DBG("Sample per block changed to " << nframes); // DBG("Sample per block changed to " << nframes);
std::lock_guard<SpinMutex> lock { processMutex };
synth->setSamplesPerBlock(nframes); synth->setSamplesPerBlock(nframes);
return 0; return 0;
} }
@ -123,6 +135,7 @@ int sampleRateChanged(jack_nframes_t nframes, void* arg)
auto* synth = reinterpret_cast<sfz::Sfizz*>(arg); auto* synth = reinterpret_cast<sfz::Sfizz*>(arg);
// DBG("Sample rate changed to " << nframes); // DBG("Sample rate changed to " << nframes);
std::lock_guard<SpinMutex> lock { processMutex };
synth->setSampleRate(nframes); synth->setSampleRate(nframes);
return 0; return 0;
} }