diff --git a/clients/CMakeLists.txt b/clients/CMakeLists.txt index a48af11a..367acc04 100644 --- a/clients/CMakeLists.txt +++ b/clients/CMakeLists.txt @@ -1,6 +1,6 @@ if(SFIZZ_JACK) 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) install(TARGETS sfizz_jack DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT "jack" OPTIONAL) diff --git a/clients/jack_client.cpp b/clients/jack_client.cpp index b9e5f5dd..46fff6b2 100644 --- a/clients/jack_client.cpp +++ b/clients/jack_client.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -38,11 +39,14 @@ #include #include #include +#include +#include static jack_port_t* midiInputPort; static jack_port_t* outputPort1; static jack_port_t* outputPort2; static jack_client_t* client; +static SpinMutex processMutex; 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); assert(buffer); + auto* leftOutput = reinterpret_cast(jack_port_get_buffer(outputPort1, numFrames)); + auto* rightOutput = reinterpret_cast(jack_port_get_buffer(outputPort2, numFrames)); + + std::unique_lock 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); jack_midi_event_t event; @@ -96,9 +110,6 @@ int process(jack_nframes_t numFrames, void* arg) } } - auto* leftOutput = reinterpret_cast(jack_port_get_buffer(outputPort1, numFrames)); - auto* rightOutput = reinterpret_cast(jack_port_get_buffer(outputPort2, numFrames)); - float* stereoOutput[] = { leftOutput, rightOutput }; synth->renderBlock(stereoOutput, numFrames); @@ -112,6 +123,7 @@ int sampleBlockChanged(jack_nframes_t nframes, void* arg) auto* synth = reinterpret_cast(arg); // DBG("Sample per block changed to " << nframes); + std::lock_guard lock { processMutex }; synth->setSamplesPerBlock(nframes); return 0; } @@ -123,6 +135,7 @@ int sampleRateChanged(jack_nframes_t nframes, void* arg) auto* synth = reinterpret_cast(arg); // DBG("Sample rate changed to " << nframes); + std::lock_guard lock { processMutex }; synth->setSampleRate(nframes); return 0; }