Fix crash with clap plugins without MIDI input
[carla.git] / source / libjack / libjack.cpp
blob3844b85216fadbde4282c33d4ea254d313cbf409
1 /*
2 * Carla JACK API for external applications
3 * Copyright (C) 2016-2022 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "libjack.hpp"
20 #include "CarlaThread.hpp"
21 #include "CarlaJuceUtils.hpp"
23 #include <signal.h>
24 #include <sys/time.h>
26 // ---------------------------------------------------------------------------------------------------------------------
28 CARLA_BACKEND_START_NAMESPACE
30 // ---------------------------------------------------------------------------------------------------------------------
32 static int64_t getCurrentTimeMilliseconds() noexcept
34 struct timeval tv;
35 gettimeofday (&tv, nullptr);
36 return ((int64_t) tv.tv_sec) * 1000 + tv.tv_usec / 1000;
39 static int carla_interposed_callback(int, void*);
41 // ---------------------------------------------------------------------------------------------------------------------
43 class CarlaJackRealtimeThread : public CarlaThread
45 public:
46 struct Callback {
47 Callback() {}
48 virtual ~Callback() {};
49 virtual void runRealtimeThread() = 0;
52 CarlaJackRealtimeThread(Callback* const callback)
53 : CarlaThread("CarlaJackRealtimeThread"),
54 fCallback(callback) {}
56 protected:
57 void run() override
59 fCallback->runRealtimeThread();
62 private:
63 Callback* const fCallback;
65 CARLA_DECLARE_NON_COPYABLE(CarlaJackRealtimeThread)
68 // --------------------------------------------------------------------------------------------------------------------
70 class CarlaJackNonRealtimeThread : public CarlaThread
72 public:
73 struct Callback {
74 Callback() {}
75 virtual ~Callback() {};
76 virtual void runNonRealtimeThread() = 0;
79 CarlaJackNonRealtimeThread(Callback* const callback)
80 : CarlaThread("CarlaJackNonRealtimeThread"),
81 fCallback(callback) {}
83 protected:
84 void run() override
86 fCallback->runNonRealtimeThread();
89 private:
90 Callback* const fCallback;
92 CARLA_DECLARE_NON_COPYABLE(CarlaJackNonRealtimeThread)
95 // ---------------------------------------------------------------------------------------------------------------------
97 class CarlaJackAppClient : public CarlaJackRealtimeThread::Callback,
98 public CarlaJackNonRealtimeThread::Callback
100 public:
101 JackServerState fServer;
102 LinkedList<JackClientState*> fClients;
103 LinkedList<JackClientState*> fNewClients;
105 CarlaJackAppClient()
106 : fServer(this),
107 fClients(),
108 fNewClients(),
109 fShmAudioPool(),
110 fShmRtClientControl(),
111 fShmNonRtClientControl(),
112 fShmNonRtServerControl(),
113 fAudioPoolCopy(nullptr),
114 fAudioTmpBuf(nullptr),
115 fDummyMidiInBuffer(true),
116 fDummyMidiOutBuffer(false),
117 fMidiInBuffers(nullptr),
118 fMidiOutBuffers(nullptr),
119 fInitialized(false),
120 fIsOffline(false),
121 fIsReady(false),
122 fLastPingTime(-1),
123 fSessionManager(0),
124 fSetupHints(0),
125 fRealtimeThread(this),
126 fNonRealtimeThread(this),
127 fRealtimeThreadMutex()
128 #ifdef DEBUG
129 ,leakDetector_CarlaJackAppClient()
130 #endif
132 carla_debug("CarlaJackAppClient::CarlaJackAppClient() START");
134 const char* const shmIds(std::getenv("CARLA_SHM_IDS"));
135 CARLA_SAFE_ASSERT_INT2_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4,
136 shmIds != nullptr ? static_cast<int>(std::strlen(shmIds)) : -1, 6*4,);
138 const char* const libjackSetup(std::getenv("CARLA_LIBJACK_SETUP"));
139 CARLA_SAFE_ASSERT_INT_RETURN(libjackSetup != nullptr && std::strlen(libjackSetup) >= 6,
140 libjackSetup != nullptr ? static_cast<int>(std::strlen(libjackSetup)) : -1,);
142 // make sure we don't get loaded again
143 carla_unsetenv("CARLA_SHM_IDS");
145 // kill ourselves if main carla dies
146 carla_terminateProcessOnParentExit(true);
148 for (int i=4; --i >= 0;) {
149 CARLA_SAFE_ASSERT_RETURN(libjackSetup[i] >= '0' && libjackSetup[i] <= '0'+64,);
151 CARLA_SAFE_ASSERT_RETURN(libjackSetup[4] >= '0' && libjackSetup[4] <= '0' + LIBJACK_SESSION_MANAGER_NSM,);
152 CARLA_SAFE_ASSERT_RETURN(libjackSetup[5] >= '0' && libjackSetup[5] < '0'+0x4f,);
154 std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6);
155 std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6);
156 std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6);
157 std::memcpy(fBaseNameNonRtServerControl, shmIds+6*3, 6);
159 fBaseNameAudioPool[6] = '\0';
160 fBaseNameRtClientControl[6] = '\0';
161 fBaseNameNonRtClientControl[6] = '\0';
162 fBaseNameNonRtServerControl[6] = '\0';
164 fServer.numAudioIns = static_cast<uint8_t>(libjackSetup[0] - '0');
165 fServer.numAudioOuts = static_cast<uint8_t>(libjackSetup[1] - '0');
166 fServer.numMidiIns = static_cast<uint8_t>(libjackSetup[2] - '0');
167 fServer.numMidiOuts = static_cast<uint8_t>(libjackSetup[3] - '0');
169 fSessionManager = static_cast<uint>(libjackSetup[4] - '0');
170 fSetupHints = static_cast<uint>(libjackSetup[5] - '0');
172 if (fSetupHints & LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN)
173 fServer.numMidiOuts = 16;
175 jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_HINTS_AND_CALLBACK,
176 fSetupHints,
177 (void*)carla_interposed_callback);
179 jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SET_SESSION_MANAGER,
180 fSessionManager,
181 nullptr);
183 fNonRealtimeThread.startThread(false);
185 fInitialized = true;
186 carla_debug("CarlaJackAppClient::CarlaJackAppClient() DONE");
189 ~CarlaJackAppClient() noexcept override
191 carla_debug("CarlaJackAppClient::~CarlaJackAppClient() START");
193 fLastPingTime = -1;
195 fNonRealtimeThread.stopThread(5000);
198 const CarlaMutexLocker cms(fRealtimeThreadMutex);
200 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
202 JackClientState* const jclient(it.getValue(nullptr));
203 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
205 delete jclient;
208 fClients.clear();
209 fNewClients.clear();
212 clearSharedMemory();
214 carla_debug("CarlaJackAppClient::~CarlaJackAppClient() DONE");
217 JackClientState* createClient(const char* const name)
219 if (! fInitialized)
220 return nullptr;
222 while (fNonRealtimeThread.isThreadRunning() && ! fIsReady)
223 carla_sleep(1);
225 return new JackClientState(fServer, name);
228 void destroyClient(JackClientState* const jclient)
231 const CarlaMutexLocker cms(fRealtimeThreadMutex);
232 fClients.removeOne(jclient);
235 delete jclient;
238 bool activateClient(JackClientState* const jclient)
240 const CarlaMutexLocker cms(fRealtimeThreadMutex);
242 if (! fClients.append(jclient))
243 return false;
244 if (! fNewClients.append(jclient))
246 fClients.removeOne(jclient);
247 return false;
250 jclient->activated = true;
251 jclient->deactivated = false;
252 return true;
255 bool deactivateClient(JackClientState* const jclient)
257 const CarlaMutexLocker cms(fRealtimeThreadMutex);
259 if (! fClients.removeOne(jclient))
260 return false;
262 jclient->activated = false;
263 jclient->deactivated = true;
264 return true;
267 const char* getClientNameFromUUID(const jack_uuid_t uuid) const noexcept
269 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
271 JackClientState* const jclient(it.getValue(nullptr));
272 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
274 if (jclient->uuid == uuid)
275 return jclient->name;
278 return nullptr;
281 jack_uuid_t getUUIDForClientName(const char* const name) const noexcept
283 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
285 JackClientState* const jclient(it.getValue(nullptr));
286 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
288 if (std::strcmp(jclient->name, name) == 0)
289 return jclient->uuid;
292 return JACK_UUID_EMPTY_INITIALIZER;
295 pthread_t getRealtimeThreadId() const noexcept
297 return (pthread_t)fRealtimeThread.getThreadId();
300 int handleInterposerCallback(const int cb_action, void* const ptr)
302 carla_debug("handleInterposerCallback(%o, %p)", cb_action, ptr);
304 switch (cb_action)
306 case LIBJACK_INTERPOSER_CALLBACK_UI_HIDE: {
307 const CarlaMutexLocker cml(fShmNonRtServerControl.mutex);
308 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
309 fShmNonRtServerControl.commitWrite();
310 break;
314 return 0;
316 // maybe unused
317 (void)ptr;
320 // -------------------------------------------------------------------
322 protected:
323 void runRealtimeThread() override;
324 void runNonRealtimeThread() override;
326 private:
327 bool initSharedMemmory();
328 void clearSharedMemory() noexcept;
330 bool handleRtData();
331 bool handleNonRtData();
333 BridgeAudioPool fShmAudioPool;
334 BridgeRtClientControl fShmRtClientControl;
335 BridgeNonRtClientControl fShmNonRtClientControl;
336 BridgeNonRtServerControl fShmNonRtServerControl;
338 float* fAudioPoolCopy;
339 float* fAudioTmpBuf;
341 JackMidiPortBufferDummy fDummyMidiInBuffer;
342 JackMidiPortBufferDummy fDummyMidiOutBuffer;
343 JackMidiPortBufferOnStack* fMidiInBuffers;
344 JackMidiPortBufferOnStack* fMidiOutBuffers;
346 char fBaseNameAudioPool[6+1];
347 char fBaseNameRtClientControl[6+1];
348 char fBaseNameNonRtClientControl[6+1];
349 char fBaseNameNonRtServerControl[6+1];
351 bool fInitialized;
352 bool fIsOffline;
353 volatile bool fIsReady;
354 int64_t fLastPingTime;
356 uint fSessionManager;
357 uint fSetupHints;
359 CarlaJackRealtimeThread fRealtimeThread;
360 CarlaJackNonRealtimeThread fNonRealtimeThread;
362 CarlaMutex fRealtimeThreadMutex;
364 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaJackAppClient)
367 // ---------------------------------------------------------------------------------------------------------------------
369 bool CarlaJackAppClient::initSharedMemmory()
371 if (! fShmAudioPool.attachClient(fBaseNameAudioPool))
373 carla_stderr("Failed to attach to audio pool shared memory");
374 return false;
377 if (! fShmRtClientControl.attachClient(fBaseNameRtClientControl))
379 clearSharedMemory();
380 carla_stderr("Failed to attach to rt client control shared memory");
381 return false;
384 if (! fShmRtClientControl.mapData())
386 clearSharedMemory();
387 carla_stderr("Failed to map rt client control shared memory");
388 return false;
391 if (! fShmNonRtClientControl.attachClient(fBaseNameNonRtClientControl))
393 clearSharedMemory();
394 carla_stderr("Failed to attach to non-rt client control shared memory");
395 return false;
398 if (! fShmNonRtClientControl.mapData())
400 clearSharedMemory();
401 carla_stderr("Failed to map non-rt control client shared memory");
402 return false;
405 if (! fShmNonRtServerControl.attachClient(fBaseNameNonRtServerControl))
407 clearSharedMemory();
408 carla_stderr("Failed to attach to non-rt server control shared memory");
409 return false;
412 if (! fShmNonRtServerControl.mapData())
414 clearSharedMemory();
415 carla_stderr("Failed to map non-rt control server shared memory");
416 return false;
419 PluginBridgeNonRtClientOpcode opcode;
421 opcode = fShmNonRtClientControl.readOpcode();
422 CARLA_SAFE_ASSERT_RETURN(opcode == kPluginBridgeNonRtClientVersion, false);
424 const uint32_t apiVersion = fShmNonRtClientControl.readUInt();
425 CARLA_SAFE_ASSERT_RETURN(apiVersion == CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT, false);
427 const uint32_t shmRtClientDataSize = fShmNonRtClientControl.readUInt();
428 CARLA_SAFE_ASSERT_INT2(shmRtClientDataSize == sizeof(BridgeRtClientData), shmRtClientDataSize, sizeof(BridgeRtClientData));
430 const uint32_t shmNonRtClientDataSize = fShmNonRtClientControl.readUInt();
431 CARLA_SAFE_ASSERT_INT2(shmNonRtClientDataSize == sizeof(BridgeNonRtClientData), shmNonRtClientDataSize, sizeof(BridgeNonRtClientData));
433 const uint32_t shmNonRtServerDataSize = fShmNonRtClientControl.readUInt();
434 CARLA_SAFE_ASSERT_INT2(shmNonRtServerDataSize == sizeof(BridgeNonRtServerData), shmNonRtServerDataSize, sizeof(BridgeNonRtServerData));
436 if (shmRtClientDataSize != sizeof(BridgeRtClientData) ||
437 shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) ||
438 shmNonRtServerDataSize != sizeof(BridgeNonRtServerData))
440 carla_stderr2("CarlaJackAppClient: data size mismatch");
441 return false;
444 opcode = fShmNonRtClientControl.readOpcode();
445 CARLA_SAFE_ASSERT_RETURN(opcode == kPluginBridgeNonRtClientInitialSetup, false);
447 fServer.bufferSize = fShmNonRtClientControl.readUInt();
448 fServer.sampleRate = fShmNonRtClientControl.readDouble();
450 if (fServer.bufferSize == 0 || carla_isZero(fServer.sampleRate))
452 carla_stderr2("CarlaJackAppClient: invalid empty state");
453 return false;
456 fAudioTmpBuf = new float[fServer.bufferSize];
457 carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
459 fLastPingTime = getCurrentTimeMilliseconds();
460 CARLA_SAFE_ASSERT(fLastPingTime > 0);
463 // tell backend we're live
464 const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
466 // ready!
467 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady);
468 fShmNonRtServerControl.commitWrite();
469 fShmNonRtServerControl.waitIfDataIsReachingLimit();
472 fIsReady = true;
473 return true;
476 void CarlaJackAppClient::clearSharedMemory() noexcept
478 const CarlaMutexLocker cml(fRealtimeThreadMutex);
480 if (fAudioPoolCopy != nullptr)
482 delete[] fAudioPoolCopy;
483 fAudioPoolCopy = nullptr;
486 if (fAudioTmpBuf != nullptr)
488 delete[] fAudioTmpBuf;
489 fAudioTmpBuf = nullptr;
492 if (fMidiInBuffers != nullptr)
494 delete[] fMidiInBuffers;
495 fMidiInBuffers = nullptr;
498 if (fMidiOutBuffers != nullptr)
500 delete[] fMidiOutBuffers;
501 fMidiOutBuffers = nullptr;
504 fShmAudioPool.clear();
505 fShmRtClientControl.clear();
506 fShmNonRtClientControl.clear();
507 fShmNonRtServerControl.clear();
510 bool CarlaJackAppClient::handleRtData()
512 if (fNewClients.count() != 0)
514 for (LinkedList<JackClientState*>::Itenerator it = fNewClients.begin2(); it.valid(); it.next())
516 JackClientState* const jclient(it.getValue(nullptr));
517 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
519 if (jclient->threadInitCb != nullptr)
520 jclient->threadInitCb(jclient->threadInitCbPtr);
523 fNewClients.clear();
526 const BridgeRtClientControl::WaitHelper helper(fShmRtClientControl);
528 if (! helper.ok)
529 return false;
531 bool ret = false;
533 for (; fShmRtClientControl.isDataAvailableForReading();)
535 const PluginBridgeRtClientOpcode opcode(fShmRtClientControl.readOpcode());
536 #ifdef DEBUG
537 if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
538 carla_debug("CarlaJackAppClientRtThread::run() - got opcode: %s", PluginBridgeRtClientOpcode2str(opcode));
540 #endif
542 switch (opcode)
544 case kPluginBridgeRtClientNull:
545 break;
547 case kPluginBridgeRtClientSetAudioPool: {
548 const CarlaMutexLocker cml(fRealtimeThreadMutex);
550 if (fShmAudioPool.data != nullptr)
552 jackbridge_shm_unmap(fShmAudioPool.shm, fShmAudioPool.data);
553 fShmAudioPool.data = nullptr;
555 if (fAudioPoolCopy != nullptr)
557 delete[] fAudioPoolCopy;
558 fAudioPoolCopy = nullptr;
560 const uint64_t poolSize(fShmRtClientControl.readULong());
561 CARLA_SAFE_ASSERT_BREAK(poolSize > 0);
562 fShmAudioPool.data = (float*)jackbridge_shm_map(fShmAudioPool.shm, static_cast<size_t>(poolSize));
563 fAudioPoolCopy = new float[poolSize];
564 break;
567 case kPluginBridgeRtClientSetBufferSize:
568 if (const uint32_t newBufferSize = fShmRtClientControl.readUInt())
570 if (fServer.bufferSize != newBufferSize)
572 const CarlaMutexLocker cml(fRealtimeThreadMutex);
574 fServer.bufferSize = newBufferSize;
576 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
578 JackClientState* const jclient(it.getValue(nullptr));
579 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
581 if (jclient->bufferSizeCb != nullptr)
582 jclient->bufferSizeCb(fServer.bufferSize, jclient->bufferSizeCbPtr);
585 delete[] fAudioTmpBuf;
586 fAudioTmpBuf = new float[fServer.bufferSize];
587 carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
590 break;
592 case kPluginBridgeRtClientSetSampleRate: {
593 const double newSampleRate = fShmRtClientControl.readDouble();
595 if (carla_isNotZero(newSampleRate) && carla_isNotEqual(fServer.sampleRate, newSampleRate))
597 const CarlaMutexLocker cml(fRealtimeThreadMutex);
599 fServer.sampleRate = newSampleRate;
601 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
603 JackClientState* const jclient(it.getValue(nullptr));
604 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
606 if (jclient->sampleRateCb != nullptr)
607 jclient->sampleRateCb(static_cast<uint32_t>(fServer.sampleRate), jclient->sampleRateCbPtr);
610 } break;
612 case kPluginBridgeRtClientSetOnline: {
613 const bool offline = fShmRtClientControl.readBool();
615 if (fIsOffline != offline)
617 const CarlaMutexLocker cml(fRealtimeThreadMutex);
619 fIsOffline = offline;
621 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
623 JackClientState* const jclient(it.getValue(nullptr));
624 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
626 if (jclient->freewheelCb != nullptr)
627 jclient->freewheelCb(offline ? 1 : 0, jclient->freewheelCbPtr);
630 } break;
632 case kPluginBridgeRtClientControlEventParameter:
633 break;
635 case kPluginBridgeRtClientControlEventMidiBank: {
636 const uint32_t time = fShmRtClientControl.readUInt();
637 const uint8_t channel = fShmRtClientControl.readByte();
638 const uint16_t value = fShmRtClientControl.readUShort();
640 if (fServer.numMidiIns > 0 && fRealtimeThreadMutex.tryLock())
642 JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[0]);
644 if (midiPortBuf.count+1U < JackMidiPortBufferBase::kMaxEventCount &&
645 midiPortBuf.bufferPoolPos + 6U < JackMidiPortBufferBase::kBufferPoolSize)
647 jack_midi_event_t& ev1(midiPortBuf.events[midiPortBuf.count++]);
648 ev1.time = time;
649 ev1.size = 3;
650 ev1.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
651 ev1.buffer[0] = jack_midi_data_t(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
652 ev1.buffer[1] = MIDI_CONTROL_BANK_SELECT;
653 ev1.buffer[2] = 0;
654 midiPortBuf.bufferPoolPos += 3;
656 jack_midi_event_t& ev2(midiPortBuf.events[midiPortBuf.count++]);
657 ev2.time = time;
658 ev2.size = 3;
659 ev2.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
660 ev2.buffer[0] = jack_midi_data_t(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
661 ev2.buffer[1] = MIDI_CONTROL_BANK_SELECT__LSB;
662 ev2.buffer[2] = jack_midi_data_t(value);
663 midiPortBuf.bufferPoolPos += 3;
666 fRealtimeThreadMutex.unlock(true);
668 break;
671 case kPluginBridgeRtClientControlEventMidiProgram: {
672 const uint32_t time = fShmRtClientControl.readUInt();
673 const uint8_t channel = fShmRtClientControl.readByte();
674 const uint16_t value = fShmRtClientControl.readUShort();
676 if (fServer.numMidiIns > 0 && fRealtimeThreadMutex.tryLock())
678 JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[0]);
680 if (midiPortBuf.count < JackMidiPortBufferBase::kMaxEventCount &&
681 midiPortBuf.bufferPoolPos + 2U < JackMidiPortBufferBase::kBufferPoolSize)
683 jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
685 ev.time = time;
686 ev.size = 2;
687 ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
688 ev.buffer[0] = jack_midi_data_t(MIDI_STATUS_PROGRAM_CHANGE | (channel & MIDI_CHANNEL_BIT));
689 ev.buffer[1] = jack_midi_data_t(value);
690 midiPortBuf.bufferPoolPos += 2;
693 fRealtimeThreadMutex.unlock(true);
695 break;
698 case kPluginBridgeRtClientControlEventAllSoundOff: {
699 const uint32_t time = fShmRtClientControl.readUInt();
700 const uint8_t channel = fShmRtClientControl.readByte();
702 if (fServer.numMidiIns > 0 && fRealtimeThreadMutex.tryLock())
704 JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[0]);
706 if (midiPortBuf.count < JackMidiPortBufferBase::kMaxEventCount &&
707 midiPortBuf.bufferPoolPos + 3U < JackMidiPortBufferBase::kBufferPoolSize)
709 jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
711 ev.time = time;
712 ev.size = 3;
713 ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
714 ev.buffer[0] = jack_midi_data_t(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
715 ev.buffer[1] = MIDI_CONTROL_ALL_SOUND_OFF;
716 ev.buffer[2] = 0;
717 midiPortBuf.bufferPoolPos += 3;
720 fRealtimeThreadMutex.unlock(true);
722 break;
725 case kPluginBridgeRtClientControlEventAllNotesOff: {
726 const uint32_t time = fShmRtClientControl.readUInt();
727 const uint8_t channel = fShmRtClientControl.readByte();
729 if (fServer.numMidiIns > 0 && fRealtimeThreadMutex.tryLock())
731 JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[0]);
733 if (midiPortBuf.count < JackMidiPortBufferBase::kMaxEventCount &&
734 midiPortBuf.bufferPoolPos + 3U < JackMidiPortBufferBase::kBufferPoolSize)
736 jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
738 ev.time = time;
739 ev.size = 3;
740 ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
741 ev.buffer[0] = jack_midi_data_t(MIDI_STATUS_CONTROL_CHANGE | (channel & MIDI_CHANNEL_BIT));
742 ev.buffer[1] = MIDI_CONTROL_ALL_NOTES_OFF;
743 ev.buffer[2] = 0;
744 midiPortBuf.bufferPoolPos += 3;
747 fRealtimeThreadMutex.unlock(true);
749 break;
752 case kPluginBridgeRtClientMidiEvent: {
753 const uint32_t time = fShmRtClientControl.readUInt();
754 const uint8_t port = fShmRtClientControl.readByte();
755 const uint8_t size = fShmRtClientControl.readByte();
756 CARLA_SAFE_ASSERT_BREAK(size > 0);
758 if (port >= fServer.numMidiIns || size > JackMidiPortBufferBase::kMaxEventSize || ! fRealtimeThreadMutex.tryLock())
760 for (uint8_t i=0; i<size; ++i)
761 fShmRtClientControl.readByte();
762 break;
765 JackMidiPortBufferOnStack& midiPortBuf(fMidiInBuffers[port]);
767 if (midiPortBuf.count < JackMidiPortBufferBase::kMaxEventCount &&
768 midiPortBuf.bufferPoolPos + size < JackMidiPortBufferBase::kBufferPoolSize)
770 jack_midi_event_t& ev(midiPortBuf.events[midiPortBuf.count++]);
772 ev.time = time;
773 ev.size = size;
774 ev.buffer = midiPortBuf.bufferPool + midiPortBuf.bufferPoolPos;
775 midiPortBuf.bufferPoolPos += size;
777 for (uint8_t i=0; i<size; ++i)
778 ev.buffer[i] = fShmRtClientControl.readByte();
781 fRealtimeThreadMutex.unlock(true);
782 break;
785 case kPluginBridgeRtClientProcess: {
786 const uint32_t frames(fShmRtClientControl.readUInt());
787 CARLA_SAFE_ASSERT_UINT2_BREAK(frames == fServer.bufferSize, frames, fServer.bufferSize);
789 // TODO tell client of xrun in case buffersize does not match
791 const CarlaMutexTryLocker cmtl(fRealtimeThreadMutex, fIsOffline);
793 if (cmtl.wasLocked())
795 CARLA_SAFE_ASSERT_BREAK(fShmAudioPool.data != nullptr);
797 // mixdown is default, do buffer addition (for multiple clients) if requested
798 const bool doBufferAddition = fSetupHints & LIBJACK_FLAG_AUDIO_BUFFERS_ADDITION;
799 // mixdown midi outputs based on channel if requested
800 const bool doMidiChanMixdown = fSetupHints & LIBJACK_FLAG_MIDI_OUTPUT_CHANNEL_MIXDOWN;
802 // location to start of audio outputs (shm buffer)
803 float* const fdataRealOuts = fShmAudioPool.data+(fServer.bufferSize*fServer.numAudioIns);
805 if (doBufferAddition && fServer.numAudioOuts > 0)
806 carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
808 if (! fClients.isEmpty())
810 // save transport for all clients
811 const BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);
813 const bool transportChanged = fServer.playing != bridgeTimeInfo.playing ||
814 (bridgeTimeInfo.playing && fServer.position.frame + frames != bridgeTimeInfo.frame);
816 fServer.playing = bridgeTimeInfo.playing;
817 fServer.position.frame = static_cast<jack_nframes_t>(bridgeTimeInfo.frame);
818 fServer.position.usecs = bridgeTimeInfo.usecs;
820 fServer.position.frame_rate = static_cast<jack_nframes_t>(fServer.sampleRate);
822 if (bridgeTimeInfo.validFlags & kPluginBridgeTimeInfoValidBBT)
824 fServer.position.bar = bridgeTimeInfo.bar;
825 fServer.position.beat = bridgeTimeInfo.beat;
826 fServer.position.tick = static_cast<int32_t>(bridgeTimeInfo.tick + 0.5);
828 fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
829 fServer.position.beat_type = bridgeTimeInfo.beatType;
831 fServer.position.ticks_per_beat = bridgeTimeInfo.ticksPerBeat;
832 fServer.position.beats_per_minute = bridgeTimeInfo.beatsPerMinute;
833 fServer.position.bar_start_tick = bridgeTimeInfo.barStartTick;
835 #ifdef JACK_TICK_DOUBLE
836 fServer.position.tick_double = bridgeTimeInfo.tick;
837 fServer.position.valid = static_cast<jack_position_bits_t>(JackPositionBBT|JackTickDouble);
838 #else
839 fServer.position.valid = JackPositionBBT;
840 #endif
842 else
844 fServer.position.valid = static_cast<jack_position_bits_t>(0x0);
847 int numClientOutputsProcessed = 0;
849 // now go through each client
850 for (LinkedList<JackClientState*>::Itenerator it = fClients.begin2(); it.valid(); it.next())
852 JackClientState* const jclient(it.getValue(nullptr));
853 CARLA_SAFE_ASSERT_CONTINUE(jclient != nullptr);
855 const CarlaMutexTryLocker cmtl2(jclient->mutex, fIsOffline);
857 // check if we can process
858 if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated)
860 if (fServer.numAudioOuts > 0)
861 carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
863 if (jclient->deactivated)
864 fShmRtClientControl.data->procFlags = 1;
866 else
868 // report transport sync changes if needed
869 if (transportChanged && jclient->syncCb != nullptr)
871 jclient->syncCb(fServer.playing ? JackTransportRolling : JackTransportStopped,
872 &fServer.position,
873 jclient->syncCbPtr);
876 uint8_t i;
877 // direct access to shm buffer, used only for inputs
878 float* fdataReal = fShmAudioPool.data;
879 // safe temp location for output, mixed down to shm buffer later on
880 float* fdataCopy = fAudioPoolCopy;
881 // wherever we're using fAudioTmpBuf
882 bool needsTmpBufClear = false;
884 // set audio inputs
885 i = 0;
886 for (LinkedList<JackPortState*>::Itenerator it2 = jclient->audioIns.begin2(); it2.valid(); it2.next())
888 JackPortState* const jport = it2.getValue(nullptr);
889 CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
891 if (i++ < fServer.numAudioIns)
893 if (numClientOutputsProcessed == 0 || ! doBufferAddition)
894 jport->buffer = fdataReal;
895 else
896 jport->buffer = fdataRealOuts + (i*fServer.bufferSize);
898 fdataReal += fServer.bufferSize;
899 fdataCopy += fServer.bufferSize;
901 else
903 jport->buffer = fAudioTmpBuf;
904 needsTmpBufClear = true;
907 if (i < fServer.numAudioIns)
909 const std::size_t remainingBufferSize = fServer.bufferSize * static_cast<uint8_t>(fServer.numAudioIns - i);
910 //fdataReal += remainingBufferSize;
911 fdataCopy += remainingBufferSize;
914 // location to start of audio outputs
915 float* const fdataCopyOuts = fdataCopy;
917 // set audio outputs
918 i = 0;
919 for (LinkedList<JackPortState*>::Itenerator it2 = jclient->audioOuts.begin2(); it2.valid(); it2.next())
921 JackPortState* const jport = it2.getValue(nullptr);
922 CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
924 if (i++ < fServer.numAudioOuts)
926 jport->buffer = fdataCopy;
927 fdataCopy += fServer.bufferSize;
929 else
931 jport->buffer = fAudioTmpBuf;
932 needsTmpBufClear = true;
935 if (i < fServer.numAudioOuts)
937 const std::size_t remainingBufferSize = fServer.bufferSize * static_cast<uint8_t>(fServer.numAudioOuts - i);
938 carla_zeroFloats(fdataCopy, remainingBufferSize);
939 //fdataCopy += remainingBufferSize;
942 // set midi inputs
943 i = 0;
944 for (LinkedList<JackPortState*>::Itenerator it2 = jclient->midiIns.begin2(); it2.valid(); it2.next())
946 JackPortState* const jport = it2.getValue(nullptr);
947 CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
949 if (i++ < fServer.numMidiIns)
950 jport->buffer = &fMidiInBuffers[i-1];
951 else
952 jport->buffer = &fDummyMidiInBuffer;
955 // set midi outputs
956 i = 0;
957 for (LinkedList<JackPortState*>::Itenerator it2 = jclient->midiOuts.begin2(); it2.valid(); it2.next())
959 JackPortState* const jport = it2.getValue(nullptr);
960 CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr);
962 if (i++ < fServer.numMidiOuts)
963 jport->buffer = &fMidiOutBuffers[i-1];
964 else
965 jport->buffer = &fDummyMidiOutBuffer;
968 if (needsTmpBufClear)
969 carla_zeroFloats(fAudioTmpBuf, fServer.bufferSize);
971 jclient->processCb(fServer.bufferSize, jclient->processCbPtr);
973 if (fServer.numAudioOuts > 0)
975 if (++numClientOutputsProcessed == 1)
977 // first client, we can copy stuff over
978 carla_copyFloats(fdataRealOuts, fdataCopyOuts,
979 fServer.bufferSize*fServer.numAudioOuts);
981 else
983 // subsequent clients, add data (then divide by number of clients later on)
984 carla_add(fdataRealOuts, fdataCopyOuts,
985 fServer.bufferSize*fServer.numAudioOuts);
987 if (doBufferAddition)
989 // for more than 1 client addition, we need to divide buffers now
990 carla_multiply(fdataRealOuts,
991 1.0f/static_cast<float>(numClientOutputsProcessed),
992 fServer.bufferSize*fServer.numAudioOuts);
996 if (jclient->audioOuts.count() == 1 && fServer.numAudioOuts > 1)
998 for (uint8_t j=1; j<fServer.numAudioOuts; ++j)
1000 carla_copyFloats(fdataRealOuts+(fServer.bufferSize*j),
1001 fdataCopyOuts,
1002 fServer.bufferSize);
1009 if (numClientOutputsProcessed > 1 && ! doBufferAddition)
1011 // more than 1 client active, need to divide buffers
1012 carla_multiply(fdataRealOuts,
1013 1.0f/static_cast<float>(numClientOutputsProcessed),
1014 fServer.bufferSize*fServer.numAudioOuts);
1017 // fClients.isEmpty()
1018 else if (fServer.numAudioOuts > 0)
1020 carla_zeroFloats(fdataRealOuts, fServer.bufferSize*fServer.numAudioOuts);
1023 for (uint8_t i=0; i<fServer.numMidiIns; ++i)
1025 fMidiInBuffers[i].count = 0;
1026 fMidiInBuffers[i].bufferPoolPos = 0;
1029 if (fServer.numMidiOuts > 0)
1031 uint8_t* midiData = fShmRtClientControl.data->midiOut;
1032 carla_zeroBytes(midiData, kBridgeBaseMidiOutHeaderSize);
1033 std::size_t curMidiDataPos = 0;
1035 for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
1037 JackMidiPortBufferOnStack& midiPortBuf(fMidiOutBuffers[i]);
1039 for (uint16_t j=0; j<midiPortBuf.count; ++j)
1041 jack_midi_event_t& jmevent(midiPortBuf.events[j]);
1043 if (curMidiDataPos + kBridgeBaseMidiOutHeaderSize + jmevent.size >= kBridgeRtClientDataMidiOutSize)
1044 break;
1046 if (doMidiChanMixdown && MIDI_IS_CHANNEL_MESSAGE(jmevent.buffer[0]))
1047 jmevent.buffer[0] = static_cast<jack_midi_data_t>(
1048 (jmevent.buffer[0] & MIDI_STATUS_BIT) | (i & MIDI_CHANNEL_BIT));
1050 // set time
1051 *(uint32_t*)midiData = jmevent.time;
1052 midiData += 4;
1054 // set port
1055 *midiData++ = doMidiChanMixdown ? 0 : i;
1057 // set size
1058 *midiData++ = static_cast<uint8_t>(jmevent.size);
1060 // set data
1061 std::memcpy(midiData, jmevent.buffer, jmevent.size);
1062 midiData += jmevent.size;
1064 curMidiDataPos += kBridgeBaseMidiOutHeaderSize + jmevent.size;
1068 // make last event null, so server stops when reaching it
1069 if (curMidiDataPos != 0 &&
1070 curMidiDataPos + kBridgeBaseMidiOutHeaderSize < kBridgeRtClientDataMidiOutSize)
1072 carla_zeroBytes(midiData, kBridgeBaseMidiOutHeaderSize);
1074 // sort events in case of mixdown
1075 if (doMidiChanMixdown)
1077 uint32_t time;
1078 uint8_t size, *midiDataPtr;
1079 uint8_t tmp[kBridgeBaseMidiOutHeaderSize + JackMidiPortBufferBase::kMaxEventSize];
1080 bool wasSorted = true;
1082 for (; wasSorted;)
1084 midiDataPtr = fShmRtClientControl.data->midiOut;
1085 uint8_t* prevData = midiDataPtr;
1086 uint32_t prevTime = *(uint32_t*)midiDataPtr;
1087 uint8_t prevSize = *(midiDataPtr + 5);
1088 wasSorted = false;
1090 for (;;)
1092 time = *(uint32_t*)midiDataPtr;
1093 size = *(midiDataPtr + 5); // time and port
1095 if (size == 0)
1096 break;
1098 if (prevTime > time)
1100 // copy previous data to a temporary place
1101 std::memcpy(tmp, prevData, kBridgeBaseMidiOutHeaderSize + prevSize);
1102 // override previous data with new one (shifting left)
1103 std::memcpy(prevData, midiDataPtr, kBridgeBaseMidiOutHeaderSize + size);
1104 // override new data with old one
1105 std::memcpy(midiDataPtr, tmp, kBridgeBaseMidiOutHeaderSize + prevSize);
1106 // done swapping, flag it
1107 wasSorted = true;
1110 prevTime = time;
1111 prevSize = size;
1112 prevData = midiDataPtr;
1113 midiDataPtr += 6 + size;
1120 else
1122 carla_stderr2("CarlaJackAppClient: fRealtimeThreadMutex tryLock failed");
1124 fServer.monotonic_frame += frames;
1125 break;
1128 case kPluginBridgeRtClientQuit:
1129 ret = true;
1130 break;
1133 #ifdef DEBUG
1134 if (opcode != kPluginBridgeRtClientProcess && opcode != kPluginBridgeRtClientMidiEvent) {
1135 carla_debug("CarlaJackAppClientRtThread::run() - opcode %s done", PluginBridgeRtClientOpcode2str(opcode));
1137 #endif
1140 return ret;
1143 bool CarlaJackAppClient::handleNonRtData()
1145 bool ret = false;
1147 for (; fShmNonRtClientControl.isDataAvailableForReading();)
1149 const PluginBridgeNonRtClientOpcode opcode(fShmNonRtClientControl.readOpcode());
1150 #ifdef DEBUG
1151 if (opcode != kPluginBridgeNonRtClientPing) {
1152 carla_debug("CarlaJackAppClient::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode));
1154 #endif
1156 if (opcode != kPluginBridgeNonRtClientNull && opcode != kPluginBridgeNonRtClientPingOnOff && fLastPingTime > 0)
1157 fLastPingTime = getCurrentTimeMilliseconds();
1159 switch (opcode)
1161 case kPluginBridgeNonRtClientNull:
1162 break;
1164 case kPluginBridgeNonRtClientVersion: {
1165 const uint apiVersion = fShmNonRtServerControl.readUInt();
1166 CARLA_SAFE_ASSERT_UINT2(apiVersion == CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT,
1167 apiVersion, CARLA_PLUGIN_BRIDGE_API_VERSION_CURRENT);
1168 } break;
1170 case kPluginBridgeNonRtClientPing: {
1171 const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
1173 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong);
1174 fShmNonRtServerControl.commitWrite();
1175 } break;
1177 case kPluginBridgeNonRtClientPingOnOff: {
1178 const uint32_t onOff(fShmNonRtClientControl.readBool());
1180 fLastPingTime = onOff ? getCurrentTimeMilliseconds() : -1;
1181 } break;
1183 case kPluginBridgeNonRtClientActivate:
1184 case kPluginBridgeNonRtClientDeactivate:
1185 break;
1187 case kPluginBridgeNonRtClientInitialSetup:
1188 // should never happen!!
1189 fShmNonRtServerControl.readUInt();
1190 fShmNonRtServerControl.readDouble();
1191 break;
1193 case kPluginBridgeNonRtClientSetParameterValue:
1194 case kPluginBridgeNonRtClientSetParameterMidiChannel:
1195 case kPluginBridgeNonRtClientSetParameterMappedControlIndex:
1196 case kPluginBridgeNonRtClientSetParameterMappedRange:
1197 case kPluginBridgeNonRtClientSetProgram:
1198 case kPluginBridgeNonRtClientSetMidiProgram:
1199 case kPluginBridgeNonRtClientSetCustomData:
1200 case kPluginBridgeNonRtClientSetChunkDataFile:
1201 case kPluginBridgeNonRtClientSetWindowTitle:
1202 break;
1204 case kPluginBridgeNonRtClientSetOption:
1205 fShmNonRtClientControl.readUInt();
1206 fShmNonRtClientControl.readBool();
1207 break;
1209 case kPluginBridgeNonRtClientSetOptions:
1210 fShmNonRtClientControl.readUInt();
1211 break;
1213 case kPluginBridgeNonRtClientSetCtrlChannel:
1214 fShmNonRtClientControl.readShort();
1215 break;
1217 case kPluginBridgeNonRtClientGetParameterText:
1218 fShmNonRtClientControl.readUInt();
1219 break;
1221 case kPluginBridgeNonRtClientPrepareForSave:
1223 if (fSessionManager == LIBJACK_SESSION_MANAGER_AUTO && std::getenv("NSM_URL") == nullptr)
1225 struct sigaction sig;
1226 carla_zeroStruct(sig);
1228 sigaction(SIGUSR1, nullptr, &sig);
1230 if (sig.sa_handler != nullptr)
1231 fSessionManager = LIBJACK_SESSION_MANAGER_LADISH;
1234 if (fSessionManager == LIBJACK_SESSION_MANAGER_LADISH)
1235 ::kill(::getpid(), SIGUSR1);
1237 const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
1239 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerSaved);
1240 fShmNonRtServerControl.commitWrite();
1242 break;
1244 case kPluginBridgeNonRtClientRestoreLV2State:
1245 break;
1247 case kPluginBridgeNonRtClientShowUI:
1248 if (jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SHOW_HIDE_GUI, 1, nullptr) == 1337)
1250 // failed, LD_PRELOAD did not work?
1251 const char* const message("Cannot show UI, LD_PRELOAD not working?");
1252 const std::size_t messageSize(std::strlen(message));
1254 const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
1256 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerUiClosed);
1257 fShmNonRtServerControl.commitWrite();
1259 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
1260 fShmNonRtServerControl.writeUInt(messageSize);
1261 fShmNonRtServerControl.writeCustomData(message, messageSize);
1262 fShmNonRtServerControl.commitWrite();
1264 break;
1266 case kPluginBridgeNonRtClientHideUI:
1267 jack_carla_interposed_action(LIBJACK_INTERPOSER_ACTION_SHOW_HIDE_GUI, 0, nullptr);
1268 break;
1270 case kPluginBridgeNonRtClientUiParameterChange:
1271 case kPluginBridgeNonRtClientUiProgramChange:
1272 case kPluginBridgeNonRtClientUiMidiProgramChange:
1273 case kPluginBridgeNonRtClientUiNoteOn:
1274 case kPluginBridgeNonRtClientUiNoteOff:
1275 break;
1277 case kPluginBridgeNonRtClientEmbedUI:
1278 fShmNonRtClientControl.readULong();
1279 break;
1281 case kPluginBridgeNonRtClientQuit:
1282 ret = true;
1283 break;
1285 case kPluginBridgeNonRtClientReload:
1286 break;
1289 #ifdef DEBUG
1290 if (opcode != kPluginBridgeNonRtClientPing) {
1291 carla_debug("CarlaJackAppClient::handleNonRtData() - opcode %s handled", PluginBridgeNonRtClientOpcode2str(opcode));
1293 #endif
1296 return ret;
1299 void CarlaJackAppClient::runRealtimeThread()
1301 carla_debug("CarlaJackAppClient runRealtimeThread START");
1303 #ifdef __SSE2_MATH__
1304 // Set FTZ and DAZ flags
1305 _mm_setcsr(_mm_getcsr() | 0x8040);
1306 #endif
1308 bool quitReceived = false;
1310 for (; ! fRealtimeThread.shouldThreadExit();)
1312 if (handleRtData())
1314 quitReceived = true;
1315 break;
1319 fNonRealtimeThread.signalThreadShouldExit();
1321 carla_debug("CarlaJackAppClient runRealtimeThread FINISHED");
1323 // TODO
1324 return; (void)quitReceived;
1327 void CarlaJackAppClient::runNonRealtimeThread()
1329 carla_debug("CarlaJackAppClient runNonRealtimeThread START");
1330 CARLA_SAFE_ASSERT_RETURN(initSharedMemmory(),);
1332 if (fServer.numMidiIns > 0)
1334 fMidiInBuffers = new JackMidiPortBufferOnStack[fServer.numMidiIns];
1336 for (uint8_t i=0; i<fServer.numMidiIns; ++i)
1337 fMidiInBuffers[i].isInput = true;
1340 if (fServer.numMidiOuts > 0)
1342 fMidiOutBuffers = new JackMidiPortBufferOnStack[fServer.numMidiOuts];
1344 for (uint8_t i=0; i<fServer.numMidiOuts; ++i)
1345 fMidiOutBuffers[i].isInput = false;
1348 fRealtimeThread.startThread(true);
1350 fLastPingTime = getCurrentTimeMilliseconds();
1351 carla_stdout("Carla Jack Client Ready!");
1353 bool quitReceived = false,
1354 timedOut = false;
1356 for (; ! fNonRealtimeThread.shouldThreadExit();)
1358 carla_msleep(50);
1360 try {
1361 quitReceived = handleNonRtData();
1362 } CARLA_SAFE_EXCEPTION("handleNonRtData");
1364 if (quitReceived)
1365 break;
1368 if (fLastPingTime > 0 && getCurrentTimeMilliseconds() > fLastPingTime + 30000)
1370 carla_stderr("Did not receive ping message from server for 30 secs, closing...");
1372 timedOut = true;
1373 fRealtimeThread.signalThreadShouldExit();
1374 break;
1379 //callback(true, true, ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
1381 if (quitReceived)
1383 ::kill(::getpid(), SIGTERM);
1385 else if (timedOut)
1387 // TODO send shutdown?
1388 carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended with time out");
1389 ::kill(::getpid(), SIGTERM);
1391 else
1393 bool activated;
1396 const CarlaMutexLocker cms(fRealtimeThreadMutex);
1398 if (fClients.isEmpty())
1400 activated = false;
1402 else if (JackClientState* const jclient = fClients.getLast(nullptr))
1404 const CarlaMutexLocker cms2(jclient->mutex);
1405 activated = jclient->activated;
1407 else
1409 activated = true;
1413 if (activated)
1415 carla_stderr("CarlaJackAppClient error: runNonRealtimeThread ended while client is activated");
1417 const char* const message("Plugin bridge error, process thread has stopped");
1418 const std::size_t messageSize(std::strlen(message));
1420 const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex);
1421 fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerError);
1422 fShmNonRtServerControl.writeUInt(messageSize);
1423 fShmNonRtServerControl.writeCustomData(message, messageSize);
1424 fShmNonRtServerControl.commitWrite();
1428 if (fRealtimeThread.isThreadRunning())
1430 fRealtimeThread.signalThreadShouldExit();
1432 const CarlaMutexLocker cml(fRealtimeThreadMutex);
1434 if (fShmRtClientControl.data != nullptr)
1435 fShmRtClientControl.data->procFlags = 1;
1438 clearSharedMemory();
1440 fRealtimeThread.stopThread(5000);
1442 carla_debug("CarlaJackAppClient runNonRealtimeThread FINISHED");
1445 CARLA_BACKEND_END_NAMESPACE
1447 // ---------------------------------------------------------------------------------------------------------------------
1449 using CARLA_BACKEND_NAMESPACE::CarlaJackAppClient;
1450 using CARLA_BACKEND_NAMESPACE::JackClientState;
1452 static CarlaJackAppClient gClient;
1454 CARLA_BACKEND_START_NAMESPACE
1456 static int carla_interposed_callback(int cb_action, void* ptr)
1458 return gClient.handleInterposerCallback(cb_action, ptr);
1461 CARLA_BACKEND_END_NAMESPACE
1463 // ---------------------------------------------------------------------------------------------------------------------
1465 CARLA_PLUGIN_EXPORT
1466 jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...)
1468 carla_debug("%s(%s, 0x%x, %p)", __FUNCTION__, client_name, options, status);
1470 if (JackClientState* const client = gClient.createClient(client_name))
1472 if (status != nullptr)
1473 *status = static_cast<JackStatus>(0x0);
1475 return (jack_client_t*)client;
1478 if (status != nullptr)
1479 *status = JackServerError;
1481 return nullptr;
1483 // unused
1484 (void)options;
1487 CARLA_PLUGIN_EXPORT
1488 jack_client_t* jack_client_new(const char* client_name)
1490 return jack_client_open(client_name, JackNullOption, nullptr);
1493 CARLA_PLUGIN_EXPORT
1494 int jack_client_close(jack_client_t* client)
1496 carla_debug("%s(%p)", __FUNCTION__, client);
1498 JackClientState* const jclient = (JackClientState*)client;
1499 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
1501 gClient.destroyClient(jclient);
1502 return 0;
1505 CARLA_PLUGIN_EXPORT
1506 int jack_activate(jack_client_t* client)
1508 carla_debug("%s(%p)", __FUNCTION__, client);
1510 JackClientState* const jclient = (JackClientState*)client;
1511 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
1513 return gClient.activateClient(jclient) ? 0 : 1;
1516 CARLA_PLUGIN_EXPORT
1517 int jack_deactivate(jack_client_t* client)
1519 carla_debug("%s(%p)", __FUNCTION__, client);
1521 JackClientState* const jclient = (JackClientState*)client;
1522 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 1);
1524 return gClient.deactivateClient(jclient) ? 0 : 1;
1527 // ---------------------------------------------------------------------------------------------------------------------
1529 CARLA_PLUGIN_EXPORT
1530 char* jack_get_client_name_by_uuid(jack_client_t* const client, const char* const uuidstr)
1532 carla_debug("%s(%p, %s)", __FUNCTION__, client, uuidstr);
1534 jack_uuid_t uuid = JACK_UUID_EMPTY_INITIALIZER;
1535 CARLA_SAFE_ASSERT_RETURN(jack_uuid_parse(uuidstr, &uuid) == 0, nullptr);
1537 JackClientState* const jclient = (JackClientState*)client;
1538 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr);
1540 const char* clientName;
1542 if (jclient->server.uuid == uuid)
1543 return strdup("system");
1545 if (jclient->uuid == uuid)
1547 clientName = jclient->name;
1548 CARLA_SAFE_ASSERT_RETURN(clientName != nullptr, nullptr);
1550 else
1552 CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
1553 CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, nullptr);
1555 clientName = jackAppPtr->getClientNameFromUUID(uuid);
1556 CARLA_SAFE_ASSERT_RETURN(clientName != nullptr, nullptr);
1559 return strdup(clientName);
1562 CARLA_PLUGIN_EXPORT
1563 char* jack_get_uuid_for_client_name(jack_client_t* client, const char* name)
1565 carla_debug("%s(%p, %s)", __FUNCTION__, client, name);
1567 JackClientState* const jclient = (JackClientState*)client;
1568 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, nullptr);
1570 if (std::strcmp(name, "system") == 0)
1572 char* const uuidstr = static_cast<char*>(std::malloc(JACK_UUID_STRING_SIZE));
1573 CARLA_SAFE_ASSERT_RETURN(uuidstr != nullptr, nullptr);
1575 jack_uuid_unparse(jclient->server.uuid, uuidstr);
1576 return uuidstr;
1578 else
1580 CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
1581 CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, nullptr);
1583 const jack_uuid_t uuid = jackAppPtr->getUUIDForClientName(name);
1584 CARLA_SAFE_ASSERT_RETURN(uuid != JACK_UUID_EMPTY_INITIALIZER, nullptr);
1586 char* const uuidstr = static_cast<char*>(std::malloc(JACK_UUID_STRING_SIZE));
1587 CARLA_SAFE_ASSERT_RETURN(uuidstr != nullptr, nullptr);
1589 jack_uuid_unparse(jclient->uuid, uuidstr);
1590 return uuidstr;
1594 // ---------------------------------------------------------------------------------------------------------------------
1596 CARLA_PLUGIN_EXPORT
1597 pthread_t jack_client_thread_id(jack_client_t* client)
1599 carla_debug("%s(%p)", __FUNCTION__, client);
1601 JackClientState* const jclient = (JackClientState*)client;
1602 CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, 0);
1604 CarlaJackAppClient* const jackAppPtr = jclient->server.jackAppPtr;
1605 CARLA_SAFE_ASSERT_RETURN(jackAppPtr != nullptr && jackAppPtr == &gClient, 0);
1607 return jackAppPtr->getRealtimeThreadId();
1610 // ---------------------------------------------------------------------------------------------------------------------
1612 #include "jackbridge/JackBridge2.cpp"
1613 #include "CarlaBridgeUtils.cpp"
1615 // ---------------------------------------------------------------------------------------------------------------------
1616 // TODO
1618 CARLA_BACKEND_USE_NAMESPACE
1620 CARLA_PLUGIN_EXPORT
1621 int jack_client_real_time_priority(jack_client_t* client)
1623 carla_debug("%s(%p)", __FUNCTION__, client);
1625 // code as used by water
1626 const int minPriority = sched_get_priority_min(SCHED_RR);
1627 const int maxPriority = sched_get_priority_max(SCHED_RR);
1628 return ((maxPriority - minPriority) * 9) / 10 + minPriority;
1630 // unused
1631 (void)client;
1634 int jack_client_create_thread(jack_client_t* client, pthread_t* thread, int priority,
1635 int realtime, void *(*start_routine)(void*), void* arg)
1637 carla_stderr2("%s(%p, %p, %i, %i, %p, %p)", __FUNCTION__, client, thread, priority, realtime, start_routine, arg);
1638 return ENOSYS;
1641 typedef void (*JackSessionCallback)(jack_session_event_t*, void*);
1643 CARLA_PLUGIN_EXPORT
1644 int jack_set_session_callback(jack_client_t* client, JackSessionCallback callback, void* arg)
1646 carla_stderr2("%s(%p, %p, %p)", __FUNCTION__, client, callback, arg);
1647 return 0;
1650 // ---------------------------------------------------------------------------------------------------------------------