--- a/src/CMakeLists.txt Sun Oct 04 19:59:03 2020 +0200
+++ b/src/CMakeLists.txt Sun Oct 04 20:42:51 2020 +0200
@@ -34,7 +34,7 @@
)
# Link libraries:
-target_link_libraries(${EXECUTABLE_FILE} ${RELPIPE_LIBS_LIBRARIES})
+target_link_libraries(${EXECUTABLE_FILE} ${RELPIPE_LIBS_LIBRARIES} pthread)
set_property(TARGET ${EXECUTABLE_FILE} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(TARGETS ${EXECUTABLE_FILE} DESTINATION bin)
--- a/src/JackHandler.h Sun Oct 04 19:59:03 2020 +0200
+++ b/src/JackHandler.h Sun Oct 04 20:42:51 2020 +0200
@@ -28,6 +28,7 @@
#include <sys/mman.h>
#include <signal.h>
#include <unistd.h>
+#include <pthread.h>
#include <jack/jack.h>
#include <jack/midiport.h>
@@ -73,6 +74,9 @@
jack_port_t* jackPort = nullptr;
jack_ringbuffer_t* ringBuffer = nullptr;
+ pthread_mutex_t processingLock = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t processingDone = PTHREAD_COND_INITIALIZER;
+
const int RING_BUFFER_SIZE = 100;
int processCallback(jack_nframes_t frames) {
@@ -86,11 +90,16 @@
jack_midi_data_t* midiData = jack_midi_event_reserve(jackPortBuffer, m.time, m.size);
memcpy(midiData, m.buffer, m.size);
}
+
+ if (pthread_mutex_trylock(&processingLock) == 0) {
+ pthread_cond_signal(&processingDone);
+ pthread_mutex_unlock(&processingLock);
+ }
+
return 0;
}
int syncCallback(jack_transport_state_t state, jack_position_t* position) {
- std::wcerr << L"syncCallback()" << std::endl;
return true;
}
@@ -160,6 +169,7 @@
jack_deactivate(realTimeContext.jackClient);
jack_client_close(realTimeContext.jackClient);
jack_ringbuffer_free(realTimeContext.ringBuffer);
+ pthread_mutex_unlock(&realTimeContext.processingLock);
}
void failInConstructor(const relpipe::common::type::StringX& errorMessage) {
@@ -170,6 +180,8 @@
public:
JackHandler(Configuration& configuration) : configuration(configuration) {
+ pthread_mutex_unlock(&realTimeContext.processingLock);
+
// Initialize JACK connection:
std::string clientName = convertor.to_bytes(configuration.jackClientName);
realTimeContext.jackClient = jack_client_open(clientName.c_str(), JackNullOption, nullptr);
@@ -284,11 +296,10 @@
}
void endOfPipe() {
- // Wait until the ring buffer is empty
- while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) usleep(1000);
- usleep(1000000);
- // TODO: better waiting (ringBuffer might be empty, but events have not been sent to JACK yet)
// TODO: optionally mute all; probably enabled by default
+
+ // Wait until the ring buffer is empty (messages dequeued from the buffer) and real-time cycle was finished (messages passed to JACK)
+ while (continueProcessing && jack_ringbuffer_read_space(realTimeContext.ringBuffer)) pthread_cond_wait(&realTimeContext.processingDone, &realTimeContext.processingLock);
}
void finish(int sig) {