Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2328 lines
81KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  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.
  9. *
  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.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaEngineInternal.hpp"
  18. #include "CarlaPlugin.hpp"
  19. #include "CarlaBackendUtils.hpp"
  20. #include "CarlaEngineUtils.hpp"
  21. #include "CarlaMathUtils.hpp"
  22. #include "CarlaMIDI.h"
  23. #include "CarlaPatchbayUtils.hpp"
  24. #include "CarlaStringList.hpp"
  25. #include "jackey.h"
  26. #include "juce_audio_basics.h"
  27. #ifdef __SSE2_MATH__
  28. # include <xmmintrin.h>
  29. #endif
  30. // must be last
  31. #include "jackbridge/JackBridge.hpp"
  32. #define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon"
  33. using juce::FloatVectorOperations;
  34. using juce::String;
  35. using juce::StringArray;
  36. CARLA_BACKEND_START_NAMESPACE
  37. class CarlaEngineJack;
  38. class CarlaEngineJackClient;
  39. // -----------------------------------------------------------------------
  40. // Fallback data
  41. static const EngineEvent kFallbackJackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} };
  42. // -----------------------------------------------------------------------
  43. // Carla Engine Port removal helper
  44. class CarlaEngineJackAudioPort;
  45. class CarlaEngineJackCVPort;
  46. class CarlaEngineJackEventPort;
  47. struct JackPortDeletionCallback {
  48. virtual ~JackPortDeletionCallback() noexcept {}
  49. virtual void jackAudioPortDeleted(CarlaEngineJackAudioPort* const) noexcept = 0;
  50. virtual void jackCVPortDeleted(CarlaEngineJackCVPort* const) noexcept = 0;
  51. virtual void jackEventPortDeleted(CarlaEngineJackEventPort* const) noexcept = 0;
  52. };
  53. // -----------------------------------------------------------------------
  54. // Carla Engine JACK-Audio port
  55. class CarlaEngineJackAudioPort : public CarlaEngineAudioPort
  56. {
  57. public:
  58. CarlaEngineJackAudioPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset, jack_client_t* const jackClient, jack_port_t* const jackPort, JackPortDeletionCallback* const delCallback) noexcept
  59. : CarlaEngineAudioPort(client, isInputPort, indexOffset),
  60. fJackClient(jackClient),
  61. fJackPort(jackPort),
  62. kDeletionCallback(delCallback)
  63. {
  64. carla_debug("CarlaEngineJackAudioPort::CarlaEngineJackAudioPort(%s, %p, %p)", bool2str(isInputPort), jackClient, jackPort);
  65. switch (kClient.getEngine().getProccessMode())
  66. {
  67. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  68. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  69. CARLA_SAFE_ASSERT_RETURN(jackClient != nullptr && jackPort != nullptr,);
  70. #ifndef BUILD_BRIDGE
  71. if (const jack_uuid_t uuid = jackbridge_port_uuid(jackPort))
  72. jackbridge_set_property(jackClient, uuid, JACKEY_SIGNAL_TYPE, "AUDIO", "text/plain");
  73. #endif
  74. break;
  75. default:
  76. CARLA_SAFE_ASSERT(jackClient == nullptr && jackPort == nullptr);
  77. break;
  78. }
  79. }
  80. ~CarlaEngineJackAudioPort() noexcept override
  81. {
  82. carla_debug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()");
  83. if (fJackClient != nullptr && fJackPort != nullptr)
  84. {
  85. #ifndef BUILD_BRIDGE
  86. try {
  87. if (const jack_uuid_t uuid = jackbridge_port_uuid(fJackPort))
  88. jackbridge_remove_property(fJackClient, uuid, JACKEY_SIGNAL_TYPE);
  89. } CARLA_SAFE_EXCEPTION("Audio port remove meta type");
  90. #endif
  91. try {
  92. jackbridge_port_unregister(fJackClient, fJackPort);
  93. } CARLA_SAFE_EXCEPTION("Audio port unregister");
  94. fJackClient = nullptr;
  95. fJackPort = nullptr;
  96. }
  97. if (kDeletionCallback != nullptr)
  98. kDeletionCallback->jackAudioPortDeleted(this);
  99. }
  100. void initBuffer() noexcept override
  101. {
  102. if (fJackPort == nullptr)
  103. return CarlaEngineAudioPort::initBuffer();
  104. const uint32_t bufferSize(kClient.getEngine().getBufferSize());
  105. try {
  106. fBuffer = (float*)jackbridge_port_get_buffer(fJackPort, bufferSize);
  107. }
  108. catch(...) {
  109. fBuffer = nullptr;
  110. return;
  111. }
  112. if (! kIsInput)
  113. FloatVectorOperations::clear(fBuffer, static_cast<int>(bufferSize));
  114. }
  115. void invalidate() noexcept
  116. {
  117. fJackClient = nullptr;
  118. fJackPort = nullptr;
  119. }
  120. private:
  121. jack_client_t* fJackClient;
  122. jack_port_t* fJackPort;
  123. JackPortDeletionCallback* const kDeletionCallback;
  124. friend class CarlaEngineJackClient;
  125. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackAudioPort)
  126. };
  127. // -----------------------------------------------------------------------
  128. // Carla Engine JACK-CV port
  129. class CarlaEngineJackCVPort : public CarlaEngineCVPort
  130. {
  131. public:
  132. CarlaEngineJackCVPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset, jack_client_t* const jackClient, jack_port_t* const jackPort, JackPortDeletionCallback* const delCallback) noexcept
  133. : CarlaEngineCVPort(client, isInputPort, indexOffset),
  134. fJackClient(jackClient),
  135. fJackPort(jackPort),
  136. kDeletionCallback(delCallback)
  137. {
  138. carla_debug("CarlaEngineJackCVPort::CarlaEngineJackCVPort(%s, %p, %p)", bool2str(isInputPort), jackClient, jackPort);
  139. switch (kClient.getEngine().getProccessMode())
  140. {
  141. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  142. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  143. CARLA_SAFE_ASSERT_RETURN(jackClient != nullptr && jackPort != nullptr,);
  144. #ifndef BUILD_BRIDGE
  145. if (const jack_uuid_t uuid = jackbridge_port_uuid(jackPort))
  146. jackbridge_set_property(jackClient, uuid, JACKEY_SIGNAL_TYPE, "CV", "text/plain");
  147. #endif
  148. break;
  149. default:
  150. CARLA_SAFE_ASSERT(jackClient == nullptr && jackPort == nullptr);
  151. break;
  152. }
  153. }
  154. ~CarlaEngineJackCVPort() noexcept override
  155. {
  156. carla_debug("CarlaEngineJackCVPort::~CarlaEngineJackCVPort()");
  157. if (fJackClient != nullptr && fJackPort != nullptr)
  158. {
  159. #ifndef BUILD_BRIDGE
  160. try {
  161. if (const jack_uuid_t uuid = jackbridge_port_uuid(fJackPort))
  162. jackbridge_remove_property(fJackClient, uuid, JACKEY_SIGNAL_TYPE);
  163. } CARLA_SAFE_EXCEPTION("CV port remove meta type");
  164. #endif
  165. try {
  166. jackbridge_port_unregister(fJackClient, fJackPort);
  167. } CARLA_SAFE_EXCEPTION("CV port unregister");
  168. fJackClient = nullptr;
  169. fJackPort = nullptr;
  170. }
  171. if (kDeletionCallback != nullptr)
  172. kDeletionCallback->jackCVPortDeleted(this);
  173. }
  174. void initBuffer() noexcept override
  175. {
  176. if (fJackPort == nullptr)
  177. return CarlaEngineCVPort::initBuffer();
  178. const uint32_t bufferSize(kClient.getEngine().getBufferSize());
  179. try {
  180. fBuffer = (float*)jackbridge_port_get_buffer(fJackPort, bufferSize);
  181. }
  182. catch(...) {
  183. fBuffer = nullptr;
  184. return;
  185. }
  186. if (! kIsInput)
  187. FloatVectorOperations::clear(fBuffer, static_cast<int>(bufferSize));
  188. }
  189. void invalidate() noexcept
  190. {
  191. fJackClient = nullptr;
  192. fJackPort = nullptr;
  193. }
  194. private:
  195. jack_client_t* fJackClient;
  196. jack_port_t* fJackPort;
  197. JackPortDeletionCallback* const kDeletionCallback;
  198. friend class CarlaEngineJackClient;
  199. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackCVPort)
  200. };
  201. // -----------------------------------------------------------------------
  202. // Carla Engine JACK-Event port
  203. class CarlaEngineJackEventPort : public CarlaEngineEventPort
  204. {
  205. public:
  206. CarlaEngineJackEventPort(const CarlaEngineClient& client, const bool isInputPort, const uint32_t indexOffset, jack_client_t* const jackClient, jack_port_t* const jackPort, JackPortDeletionCallback* const delCallback) noexcept
  207. : CarlaEngineEventPort(client, isInputPort, indexOffset),
  208. fJackClient(jackClient),
  209. fJackPort(jackPort),
  210. fJackBuffer(nullptr),
  211. fRetEvent(kFallbackJackEngineEvent),
  212. kDeletionCallback(delCallback)
  213. {
  214. carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInputPort), jackClient, jackPort);
  215. switch (kClient.getEngine().getProccessMode())
  216. {
  217. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  218. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  219. CARLA_SAFE_ASSERT_RETURN(jackClient != nullptr && jackPort != nullptr,);
  220. break;
  221. default:
  222. CARLA_SAFE_ASSERT(jackClient == nullptr && jackPort == nullptr);
  223. break;
  224. }
  225. }
  226. ~CarlaEngineJackEventPort() noexcept override
  227. {
  228. carla_debug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()");
  229. if (fJackClient != nullptr && fJackPort != nullptr)
  230. {
  231. try {
  232. jackbridge_port_unregister(fJackClient, fJackPort);
  233. } CARLA_SAFE_EXCEPTION("Event port unregister");
  234. fJackClient = nullptr;
  235. fJackPort = nullptr;
  236. }
  237. if (kDeletionCallback != nullptr)
  238. kDeletionCallback->jackEventPortDeleted(this);
  239. }
  240. void initBuffer() noexcept override
  241. {
  242. if (fJackPort == nullptr)
  243. return CarlaEngineEventPort::initBuffer();
  244. try {
  245. fJackBuffer = jackbridge_port_get_buffer(fJackPort, kClient.getEngine().getBufferSize());
  246. }
  247. catch(...) {
  248. fJackBuffer = nullptr;
  249. return;
  250. }
  251. if (! kIsInput)
  252. jackbridge_midi_clear_buffer(fJackBuffer);
  253. }
  254. uint32_t getEventCount() const noexcept override
  255. {
  256. if (fJackPort == nullptr)
  257. return CarlaEngineEventPort::getEventCount();
  258. CARLA_SAFE_ASSERT_RETURN(kIsInput, 0);
  259. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, 0);
  260. try {
  261. return jackbridge_midi_get_event_count(fJackBuffer);
  262. } CARLA_SAFE_EXCEPTION_RETURN("jack_midi_get_event_count", 0);
  263. }
  264. const EngineEvent& getEvent(const uint32_t index) const noexcept override
  265. {
  266. if (fJackPort == nullptr)
  267. return CarlaEngineEventPort::getEvent(index);
  268. CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackJackEngineEvent);
  269. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, kFallbackJackEngineEvent);
  270. return getEventUnchecked(index);
  271. }
  272. const EngineEvent& getEventUnchecked(const uint32_t index) const noexcept override
  273. {
  274. jack_midi_event_t jackEvent;
  275. bool test = false;
  276. try {
  277. test = jackbridge_midi_event_get(&jackEvent, fJackBuffer, index);
  278. } CARLA_SAFE_EXCEPTION_RETURN("jack_midi_event_get", kFallbackJackEngineEvent);
  279. if (! test)
  280. return kFallbackJackEngineEvent;
  281. CARLA_SAFE_ASSERT_RETURN(jackEvent.size < 0xFF /* uint8_t max */, kFallbackJackEngineEvent);
  282. uint8_t port;
  283. if (kIndexOffset < 0xFF /* uint8_t max */)
  284. {
  285. port = kIndexOffset;
  286. }
  287. else
  288. {
  289. port = 0;
  290. carla_safe_assert_int("kIndexOffset < 0xFF", __FILE__, __LINE__, kIndexOffset);
  291. }
  292. fRetEvent.time = jackEvent.time;
  293. fRetEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer, port);
  294. return fRetEvent;
  295. }
  296. bool writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept override
  297. {
  298. if (fJackPort == nullptr)
  299. return CarlaEngineEventPort::writeControlEvent(time, channel, type, param, value);
  300. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  301. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  302. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  303. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  304. CARLA_SAFE_ASSERT_RETURN(param < MAX_MIDI_CONTROL, false);
  305. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  306. if (type == kEngineControlEventTypeParameter) {
  307. CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  308. }
  309. uint8_t size = 0;
  310. uint8_t data[3] = { 0, 0, 0 };
  311. EngineControlEvent ctrlEvent = { type, param, value };
  312. ctrlEvent.convertToMidiData(channel, size, data);
  313. if (size == 0)
  314. return false;
  315. try {
  316. return jackbridge_midi_event_write(fJackBuffer, time, data, size);
  317. } CARLA_SAFE_EXCEPTION_RETURN("jack_midi_event_write", false);
  318. }
  319. bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t size, const uint8_t* const data) noexcept override
  320. {
  321. if (fJackPort == nullptr)
  322. return CarlaEngineEventPort::writeMidiEvent(time, channel, size, data);
  323. CARLA_SAFE_ASSERT_RETURN(! kIsInput, false);
  324. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  325. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  326. CARLA_SAFE_ASSERT_RETURN(size > 0, false);
  327. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  328. jack_midi_data_t jdata[size];
  329. jdata[0] = static_cast<jack_midi_data_t>(MIDI_GET_STATUS_FROM_DATA(data) + channel);
  330. for (uint8_t i=1; i < size; ++i)
  331. jdata[i] = data[i];
  332. try {
  333. return jackbridge_midi_event_write(fJackBuffer, time, jdata, size);
  334. } CARLA_SAFE_EXCEPTION_RETURN("jack_midi_event_write", false);
  335. }
  336. void invalidate() noexcept
  337. {
  338. fJackClient = nullptr;
  339. fJackPort = nullptr;
  340. }
  341. private:
  342. jack_client_t* fJackClient;
  343. jack_port_t* fJackPort;
  344. void* fJackBuffer;
  345. mutable EngineEvent fRetEvent;
  346. JackPortDeletionCallback* const kDeletionCallback;
  347. friend class CarlaEngineJackClient;
  348. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackEventPort)
  349. };
  350. // -----------------------------------------------------------------------
  351. // Jack Engine client
  352. class CarlaEngineJackClient : public CarlaEngineClient,
  353. private JackPortDeletionCallback
  354. {
  355. public:
  356. CarlaEngineJackClient(const CarlaEngine& engine, jack_client_t* const jackClient)
  357. : CarlaEngineClient(engine),
  358. fJackClient(jackClient),
  359. fUseClient(engine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || engine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS),
  360. fAudioPorts(),
  361. fCVPorts(),
  362. fEventPorts()
  363. {
  364. carla_debug("CarlaEngineJackClient::CarlaEngineJackClient(%p)", jackClient);
  365. if (fUseClient)
  366. {
  367. CARLA_SAFE_ASSERT(jackClient != nullptr);
  368. }
  369. else
  370. {
  371. CARLA_SAFE_ASSERT(jackClient == nullptr);
  372. }
  373. }
  374. ~CarlaEngineJackClient() noexcept override
  375. {
  376. carla_debug("CarlaEngineJackClient::~CarlaEngineJackClient()");
  377. if (getProcessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS && fJackClient != nullptr) // FIXME
  378. jackbridge_client_close(fJackClient);
  379. // ports must have been deleted by now!
  380. //fAudioPorts.clear();
  381. //fCVPorts.clear();
  382. //fEventPorts.clear();
  383. }
  384. void activate() noexcept override
  385. {
  386. carla_debug("CarlaEngineJackClient::activate()");
  387. if (getProcessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  388. {
  389. CARLA_SAFE_ASSERT_RETURN(fJackClient != nullptr && ! isActive(),);
  390. try {
  391. jackbridge_activate(fJackClient);
  392. } catch(...) {}
  393. }
  394. CarlaEngineClient::activate();
  395. const CarlaMutexLocker cml(fPreRenameMutex);
  396. if (fJackClient != nullptr)
  397. {
  398. // restore pre-rename connections
  399. const char* portNameA = nullptr;
  400. const char* portNameB = nullptr;
  401. bool doConnection = false;
  402. for (CarlaStringList::Itenerator it = fPreRenameConnections.begin2(); it.valid(); it.next())
  403. {
  404. const bool connectNow = doConnection;
  405. doConnection = !doConnection;
  406. if (connectNow)
  407. portNameB = it.getValue(nullptr);
  408. else
  409. portNameA = it.getValue(nullptr);
  410. if (! connectNow)
  411. continue;
  412. CARLA_SAFE_ASSERT_CONTINUE(portNameA != nullptr && portNameA[0] != '\0');
  413. CARLA_SAFE_ASSERT_CONTINUE(portNameB != nullptr && portNameB[0] != '\0');
  414. jackbridge_connect(fJackClient, portNameA, portNameB);
  415. }
  416. }
  417. fPreRenameConnections.clear();
  418. }
  419. void deactivate() noexcept override
  420. {
  421. carla_debug("CarlaEngineJackClient::deactivate()");
  422. if (getProcessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  423. {
  424. CARLA_SAFE_ASSERT_RETURN(fJackClient != nullptr && isActive(),);
  425. try {
  426. jackbridge_deactivate(fJackClient);
  427. } catch(...) {}
  428. }
  429. CarlaEngineClient::deactivate();
  430. }
  431. bool isOk() const noexcept override
  432. {
  433. if (fUseClient)
  434. return (fJackClient != nullptr);
  435. return CarlaEngineClient::isOk();
  436. }
  437. CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput, const uint32_t indexOffset) override
  438. {
  439. carla_debug("CarlaEngineJackClient::addPort(%i:%s, \"%s\", %s)", portType, EnginePortType2Str(portType), name, bool2str(isInput));
  440. jack_port_t* jackPort = nullptr;
  441. const char* realName = name;
  442. // Create JACK port first, if needed
  443. if (fUseClient)
  444. {
  445. CARLA_SAFE_ASSERT_RETURN(fJackClient != nullptr, nullptr);
  446. realName = _getUniquePortName(name);
  447. switch (portType)
  448. {
  449. case kEnginePortTypeNull:
  450. break;
  451. case kEnginePortTypeAudio:
  452. jackPort = jackbridge_port_register(fJackClient, realName, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  453. break;
  454. case kEnginePortTypeCV:
  455. jackPort = jackbridge_port_register(fJackClient, realName, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  456. break;
  457. case kEnginePortTypeEvent:
  458. jackPort = jackbridge_port_register(fJackClient, realName, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  459. break;
  460. }
  461. CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr, nullptr);
  462. }
  463. // Create Engine port
  464. switch (portType)
  465. {
  466. case kEnginePortTypeNull:
  467. break;
  468. case kEnginePortTypeAudio: {
  469. _addAudioPortName(isInput, realName);
  470. if (realName != name) delete[] realName;
  471. CarlaEngineJackAudioPort* const enginePort(new CarlaEngineJackAudioPort(*this, isInput, indexOffset, fJackClient, jackPort, this));
  472. fAudioPorts.append(enginePort);
  473. return enginePort;
  474. }
  475. case kEnginePortTypeCV: {
  476. _addCVPortName(isInput, realName);
  477. if (realName != name) delete[] realName;
  478. CarlaEngineJackCVPort* const enginePort(new CarlaEngineJackCVPort(*this, isInput, indexOffset, fJackClient, jackPort, this));
  479. fCVPorts.append(enginePort);
  480. return enginePort;
  481. }
  482. case kEnginePortTypeEvent: {
  483. _addEventPortName(isInput, realName);
  484. if (realName != name) delete[] realName;
  485. CarlaEngineJackEventPort* const enginePort(new CarlaEngineJackEventPort(*this, isInput, indexOffset, fJackClient, jackPort, this));
  486. fEventPorts.append(enginePort);
  487. return enginePort;
  488. }
  489. }
  490. carla_stderr("CarlaEngineJackClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput));
  491. return nullptr;
  492. }
  493. void invalidate() noexcept
  494. {
  495. for (LinkedList<CarlaEngineJackAudioPort*>::Itenerator it = fAudioPorts.begin2(); it.valid(); it.next())
  496. {
  497. CarlaEngineJackAudioPort* const port(it.getValue(nullptr));
  498. CARLA_SAFE_ASSERT_CONTINUE(port != nullptr);
  499. port->invalidate();
  500. }
  501. for (LinkedList<CarlaEngineJackCVPort*>::Itenerator it = fCVPorts.begin2(); it.valid(); it.next())
  502. {
  503. CarlaEngineJackCVPort* const port(it.getValue(nullptr));
  504. CARLA_SAFE_ASSERT_CONTINUE(port != nullptr);
  505. port->invalidate();
  506. }
  507. for (LinkedList<CarlaEngineJackEventPort*>::Itenerator it = fEventPorts.begin2(); it.valid(); it.next())
  508. {
  509. CarlaEngineJackEventPort* const port(it.getValue(nullptr));
  510. CARLA_SAFE_ASSERT_CONTINUE(port != nullptr);
  511. port->invalidate();
  512. }
  513. fJackClient = nullptr;
  514. CarlaEngineClient::deactivate();
  515. }
  516. const char* getJackClientName() const noexcept
  517. {
  518. CARLA_SAFE_ASSERT_RETURN(fJackClient != nullptr, nullptr);
  519. try {
  520. return jackbridge_get_client_name(fJackClient);
  521. } CARLA_SAFE_EXCEPTION_RETURN("jack_get_client_name", nullptr);
  522. }
  523. void jackAudioPortDeleted(CarlaEngineJackAudioPort* const port) noexcept override
  524. {
  525. fAudioPorts.removeAll(port);
  526. }
  527. void jackCVPortDeleted(CarlaEngineJackCVPort* const port) noexcept override
  528. {
  529. fCVPorts.removeAll(port);
  530. }
  531. void jackEventPortDeleted(CarlaEngineJackEventPort* const port) noexcept override
  532. {
  533. fEventPorts.removeAll(port);
  534. }
  535. void closeForRename(jack_client_t* const client, const char* const clientName) noexcept
  536. {
  537. if (fJackClient != nullptr)
  538. {
  539. if (isActive())
  540. {
  541. {
  542. // store current client connections
  543. const CarlaMutexLocker cml(fPreRenameMutex);
  544. fPreRenameConnections.clear();
  545. _savePortsConnections(fAudioPorts, clientName);
  546. _savePortsConnections(fCVPorts, clientName);
  547. _savePortsConnections(fEventPorts, clientName);
  548. }
  549. try {
  550. jackbridge_deactivate(fJackClient);
  551. } catch(...) {}
  552. }
  553. try {
  554. jackbridge_client_close(fJackClient);
  555. } catch(...) {}
  556. invalidate();
  557. }
  558. fAudioPorts.clear();
  559. fCVPorts.clear();
  560. fEventPorts.clear();
  561. _clearPorts();
  562. fJackClient = client;
  563. }
  564. private:
  565. jack_client_t* fJackClient;
  566. const bool fUseClient;
  567. LinkedList<CarlaEngineJackAudioPort*> fAudioPorts;
  568. LinkedList<CarlaEngineJackCVPort*> fCVPorts;
  569. LinkedList<CarlaEngineJackEventPort*> fEventPorts;
  570. CarlaMutex fPreRenameMutex;
  571. CarlaStringList fPreRenameConnections;
  572. template<typename T>
  573. void _savePortsConnections(const LinkedList<T*>& t, const char* const clientName)
  574. {
  575. CarlaString clientNamePrefix(clientName);
  576. clientNamePrefix += ":";
  577. for (typename LinkedList<T*>::Itenerator it = t.begin2(); it.valid(); it.next())
  578. {
  579. T* const port(it.getValue(nullptr));
  580. CARLA_SAFE_ASSERT_CONTINUE(port != nullptr);
  581. CARLA_SAFE_ASSERT_CONTINUE(port->fJackPort != nullptr);
  582. const char* const shortPortName(jackbridge_port_short_name(port->fJackPort));
  583. CARLA_SAFE_ASSERT_CONTINUE(shortPortName != nullptr && shortPortName[0] != '\0');
  584. const CarlaString portName(clientNamePrefix + shortPortName);
  585. if (const char** const connections = jackbridge_port_get_all_connections(fJackClient, port->fJackPort))
  586. {
  587. for (int i=0; connections[i] != nullptr; ++i)
  588. {
  589. if (! port->kIsInput)
  590. fPreRenameConnections.append(portName);
  591. fPreRenameConnections.append(connections[i]);
  592. if (port->kIsInput)
  593. fPreRenameConnections.append(portName);
  594. }
  595. jackbridge_free(connections);
  596. }
  597. }
  598. }
  599. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient)
  600. };
  601. // -----------------------------------------------------------------------
  602. // Jack Engine
  603. class CarlaEngineJack : public CarlaEngine
  604. {
  605. public:
  606. CarlaEngineJack()
  607. : CarlaEngine(),
  608. fClient(nullptr),
  609. fTransportPos(),
  610. fTransportState(JackTransportStopped),
  611. fExternalPatchbay(true),
  612. fFreewheel(false),
  613. #ifdef BUILD_BRIDGE
  614. fIsRunning(false)
  615. #else
  616. fUsedGroups(),
  617. fUsedPorts(),
  618. fUsedConnections(),
  619. fNewGroups(),
  620. fRetConns()
  621. #endif
  622. {
  623. carla_debug("CarlaEngineJack::CarlaEngineJack()");
  624. #ifdef BUILD_BRIDGE
  625. pData->options.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  626. #else
  627. carla_zeroPointers(fRackPorts, kRackPortCount);
  628. #endif
  629. // FIXME: Always enable JACK transport for now
  630. pData->options.transportMode = ENGINE_TRANSPORT_MODE_JACK;
  631. carla_zeroStruct(fTransportPos);
  632. }
  633. ~CarlaEngineJack() noexcept override
  634. {
  635. carla_debug("CarlaEngineJack::~CarlaEngineJack()");
  636. CARLA_SAFE_ASSERT(fClient == nullptr);
  637. #ifndef BUILD_BRIDGE
  638. fUsedGroups.clear();
  639. fUsedPorts.clear();
  640. fUsedConnections.clear();
  641. fNewGroups.clear();
  642. #endif
  643. }
  644. // -------------------------------------------------------------------
  645. // Maximum values
  646. uint getMaxClientNameSize() const noexcept override
  647. {
  648. #ifndef BUILD_BRIDGE
  649. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  650. #endif
  651. {
  652. try {
  653. return static_cast<uint>(jackbridge_client_name_size()-1);
  654. } CARLA_SAFE_EXCEPTION_RETURN("jack_client_name_size", 32);
  655. }
  656. return CarlaEngine::getMaxClientNameSize();
  657. }
  658. uint getMaxPortNameSize() const noexcept override
  659. {
  660. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  661. {
  662. try {
  663. return static_cast<uint>(jackbridge_port_name_size()-1);
  664. } CARLA_SAFE_EXCEPTION_RETURN("jack_port_name_size", 255);
  665. }
  666. return CarlaEngine::getMaxPortNameSize();
  667. }
  668. // -------------------------------------------------------------------
  669. // Virtual, per-engine type calls
  670. bool init(const char* const clientName) override
  671. {
  672. CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, false);
  673. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  674. CARLA_SAFE_ASSERT_RETURN(jackbridge_is_ok(), false);
  675. carla_debug("CarlaEngineJack::init(\"%s\")", clientName);
  676. fFreewheel = false;
  677. fTransportState = JackTransportStopped;
  678. fExternalPatchbay = true;
  679. carla_zeroStruct(fTransportPos);
  680. CarlaString truncatedClientName(clientName);
  681. truncatedClientName.truncate(getMaxClientNameSize());
  682. #ifdef BUILD_BRIDGE
  683. fIsRunning = true;
  684. if (! pData->init(truncatedClientName))
  685. {
  686. close();
  687. setLastError("Failed to init internal data");
  688. return false;
  689. }
  690. if (pData->bufferSize == 0 || carla_isEqual(pData->sampleRate, 0.0))
  691. {
  692. // open temp client to get initial buffer-size and sample-rate values
  693. if (jack_client_t* const tmpClient = jackbridge_client_open(truncatedClientName, JackNoStartServer, nullptr))
  694. {
  695. pData->bufferSize = jackbridge_get_buffer_size(tmpClient);
  696. pData->sampleRate = jackbridge_get_sample_rate(tmpClient);
  697. jackbridge_client_close(tmpClient);
  698. }
  699. else
  700. {
  701. close();
  702. setLastError("Failed to init temporary jack client");
  703. return false;
  704. }
  705. }
  706. return true;
  707. #else
  708. fClient = jackbridge_client_open(truncatedClientName, JackNullOption, nullptr);
  709. if (fClient == nullptr)
  710. {
  711. setLastError("Failed to create new JACK client");
  712. return false;
  713. }
  714. const char* const jackClientName(jackbridge_get_client_name(fClient));
  715. if (! pData->init(jackClientName))
  716. {
  717. jackbridge_client_close(fClient);
  718. fClient = nullptr;
  719. setLastError("Failed to init internal data");
  720. return false;
  721. }
  722. pData->bufferSize = jackbridge_get_buffer_size(fClient);
  723. pData->sampleRate = jackbridge_get_sample_rate(fClient);
  724. jackbridge_set_thread_init_callback(fClient, carla_jack_thread_init_callback, nullptr);
  725. jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
  726. jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
  727. jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
  728. jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
  729. jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
  730. jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);
  731. if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY)
  732. initJackPatchbay(jackClientName);
  733. jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
  734. jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
  735. jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);
  736. jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);
  737. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  738. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  739. {
  740. fRackPorts[kRackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  741. fRackPorts[kRackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  742. fRackPorts[kRackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  743. fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  744. fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  745. fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
  746. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  747. {
  748. pData->graph.create(0, 0);
  749. }
  750. else
  751. {
  752. pData->graph.create(2, 2);
  753. patchbayRefresh(false);
  754. }
  755. }
  756. if (jackbridge_activate(fClient))
  757. {
  758. callback(ENGINE_CALLBACK_ENGINE_STARTED, 0, pData->options.processMode, pData->options.transportMode, 0.0f, getCurrentDriverName());
  759. return true;
  760. }
  761. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  762. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  763. {
  764. pData->graph.destroy();
  765. }
  766. pData->close();
  767. jackbridge_client_close(fClient);
  768. fClient = nullptr;
  769. setLastError("Failed to activate the JACK client");
  770. return false;
  771. #endif
  772. }
  773. bool close() override
  774. {
  775. carla_debug("CarlaEngineJack::close()");
  776. #ifdef BUILD_BRIDGE
  777. fClient = nullptr;
  778. fIsRunning = false;
  779. CarlaEngine::close();
  780. return true;
  781. #else
  782. CARLA_SAFE_ASSERT_RETURN_ERR(fClient != nullptr, "JACK Client is null");
  783. // deactivate first
  784. const bool deactivated(jackbridge_deactivate(fClient));
  785. // clear engine data
  786. CarlaEngine::close();
  787. fUsedGroups.clear();
  788. fUsedPorts.clear();
  789. fUsedConnections.clear();
  790. fNewGroups.clear();
  791. // clear rack/patchbay stuff
  792. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  793. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  794. {
  795. if (deactivated)
  796. {
  797. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn1]);
  798. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn2]);
  799. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut1]);
  800. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut2]);
  801. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventIn]);
  802. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventOut]);
  803. }
  804. carla_zeroPointers(fRackPorts, kRackPortCount);
  805. pData->graph.destroy();
  806. }
  807. // close client
  808. if (deactivated)
  809. jackbridge_client_close(fClient);
  810. fClient = nullptr;
  811. return true;
  812. #endif
  813. }
  814. #ifndef BUILD_BRIDGE
  815. void idle() noexcept override
  816. {
  817. CarlaEngine::idle();
  818. if (fNewGroups.count() == 0)
  819. return;
  820. LinkedList<uint> newPlugins;
  821. fNewGroups.moveTo(newPlugins);
  822. for (LinkedList<uint>::Itenerator it = newPlugins.begin2(); it.valid(); it.next())
  823. {
  824. const uint groupId(it.getValue(0));
  825. CARLA_SAFE_ASSERT_CONTINUE(groupId > 0);
  826. const char* const groupName(fUsedGroups.getGroupName(groupId));
  827. CARLA_SAFE_ASSERT_CONTINUE(groupName != nullptr && groupName[0] != '\0');
  828. int pluginId = -1;
  829. PatchbayIcon icon = PATCHBAY_ICON_PLUGIN;
  830. if (findPluginIdAndIcon(groupName, pluginId, icon))
  831. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_DATA_CHANGED, groupId, icon, pluginId, 0.0f, nullptr);
  832. }
  833. newPlugins.clear();
  834. }
  835. #endif
  836. bool isRunning() const noexcept override
  837. {
  838. #ifdef BUILD_BRIDGE
  839. return (fClient != nullptr || fIsRunning);
  840. #else
  841. return (fClient != nullptr);
  842. #endif
  843. }
  844. bool isOffline() const noexcept override
  845. {
  846. return fFreewheel;
  847. }
  848. EngineType getType() const noexcept override
  849. {
  850. return kEngineTypeJack;
  851. }
  852. const char* getCurrentDriverName() const noexcept override
  853. {
  854. return "JACK";
  855. }
  856. CarlaEngineClient* addClient(CarlaPlugin* const plugin) override
  857. {
  858. jack_client_t* client = nullptr;
  859. #ifndef BUILD_BRIDGE
  860. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  861. {
  862. client = fClient;
  863. }
  864. else if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  865. #endif
  866. {
  867. client = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);
  868. CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);
  869. jackbridge_set_thread_init_callback(client, carla_jack_thread_init_callback, nullptr);
  870. #ifndef BUILD_BRIDGE
  871. jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin);
  872. jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin);
  873. jackbridge_on_shutdown(client, carla_jack_shutdown_callback_plugin, plugin);
  874. #else
  875. fClient = client;
  876. pData->bufferSize = jackbridge_get_buffer_size(client);
  877. pData->sampleRate = jackbridge_get_sample_rate(client);
  878. jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
  879. jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
  880. jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
  881. jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
  882. jackbridge_set_process_callback(client, carla_jack_process_callback, this);
  883. jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
  884. #endif
  885. }
  886. return new CarlaEngineJackClient(*this, client);
  887. }
  888. #ifndef BUILD_BRIDGE
  889. const char* renamePlugin(const uint id, const char* const newName) override
  890. {
  891. CARLA_SAFE_ASSERT_RETURN(pData->curPluginCount > 0, nullptr);
  892. CARLA_SAFE_ASSERT_RETURN(id < pData->curPluginCount, nullptr);
  893. CARLA_SAFE_ASSERT_RETURN(pData->plugins != nullptr, nullptr);
  894. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr);
  895. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  896. if (plugin == nullptr)
  897. {
  898. carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id);
  899. return nullptr;
  900. }
  901. const ScopedThreadStopper sts(this);
  902. CARLA_SAFE_ASSERT(plugin->getId() == id);
  903. CarlaString uniqueName;
  904. try {
  905. const char* const tmpName = getUniquePluginName(newName);
  906. uniqueName = tmpName;
  907. delete[] tmpName;
  908. } CARLA_SAFE_EXCEPTION("JACK renamePlugin getUniquePluginName");
  909. if (uniqueName.isEmpty())
  910. {
  911. setLastError("Failed to request new unique plugin name");
  912. return nullptr;
  913. }
  914. // single client always re-inits
  915. bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT);
  916. // rename in multiple client mode
  917. if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  918. {
  919. CarlaEngineJackClient* const client((CarlaEngineJackClient*)plugin->getEngineClient());
  920. #if 0
  921. if (bridge.client_rename_ptr != nullptr)
  922. {
  923. newName = jackbridge_client_rename(client->fClient, newName);
  924. }
  925. else
  926. #endif
  927. {
  928. // we should not be able to do this, jack really needs to allow client rename
  929. if (jack_client_t* const jackClient = jackbridge_client_open(uniqueName, JackNullOption, nullptr))
  930. {
  931. // get new client name
  932. uniqueName = jackbridge_get_client_name(jackClient);
  933. // close client
  934. client->closeForRename(jackClient, uniqueName);
  935. // disable plugin
  936. plugin->setEnabled(false);
  937. // set new client data
  938. jackbridge_set_thread_init_callback(jackClient, carla_jack_thread_init_callback, nullptr);
  939. jackbridge_set_latency_callback(jackClient, carla_jack_latency_callback_plugin, plugin);
  940. jackbridge_set_process_callback(jackClient, carla_jack_process_callback_plugin, plugin);
  941. jackbridge_on_shutdown(jackClient, carla_jack_shutdown_callback_plugin, plugin);
  942. needsReinit = true;
  943. }
  944. else
  945. {
  946. setLastError("Failed to create new JACK client");
  947. return nullptr;
  948. }
  949. }
  950. }
  951. // Rename
  952. plugin->setName(uniqueName);
  953. if (needsReinit)
  954. {
  955. // reload plugin to recreate its ports
  956. const CarlaStateSave& saveState(plugin->getStateSave());
  957. plugin->reload();
  958. plugin->loadStateSave(saveState);
  959. }
  960. return plugin->getName();
  961. }
  962. // -------------------------------------------------------------------
  963. // Patchbay
  964. bool patchbayConnect(const uint groupA, const uint portA, const uint groupB, const uint portB) override
  965. {
  966. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
  967. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay)
  968. return CarlaEngine::patchbayConnect(groupA, portA, groupB, portB);
  969. const char* const fullPortNameA = fUsedPorts.getFullPortName(groupA, portA);
  970. CARLA_SAFE_ASSERT_RETURN(fullPortNameA != nullptr && fullPortNameA[0] != '\0', false);
  971. const char* const fullPortNameB = fUsedPorts.getFullPortName(groupB, portB);
  972. CARLA_SAFE_ASSERT_RETURN(fullPortNameB != nullptr && fullPortNameB[0] != '\0', false);
  973. carla_stdout("patchbayConnect(%u, %u, %u, %u => %s, %s)", groupA, portA, groupB, portB, fullPortNameA, fullPortNameB);
  974. if (! jackbridge_connect(fClient, fullPortNameA, fullPortNameB))
  975. {
  976. setLastError("JACK operation failed");
  977. return false;
  978. }
  979. return true;
  980. }
  981. bool patchbayDisconnect(const uint connectionId) override
  982. {
  983. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
  984. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay)
  985. return CarlaEngine::patchbayDisconnect(connectionId);
  986. ConnectionToId connectionToId = { 0, 0, 0, 0, 0 };
  987. {
  988. const CarlaMutexLocker cml(fUsedConnections.mutex);
  989. for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin2(); it.valid(); it.next())
  990. {
  991. connectionToId = it.getValue(connectionToId);
  992. CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0);
  993. if (connectionToId.id == connectionId)
  994. break;
  995. }
  996. }
  997. if (connectionToId.id == 0 || connectionToId.id != connectionId)
  998. {
  999. setLastError("Failed to find the requested connection");
  1000. return false;
  1001. }
  1002. const char* const fullPortNameA = fUsedPorts.getFullPortName(connectionToId.groupA, connectionToId.portA);
  1003. CARLA_SAFE_ASSERT_RETURN(fullPortNameA != nullptr && fullPortNameA[0] != '\0', false);
  1004. const char* const fullPortNameB = fUsedPorts.getFullPortName(connectionToId.groupB, connectionToId.portB);
  1005. CARLA_SAFE_ASSERT_RETURN(fullPortNameB != nullptr && fullPortNameB[0] != '\0', false);
  1006. if (! jackbridge_disconnect(fClient, fullPortNameA, fullPortNameB))
  1007. {
  1008. setLastError("JACK operation failed");
  1009. return false;
  1010. }
  1011. return true;
  1012. }
  1013. bool patchbayRefresh(const bool external) override
  1014. {
  1015. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
  1016. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1017. {
  1018. fExternalPatchbay = external;
  1019. pData->graph.setUsingExternal(external);
  1020. if (! external)
  1021. return CarlaEngine::patchbayRefresh(false);
  1022. }
  1023. fUsedGroups.clear();
  1024. fUsedPorts.clear();
  1025. fUsedConnections.clear();
  1026. fNewGroups.clear();
  1027. initJackPatchbay(jackbridge_get_client_name(fClient));
  1028. return true;
  1029. }
  1030. // -------------------------------------------------------------------
  1031. // Transport
  1032. void transportPlay() noexcept override
  1033. {
  1034. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  1035. return CarlaEngine::transportPlay();
  1036. if (fClient != nullptr)
  1037. {
  1038. try {
  1039. jackbridge_transport_start(fClient);
  1040. } catch(...) {}
  1041. }
  1042. }
  1043. void transportPause() noexcept override
  1044. {
  1045. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  1046. return CarlaEngine::transportPause();
  1047. if (fClient != nullptr)
  1048. {
  1049. try {
  1050. jackbridge_transport_stop(fClient);
  1051. } catch(...) {}
  1052. }
  1053. }
  1054. void transportRelocate(const uint64_t frame) noexcept override
  1055. {
  1056. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  1057. return CarlaEngine::transportRelocate(frame);
  1058. if (fClient != nullptr)
  1059. {
  1060. try {
  1061. jackbridge_transport_locate(fClient, static_cast<jack_nframes_t>(frame));
  1062. } catch(...) {}
  1063. }
  1064. }
  1065. // -------------------------------------------------------------------
  1066. // Patchbay stuff
  1067. const char* const* getPatchbayConnections(const bool external) const override
  1068. {
  1069. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, nullptr);
  1070. carla_debug("CarlaEngineJack::getPatchbayConnections(%s)", bool2str(external));
  1071. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! external)
  1072. return CarlaEngine::getPatchbayConnections(external);
  1073. CarlaStringList connList;
  1074. if (const char** const ports = jackbridge_get_ports(fClient, nullptr, nullptr, JackPortIsOutput))
  1075. {
  1076. for (int i=0; ports[i] != nullptr; ++i)
  1077. {
  1078. const jack_port_t* const jackPort(jackbridge_port_by_name(fClient, ports[i]));
  1079. const char* const fullPortName(ports[i]);
  1080. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1081. if (const char** const connections = jackbridge_port_get_all_connections(fClient, jackPort))
  1082. {
  1083. for (int j=0; connections[j] != nullptr; ++j)
  1084. {
  1085. connList.append(fullPortName);
  1086. connList.append(connections[j]);
  1087. }
  1088. jackbridge_free(connections);
  1089. }
  1090. }
  1091. jackbridge_free(ports);
  1092. }
  1093. if (connList.count() == 0)
  1094. return nullptr;
  1095. fRetConns = connList.toCharStringListPtr();
  1096. return fRetConns;
  1097. }
  1098. void restorePatchbayConnection(const bool external, const char* const connSource, const char* const connTarget, const bool sendCallback) override
  1099. {
  1100. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr,);
  1101. CARLA_SAFE_ASSERT_RETURN(connSource != nullptr && connSource[0] != '\0',);
  1102. CARLA_SAFE_ASSERT_RETURN(connTarget != nullptr && connTarget[0] != '\0',);
  1103. carla_debug("CarlaEngineJack::restorePatchbayConnection(\"%s\", \"%s\")", connSource, connTarget);
  1104. if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! external)
  1105. return CarlaEngine::restorePatchbayConnection(external, connSource, connTarget, sendCallback);
  1106. if (const jack_port_t* const port = jackbridge_port_by_name(fClient, connSource))
  1107. {
  1108. if (jackbridge_port_by_name(fClient, connTarget) == nullptr)
  1109. return;
  1110. if (! jackbridge_port_connected_to(port, connTarget))
  1111. jackbridge_connect(fClient, connSource, connTarget);
  1112. }
  1113. }
  1114. #endif
  1115. // -------------------------------------------------------------------
  1116. protected:
  1117. void handleJackBufferSizeCallback(const uint32_t newBufferSize)
  1118. {
  1119. if (pData->bufferSize == newBufferSize)
  1120. return;
  1121. pData->bufferSize = newBufferSize;
  1122. bufferSizeChanged(newBufferSize);
  1123. }
  1124. void handleJackSampleRateCallback(const double newSampleRate)
  1125. {
  1126. if (carla_isEqual(pData->sampleRate, newSampleRate))
  1127. return;
  1128. pData->sampleRate = newSampleRate;
  1129. sampleRateChanged(newSampleRate);
  1130. }
  1131. void handleJackFreewheelCallback(const bool isFreewheel)
  1132. {
  1133. if (fFreewheel == isFreewheel)
  1134. return;
  1135. fFreewheel = isFreewheel;
  1136. offlineModeChanged(isFreewheel);
  1137. }
  1138. void saveTransportInfo()
  1139. {
  1140. if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
  1141. return;
  1142. fTransportPos.unique_1 = fTransportPos.unique_2 + 1; // invalidate
  1143. fTransportState = jackbridge_transport_query(fClient, &fTransportPos);
  1144. pData->timeInfo.playing = (fTransportState == JackTransportRolling);
  1145. if (fTransportPos.unique_1 == fTransportPos.unique_2)
  1146. {
  1147. pData->timeInfo.frame = fTransportPos.frame;
  1148. pData->timeInfo.usecs = fTransportPos.usecs;
  1149. if (fTransportPos.valid & JackPositionBBT)
  1150. {
  1151. pData->timeInfo.valid = EngineTimeInfo::kValidBBT;
  1152. pData->timeInfo.bbt.bar = fTransportPos.bar;
  1153. pData->timeInfo.bbt.beat = fTransportPos.beat;
  1154. pData->timeInfo.bbt.tick = fTransportPos.tick;
  1155. pData->timeInfo.bbt.barStartTick = fTransportPos.bar_start_tick;
  1156. pData->timeInfo.bbt.beatsPerBar = fTransportPos.beats_per_bar;
  1157. pData->timeInfo.bbt.beatType = fTransportPos.beat_type;
  1158. pData->timeInfo.bbt.ticksPerBeat = fTransportPos.ticks_per_beat;
  1159. pData->timeInfo.bbt.beatsPerMinute = fTransportPos.beats_per_minute;
  1160. }
  1161. else
  1162. pData->timeInfo.valid = 0x0;
  1163. }
  1164. else
  1165. {
  1166. pData->timeInfo.frame = 0;
  1167. pData->timeInfo.valid = 0x0;
  1168. }
  1169. }
  1170. void handleJackProcessCallback(const uint32_t nframes)
  1171. {
  1172. const PendingRtEventsRunner prt(this);
  1173. saveTransportInfo();
  1174. #ifdef BUILD_BRIDGE
  1175. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  1176. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  1177. {
  1178. plugin->initBuffers();
  1179. processPlugin(plugin, nframes);
  1180. plugin->unlock();
  1181. }
  1182. #else
  1183. if (pData->curPluginCount == 0 && pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  1184. {
  1185. // pass-through
  1186. // TODO MIDI as well
  1187. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  1188. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  1189. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  1190. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  1191. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  1192. FloatVectorOperations::copy(audioOut1, audioIn1, static_cast<int>(nframes));
  1193. FloatVectorOperations::copy(audioOut2, audioIn2, static_cast<int>(nframes));
  1194. jackbridge_midi_clear_buffer(eventOut);
  1195. return;
  1196. }
  1197. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  1198. {
  1199. for (uint i=0; i < pData->curPluginCount; ++i)
  1200. {
  1201. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1202. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  1203. {
  1204. plugin->initBuffers();
  1205. processPlugin(plugin, nframes);
  1206. plugin->unlock();
  1207. }
  1208. }
  1209. }
  1210. else if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
  1211. pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
  1212. {
  1213. CARLA_SAFE_ASSERT_RETURN(pData->events.in != nullptr,);
  1214. CARLA_SAFE_ASSERT_RETURN(pData->events.out != nullptr,);
  1215. // get buffers from jack
  1216. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  1217. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  1218. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  1219. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  1220. void* const eventIn = jackbridge_port_get_buffer(fRackPorts[kRackPortEventIn], nframes);
  1221. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  1222. #if 1
  1223. // assert buffers
  1224. CARLA_SAFE_ASSERT(audioIn1 != nullptr);
  1225. CARLA_SAFE_ASSERT(audioIn2 != nullptr);
  1226. CARLA_SAFE_ASSERT(audioOut1 != nullptr);
  1227. CARLA_SAFE_ASSERT(audioOut2 != nullptr);
  1228. CARLA_SAFE_ASSERT(eventIn != nullptr);
  1229. CARLA_SAFE_ASSERT(eventOut != nullptr);
  1230. #endif
  1231. // create audio buffers
  1232. const float* inBuf[2] = { audioIn1, audioIn2 };
  1233. /**/ float* outBuf[2] = { audioOut1, audioOut2 };
  1234. // initialize events
  1235. carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
  1236. carla_zeroStructs(pData->events.out, kMaxEngineEventInternalCount);
  1237. {
  1238. ushort engineEventIndex = 0;
  1239. jack_midi_event_t jackEvent;
  1240. const uint32_t jackEventCount(jackbridge_midi_get_event_count(eventIn));
  1241. for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; ++jackEventIndex)
  1242. {
  1243. if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex))
  1244. continue;
  1245. CARLA_SAFE_ASSERT_CONTINUE(jackEvent.size < 0xFF /* uint8_t max */);
  1246. EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);
  1247. engineEvent.time = jackEvent.time;
  1248. engineEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer, 0);
  1249. if (engineEventIndex >= kMaxEngineEventInternalCount)
  1250. break;
  1251. }
  1252. }
  1253. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  1254. pData->graph.processRack(pData, inBuf, outBuf, nframes);
  1255. else
  1256. pData->graph.process(pData, inBuf, outBuf, nframes);
  1257. // output control
  1258. {
  1259. jackbridge_midi_clear_buffer(eventOut);
  1260. uint8_t size = 0;
  1261. uint8_t data[3] = { 0, 0, 0 };
  1262. const uint8_t* dataPtr = data;
  1263. for (ushort i=0; i < kMaxEngineEventInternalCount; ++i)
  1264. {
  1265. const EngineEvent& engineEvent(pData->events.out[i]);
  1266. if (engineEvent.type == kEngineEventTypeNull)
  1267. break;
  1268. else if (engineEvent.type == kEngineEventTypeControl)
  1269. {
  1270. const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
  1271. ctrlEvent.convertToMidiData(engineEvent.channel, size, data);
  1272. dataPtr = data;
  1273. }
  1274. else if (engineEvent.type == kEngineEventTypeMidi)
  1275. {
  1276. const EngineMidiEvent& midiEvent(engineEvent.midi);
  1277. size = midiEvent.size;
  1278. if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
  1279. dataPtr = midiEvent.dataExt;
  1280. else
  1281. dataPtr = midiEvent.data;
  1282. }
  1283. else
  1284. {
  1285. continue;
  1286. }
  1287. if (size > 0)
  1288. jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size);
  1289. }
  1290. }
  1291. }
  1292. #endif // ! BUILD_BRIDGE
  1293. }
  1294. void handleJackLatencyCallback(const jack_latency_callback_mode_t /*mode*/)
  1295. {
  1296. // TODO
  1297. }
  1298. #ifndef BUILD_BRIDGE
  1299. void handleJackClientRegistrationCallback(const char* const name, const bool reg)
  1300. {
  1301. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
  1302. // ignore this if on internal patchbay mode
  1303. if (! fExternalPatchbay) return;
  1304. // do nothing on client registration, wait for first port
  1305. if (reg) return;
  1306. const uint groupId(fUsedGroups.getGroupId(name));
  1307. // clients might have been registered without ports
  1308. if (groupId == 0) return;
  1309. GroupNameToId groupNameToId;
  1310. groupNameToId.setData(groupId, name);
  1311. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_REMOVED, groupNameToId.group, 0, 0, 0.0f, nullptr);
  1312. fUsedGroups.list.removeOne(groupNameToId);
  1313. }
  1314. void handleJackPortRegistrationCallback(const jack_port_id_t port, const bool reg)
  1315. {
  1316. // ignore this if on internal patchbay mode
  1317. if (! fExternalPatchbay) return;
  1318. const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  1319. CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,);
  1320. const char* const fullPortName(jackbridge_port_name(jackPort));
  1321. CARLA_SAFE_ASSERT_RETURN(fullPortName != nullptr && fullPortName[0] != '\0',);
  1322. if (reg)
  1323. {
  1324. const char* const shortPortName(jackbridge_port_short_name(jackPort));
  1325. CARLA_SAFE_ASSERT_RETURN(shortPortName != nullptr && shortPortName[0] != '\0',);
  1326. bool found;
  1327. CarlaString groupName(fullPortName);
  1328. groupName.truncate(groupName.rfind(shortPortName, &found)-1);
  1329. CARLA_SAFE_ASSERT_RETURN(found,);
  1330. const int jackPortFlags(jackbridge_port_flags(jackPort));
  1331. uint groupId(fUsedGroups.getGroupId(groupName));
  1332. if (groupId == 0)
  1333. {
  1334. groupId = ++fUsedGroups.lastId;
  1335. PatchbayIcon icon = (jackPortFlags & JackPortIsPhysical) ? PATCHBAY_ICON_HARDWARE : PATCHBAY_ICON_APPLICATION;
  1336. GroupNameToId groupNameToId;
  1337. groupNameToId.setData(groupId, groupName);
  1338. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupNameToId.group, icon, -1, 0.0f, groupNameToId.name);
  1339. fNewGroups.append(groupId);
  1340. fUsedGroups.list.append(groupNameToId);
  1341. }
  1342. addPatchbayJackPort(groupId, jackPort, shortPortName, fullPortName, jackPortFlags);
  1343. }
  1344. else
  1345. {
  1346. const PortNameToId& portNameToId(fUsedPorts.getPortNameToId(fullPortName));
  1347. CARLA_SAFE_ASSERT_RETURN(portNameToId.group > 0 && portNameToId.port > 0,);
  1348. callback(ENGINE_CALLBACK_PATCHBAY_PORT_REMOVED, portNameToId.group, static_cast<int>(portNameToId.port), 0, 0.0f, nullptr);
  1349. fUsedPorts.list.removeOne(portNameToId);
  1350. }
  1351. }
  1352. void handleJackPortConnectCallback(const jack_port_id_t a, const jack_port_id_t b, const bool connect)
  1353. {
  1354. // ignore this if on internal patchbay mode
  1355. if (! fExternalPatchbay) return;
  1356. const jack_port_t* const jackPortA(jackbridge_port_by_id(fClient, a));
  1357. CARLA_SAFE_ASSERT_RETURN(jackPortA != nullptr,);
  1358. const jack_port_t* const jackPortB(jackbridge_port_by_id(fClient, b));
  1359. CARLA_SAFE_ASSERT_RETURN(jackPortB != nullptr,);
  1360. const char* const fullPortNameA(jackbridge_port_name(jackPortA));
  1361. CARLA_SAFE_ASSERT_RETURN(fullPortNameA != nullptr && fullPortNameA[0] != '\0',);
  1362. const char* const fullPortNameB(jackbridge_port_name(jackPortB));
  1363. CARLA_SAFE_ASSERT_RETURN(fullPortNameB != nullptr && fullPortNameB[0] != '\0',);
  1364. const PortNameToId& portNameToIdA(fUsedPorts.getPortNameToId(fullPortNameA));
  1365. CARLA_SAFE_ASSERT_RETURN(portNameToIdA.group > 0 && portNameToIdA.port > 0,);
  1366. const PortNameToId& portNameToIdB(fUsedPorts.getPortNameToId(fullPortNameB));
  1367. CARLA_SAFE_ASSERT_RETURN(portNameToIdB.group > 0 && portNameToIdB.port > 0,);
  1368. if (connect)
  1369. {
  1370. char strBuf[STR_MAX+1];
  1371. std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", portNameToIdA.group, portNameToIdA.port, portNameToIdB.group, portNameToIdB.port);
  1372. strBuf[STR_MAX] = '\0';
  1373. ConnectionToId connectionToId;
  1374. connectionToId.setData(++fUsedConnections.lastId, portNameToIdA.group, portNameToIdA.port, portNameToIdB.group, portNameToIdB.port);
  1375. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);
  1376. fUsedConnections.list.append(connectionToId);
  1377. }
  1378. else
  1379. {
  1380. ConnectionToId connectionToId = { 0, 0, 0, 0, 0 };
  1381. bool found = false;
  1382. {
  1383. const CarlaMutexLocker cml(fUsedConnections.mutex);
  1384. for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin2(); it.valid(); it.next())
  1385. {
  1386. connectionToId = it.getValue(connectionToId);
  1387. CARLA_SAFE_ASSERT_CONTINUE(connectionToId.id != 0);
  1388. if (connectionToId.groupA == portNameToIdA.group && connectionToId.portA == portNameToIdA.port &&
  1389. connectionToId.groupB == portNameToIdB.group && connectionToId.portB == portNameToIdB.port)
  1390. {
  1391. found = true;
  1392. fUsedConnections.list.remove(it);
  1393. break;
  1394. }
  1395. }
  1396. }
  1397. if (found)
  1398. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connectionToId.id, 0, 0, 0.0f, nullptr);
  1399. }
  1400. }
  1401. void handleJackClientRenameCallback(const char* const oldName, const char* const newName)
  1402. {
  1403. CARLA_SAFE_ASSERT_RETURN(oldName != nullptr && oldName[0] != '\0',);
  1404. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0',);
  1405. // ignore this if on internal patchbay mode
  1406. if (! fExternalPatchbay) return;
  1407. for (LinkedList<GroupNameToId>::Itenerator it = fUsedGroups.list.begin2(); it.valid(); it.next())
  1408. {
  1409. static GroupNameToId groupNameFallback = { 0, { '\0' } };
  1410. GroupNameToId& groupNameToId(it.getValue(groupNameFallback));
  1411. CARLA_SAFE_ASSERT_CONTINUE(groupNameToId.group != 0);
  1412. if (std::strncmp(groupNameToId.name, oldName, STR_MAX) == 0)
  1413. {
  1414. groupNameToId.rename(newName);
  1415. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED, groupNameToId.group, 0, 0, 0.0f, groupNameToId.name);
  1416. break;
  1417. }
  1418. }
  1419. }
  1420. void handleJackPortRenameCallback(const jack_port_id_t port, const char* const oldFullName, const char* const newFullName)
  1421. {
  1422. CARLA_SAFE_ASSERT_RETURN(oldFullName != nullptr && oldFullName[0] != '\0',);
  1423. CARLA_SAFE_ASSERT_RETURN(newFullName != nullptr && newFullName[0] != '\0',);
  1424. // ignore this if on internal patchbay mode
  1425. if (! fExternalPatchbay) return;
  1426. const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  1427. CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,);
  1428. const char* const shortPortName(jackbridge_port_short_name(jackPort));
  1429. CARLA_SAFE_ASSERT_RETURN(shortPortName != nullptr && shortPortName[0] != '\0',);
  1430. bool found;
  1431. CarlaString groupName(newFullName);
  1432. groupName.truncate(groupName.rfind(shortPortName, &found)-1);
  1433. CARLA_SAFE_ASSERT_RETURN(found,);
  1434. const uint groupId(fUsedGroups.getGroupId(groupName));
  1435. CARLA_SAFE_ASSERT_RETURN(groupId > 0,);
  1436. for (LinkedList<PortNameToId>::Itenerator it = fUsedPorts.list.begin2(); it.valid(); it.next())
  1437. {
  1438. static PortNameToId portNameFallback = { 0, 0, { '\0' }, { '\0' } };
  1439. PortNameToId& portNameToId(it.getValue(portNameFallback));
  1440. CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group != 0);
  1441. if (std::strncmp(portNameToId.fullName, oldFullName, STR_MAX) == 0)
  1442. {
  1443. CARLA_SAFE_ASSERT_CONTINUE(portNameToId.group == groupId);
  1444. portNameToId.rename(shortPortName, newFullName);
  1445. callback(ENGINE_CALLBACK_PATCHBAY_PORT_RENAMED, portNameToId.group, static_cast<int>(portNameToId.port), 0, 0.0f, portNameToId.name);
  1446. break;
  1447. }
  1448. }
  1449. }
  1450. #endif
  1451. void handleJackShutdownCallback()
  1452. {
  1453. const PendingRtEventsRunner prt(this);
  1454. for (uint i=0; i < pData->curPluginCount; ++i)
  1455. {
  1456. if (CarlaPlugin* const plugin = pData->plugins[i].plugin)
  1457. {
  1458. plugin->tryLock(true);
  1459. if (CarlaEngineJackClient* const client = (CarlaEngineJackClient*)plugin->getEngineClient())
  1460. client->invalidate();
  1461. plugin->unlock();
  1462. }
  1463. }
  1464. fClient = nullptr;
  1465. #ifndef BUILD_BRIDGE
  1466. carla_zeroPointers(fRackPorts, kRackPortCount);
  1467. #endif
  1468. callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
  1469. }
  1470. // -------------------------------------------------------------------
  1471. void handlePluginJackShutdownCallback(CarlaPlugin* const plugin)
  1472. {
  1473. CarlaEngineJackClient* const engineClient((CarlaEngineJackClient*)plugin->getEngineClient());
  1474. CARLA_SAFE_ASSERT_RETURN(engineClient != nullptr,);
  1475. plugin->tryLock(true);
  1476. engineClient->invalidate();
  1477. plugin->unlock();
  1478. //if (pData->nextAction.pluginId == plugin->getId())
  1479. // pData->nextAction.clearAndReset();
  1480. callback(ENGINE_CALLBACK_PLUGIN_UNAVAILABLE, plugin->getId(), 0, 0, 0.0f, "Killed by JACK");
  1481. }
  1482. // -------------------------------------------------------------------
  1483. private:
  1484. jack_client_t* fClient;
  1485. jack_position_t fTransportPos;
  1486. uint32_t fTransportState;
  1487. bool fExternalPatchbay;
  1488. bool fFreewheel;
  1489. // -------------------------------------------------------------------
  1490. #ifdef BUILD_BRIDGE
  1491. bool fIsRunning;
  1492. #else
  1493. enum RackPorts {
  1494. kRackPortAudioIn1 = 0,
  1495. kRackPortAudioIn2 = 1,
  1496. kRackPortAudioOut1 = 2,
  1497. kRackPortAudioOut2 = 3,
  1498. kRackPortEventIn = 4,
  1499. kRackPortEventOut = 5,
  1500. kRackPortCount = 6
  1501. };
  1502. jack_port_t* fRackPorts[kRackPortCount];
  1503. PatchbayGroupList fUsedGroups;
  1504. PatchbayPortList fUsedPorts;
  1505. PatchbayConnectionList fUsedConnections;
  1506. LinkedList<uint> fNewGroups;
  1507. mutable CharStringListPtr fRetConns;
  1508. bool findPluginIdAndIcon(const char* const clientName, int& pluginId, PatchbayIcon& icon) noexcept
  1509. {
  1510. carla_debug("CarlaEngineJack::findPluginIdAndIcon(\"%s\", ...)", clientName);
  1511. // TODO - this currently only works in multi-client mode
  1512. if (pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  1513. return false;
  1514. for (uint i=0; i < pData->curPluginCount; ++i)
  1515. {
  1516. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1517. if (plugin == nullptr || ! plugin->isEnabled())
  1518. continue;
  1519. const CarlaEngineJackClient* const engineClient((const CarlaEngineJackClient*)plugin->getEngineClient());
  1520. CARLA_SAFE_ASSERT_CONTINUE(engineClient != nullptr);
  1521. const char* const engineClientName(engineClient->getJackClientName());
  1522. CARLA_SAFE_ASSERT_CONTINUE(engineClientName != nullptr && engineClientName[0] != '\0');
  1523. if (std::strcmp(clientName, engineClientName) != 0)
  1524. continue;
  1525. pluginId = static_cast<int>(i);
  1526. icon = PATCHBAY_ICON_PLUGIN;
  1527. if (const char* const pluginIcon = plugin->getIconName())
  1528. {
  1529. if (pluginIcon[0] == '\0')
  1530. pass();
  1531. else if (std::strcmp(pluginIcon, "app") == 0 || std::strcmp(pluginIcon, "application") == 0)
  1532. icon = PATCHBAY_ICON_APPLICATION;
  1533. else if (std::strcmp(pluginIcon, "plugin") == 0)
  1534. icon = PATCHBAY_ICON_PLUGIN;
  1535. else if (std::strcmp(pluginIcon, "hardware") == 0)
  1536. icon = PATCHBAY_ICON_HARDWARE;
  1537. else if (std::strcmp(pluginIcon, "carla") == 0)
  1538. icon = PATCHBAY_ICON_CARLA;
  1539. else if (std::strcmp(pluginIcon, "distrho") == 0)
  1540. icon = PATCHBAY_ICON_DISTRHO;
  1541. else if (std::strcmp(pluginIcon, "file") == 0)
  1542. icon = PATCHBAY_ICON_FILE;
  1543. }
  1544. return true;
  1545. }
  1546. return false;
  1547. }
  1548. void initJackPatchbay(const char* const ourName)
  1549. {
  1550. CARLA_SAFE_ASSERT_RETURN(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY || fExternalPatchbay,);
  1551. CARLA_SAFE_ASSERT_RETURN(ourName != nullptr && ourName[0] != '\0',);
  1552. StringArray parsedGroups;
  1553. // add our client first
  1554. {
  1555. parsedGroups.add(String(ourName));
  1556. GroupNameToId groupNameToId;
  1557. groupNameToId.setData(++fUsedGroups.lastId, ourName);
  1558. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupNameToId.group, PATCHBAY_ICON_CARLA, -1, 0.0f, groupNameToId.name);
  1559. fUsedGroups.list.append(groupNameToId);
  1560. }
  1561. // query all jack ports
  1562. if (const char** const ports = jackbridge_get_ports(fClient, nullptr, nullptr, 0))
  1563. {
  1564. for (int i=0; ports[i] != nullptr; ++i)
  1565. {
  1566. const char* const fullPortName(ports[i]);
  1567. CARLA_SAFE_ASSERT_CONTINUE(fullPortName != nullptr && fullPortName[0] != '\0');
  1568. const jack_port_t* const jackPort(jackbridge_port_by_name(fClient, fullPortName));
  1569. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1570. const char* const shortPortName(jackbridge_port_short_name(jackPort));
  1571. CARLA_SAFE_ASSERT_CONTINUE(shortPortName != nullptr && shortPortName[0] != '\0');
  1572. const int jackPortFlags(jackbridge_port_flags(jackPort));
  1573. uint groupId = 0;
  1574. bool found;
  1575. CarlaString groupName(fullPortName);
  1576. groupName.truncate(groupName.rfind(shortPortName, &found)-1);
  1577. CARLA_SAFE_ASSERT_CONTINUE(found);
  1578. String jGroupName(groupName.buffer());
  1579. if (parsedGroups.contains(jGroupName))
  1580. {
  1581. groupId = fUsedGroups.getGroupId(groupName);
  1582. CARLA_SAFE_ASSERT_CONTINUE(groupId > 0);
  1583. }
  1584. else
  1585. {
  1586. groupId = ++fUsedGroups.lastId;
  1587. parsedGroups.add(jGroupName);
  1588. int pluginId = -1;
  1589. PatchbayIcon icon = (jackPortFlags & JackPortIsPhysical) ? PATCHBAY_ICON_HARDWARE : PATCHBAY_ICON_APPLICATION;
  1590. findPluginIdAndIcon(groupName, pluginId, icon);
  1591. GroupNameToId groupNameToId;
  1592. groupNameToId.setData(groupId, groupName);
  1593. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, groupNameToId.group, icon, pluginId, 0.0f, groupNameToId.name);
  1594. fUsedGroups.list.append(groupNameToId);
  1595. }
  1596. addPatchbayJackPort(groupId, jackPort, shortPortName, fullPortName, jackPortFlags);
  1597. }
  1598. jackbridge_free(ports);
  1599. }
  1600. // query connections, after all ports are in place
  1601. if (const char** const ports = jackbridge_get_ports(fClient, nullptr, nullptr, JackPortIsOutput))
  1602. {
  1603. char strBuf[STR_MAX+1];
  1604. for (int i=0; ports[i] != nullptr; ++i)
  1605. {
  1606. const char* const fullPortName(ports[i]);
  1607. CARLA_SAFE_ASSERT_CONTINUE(fullPortName != nullptr && fullPortName[0] != '\0');
  1608. const jack_port_t* const jackPort(jackbridge_port_by_name(fClient, fullPortName));
  1609. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1610. const PortNameToId& thisPort(fUsedPorts.getPortNameToId(fullPortName));
  1611. CARLA_SAFE_ASSERT_CONTINUE(thisPort.group > 0);
  1612. CARLA_SAFE_ASSERT_CONTINUE(thisPort.port > 0);
  1613. if (const char** const connections = jackbridge_port_get_all_connections(fClient, jackPort))
  1614. {
  1615. for (int j=0; connections[j] != nullptr; ++j)
  1616. {
  1617. const char* const connection(connections[j]);
  1618. CARLA_SAFE_ASSERT_CONTINUE(connection != nullptr && connection[0] != '\0');
  1619. const PortNameToId& targetPort(fUsedPorts.getPortNameToId(connection));
  1620. CARLA_SAFE_ASSERT_CONTINUE(targetPort.group > 0);
  1621. CARLA_SAFE_ASSERT_CONTINUE(targetPort.port > 0);
  1622. std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", thisPort.group, thisPort.port, targetPort.group, targetPort.port);
  1623. strBuf[STR_MAX] = '\0';
  1624. ConnectionToId connectionToId;
  1625. connectionToId.setData(++fUsedConnections.lastId, thisPort.group, thisPort.port, targetPort.group, targetPort.port);
  1626. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);
  1627. fUsedConnections.list.append(connectionToId);
  1628. }
  1629. jackbridge_free(connections);
  1630. }
  1631. }
  1632. jackbridge_free(ports);
  1633. }
  1634. }
  1635. void addPatchbayJackPort(const uint groupId, const jack_port_t* const jackPort, const char* const shortPortName, const char* const fullPortName, const int jackPortFlags)
  1636. {
  1637. bool portIsInput = (jackPortFlags & JackPortIsInput);
  1638. bool portIsAudio = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);
  1639. bool portIsMIDI = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_MIDI_TYPE) == 0);
  1640. bool portIsCV = false;
  1641. bool portIsOSC = false;
  1642. if (const jack_uuid_t uuid = jackbridge_port_uuid(jackPort))
  1643. {
  1644. char* value = nullptr;
  1645. char* type = nullptr;
  1646. if (jackbridge_get_property(uuid, JACKEY_SIGNAL_TYPE, &value, &type) && value != nullptr && type != nullptr && std::strcmp(type, "text/plain") == 0)
  1647. {
  1648. portIsCV = (std::strcmp(value, "CV") == 0);
  1649. portIsOSC = (std::strcmp(value, "OSC") == 0);
  1650. }
  1651. }
  1652. uint canvasPortFlags = 0x0;
  1653. canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0;
  1654. if (portIsCV)
  1655. canvasPortFlags |= PATCHBAY_PORT_TYPE_CV;
  1656. else if (portIsAudio)
  1657. canvasPortFlags |= PATCHBAY_PORT_TYPE_AUDIO;
  1658. else if (portIsMIDI)
  1659. canvasPortFlags |= PATCHBAY_PORT_TYPE_MIDI;
  1660. PortNameToId portNameToId;
  1661. portNameToId.setData(groupId, ++fUsedPorts.lastId, shortPortName, fullPortName);
  1662. callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), static_cast<int>(canvasPortFlags), 0.0f, portNameToId.name);
  1663. fUsedPorts.list.append(portNameToId);
  1664. return; // unused
  1665. (void)portIsOSC;
  1666. }
  1667. #endif
  1668. // -------------------------------------------------------------------
  1669. void processPlugin(CarlaPlugin* const plugin, const uint32_t nframes)
  1670. {
  1671. const uint32_t audioInCount(plugin->getAudioInCount());
  1672. const uint32_t audioOutCount(plugin->getAudioOutCount());
  1673. const uint32_t cvInCount(plugin->getCVInCount());
  1674. const uint32_t cvOutCount(plugin->getCVOutCount());
  1675. const float* audioIn[audioInCount];
  1676. /* */ float* audioOut[audioOutCount];
  1677. const float* cvIn[cvInCount];
  1678. /* */ float* cvOut[cvOutCount];
  1679. for (uint32_t i=0; i < audioInCount; ++i)
  1680. {
  1681. CarlaEngineAudioPort* const port(plugin->getAudioInPort(i));
  1682. audioIn[i] = port->getBuffer();
  1683. }
  1684. for (uint32_t i=0; i < audioOutCount; ++i)
  1685. {
  1686. CarlaEngineAudioPort* const port(plugin->getAudioOutPort(i));
  1687. audioOut[i] = port->getBuffer();
  1688. }
  1689. for (uint32_t i=0; i < cvInCount; ++i)
  1690. {
  1691. CarlaEngineCVPort* const port(plugin->getCVInPort(i));
  1692. cvIn[i] = port->getBuffer();
  1693. }
  1694. for (uint32_t i=0; i < cvOutCount; ++i)
  1695. {
  1696. CarlaEngineCVPort* const port(plugin->getCVOutPort(i));
  1697. cvOut[i] = port->getBuffer();
  1698. }
  1699. float inPeaks[2] = { 0.0f };
  1700. float outPeaks[2] = { 0.0f };
  1701. for (uint32_t i=0; i < audioInCount && i < 2; ++i)
  1702. {
  1703. for (uint32_t j=0; j < nframes; ++j)
  1704. {
  1705. const float absV(std::abs(audioIn[i][j]));
  1706. if (absV > inPeaks[i])
  1707. inPeaks[i] = absV;
  1708. }
  1709. }
  1710. plugin->process(audioIn, audioOut, cvIn, cvOut, nframes);
  1711. for (uint32_t i=0; i < audioOutCount && i < 2; ++i)
  1712. {
  1713. for (uint32_t j=0; j < nframes; ++j)
  1714. {
  1715. const float absV(std::abs(audioOut[i][j]));
  1716. if (absV > outPeaks[i])
  1717. outPeaks[i] = absV;
  1718. }
  1719. }
  1720. setPluginPeaks(plugin->getId(), inPeaks, outPeaks);
  1721. }
  1722. // -------------------------------------------------------------------
  1723. #define handlePtr ((CarlaEngineJack*)arg)
  1724. static void JACKBRIDGE_API carla_jack_thread_init_callback(void*)
  1725. {
  1726. #ifdef __SSE2_MATH__
  1727. // Set FTZ and DAZ flags
  1728. _mm_setcsr(_mm_getcsr() | 0x8040);
  1729. #endif
  1730. }
  1731. static int JACKBRIDGE_API carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg)
  1732. {
  1733. carla_stdout("JACK %s", __FUNCTION__);
  1734. carla_stdout("JACK bufSize %i", newBufferSize);
  1735. carla_stdout("JACK bufSize %p", arg);
  1736. handlePtr->handleJackBufferSizeCallback(newBufferSize);
  1737. return 0;
  1738. }
  1739. static int JACKBRIDGE_API carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg)
  1740. {
  1741. carla_stdout("JACK %s", __FUNCTION__);
  1742. carla_stdout("JACK srate %i", newSampleRate);
  1743. carla_stdout("JACK srate %p", arg);
  1744. handlePtr->handleJackSampleRateCallback(newSampleRate);
  1745. return 0;
  1746. }
  1747. static void JACKBRIDGE_API carla_jack_freewheel_callback(int starting, void* arg)
  1748. {
  1749. carla_stdout("JACK %s", __FUNCTION__);
  1750. handlePtr->handleJackFreewheelCallback(bool(starting));
  1751. }
  1752. static int JACKBRIDGE_API carla_jack_process_callback(jack_nframes_t nframes, void* arg) __attribute__((annotate("realtime")))
  1753. {
  1754. carla_stdout("PROCESS CALLBACK START");
  1755. handlePtr->handleJackProcessCallback(nframes);
  1756. carla_stdout("PROCESS CALLBACK END");
  1757. return 0;
  1758. }
  1759. static void JACKBRIDGE_API carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
  1760. {
  1761. carla_stdout("JACK %s", __FUNCTION__);
  1762. handlePtr->handleJackLatencyCallback(mode);
  1763. }
  1764. #ifndef BUILD_BRIDGE
  1765. static void JACKBRIDGE_API carla_jack_client_registration_callback(const char* name, int reg, void* arg)
  1766. {
  1767. handlePtr->handleJackClientRegistrationCallback(name, (reg != 0));
  1768. }
  1769. static void JACKBRIDGE_API carla_jack_port_registration_callback(jack_port_id_t port, int reg, void* arg)
  1770. {
  1771. handlePtr->handleJackPortRegistrationCallback(port, (reg != 0));
  1772. }
  1773. static void JACKBRIDGE_API carla_jack_port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
  1774. {
  1775. handlePtr->handleJackPortConnectCallback(a, b, (connect != 0));
  1776. }
  1777. static int JACKBRIDGE_API carla_jack_client_rename_callback(const char* oldName, const char* newName, void* arg)
  1778. {
  1779. handlePtr->handleJackClientRenameCallback(oldName, newName);
  1780. return 0;
  1781. }
  1782. // NOTE: JACK1 returns void, JACK2 returns int
  1783. static int JACKBRIDGE_API carla_jack_port_rename_callback(jack_port_id_t port, const char* oldName, const char* newName, void* arg)
  1784. {
  1785. handlePtr->handleJackPortRenameCallback(port, oldName, newName);
  1786. return 0;
  1787. }
  1788. #endif
  1789. static void JACKBRIDGE_API carla_jack_shutdown_callback(void* arg)
  1790. {
  1791. carla_stdout("JACK %s", __FUNCTION__);
  1792. handlePtr->handleJackShutdownCallback();
  1793. }
  1794. #undef handlePtr
  1795. // -------------------------------------------------------------------
  1796. #ifndef BUILD_BRIDGE
  1797. static int JACKBRIDGE_API carla_jack_process_callback_plugin(jack_nframes_t nframes, void* arg) __attribute__((annotate("realtime")))
  1798. {
  1799. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1800. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr && plugin->isEnabled(), 0);
  1801. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1802. CARLA_SAFE_ASSERT_RETURN(engine != nullptr, 0);
  1803. if (plugin->tryLock(engine->fFreewheel))
  1804. {
  1805. plugin->initBuffers();
  1806. engine->saveTransportInfo();
  1807. engine->processPlugin(plugin, nframes);
  1808. plugin->unlock();
  1809. }
  1810. return 0;
  1811. }
  1812. static void JACKBRIDGE_API carla_jack_latency_callback_plugin(jack_latency_callback_mode_t /*mode*/, void* /*arg*/)
  1813. {
  1814. // TODO
  1815. }
  1816. static void JACKBRIDGE_API carla_jack_shutdown_callback_plugin(void* arg)
  1817. {
  1818. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1819. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  1820. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1821. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
  1822. engine->handlePluginJackShutdownCallback(plugin);
  1823. }
  1824. #endif
  1825. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJack)
  1826. };
  1827. // -----------------------------------------------------------------------
  1828. CarlaEngine* CarlaEngine::newJack()
  1829. {
  1830. carla_debug("CarlaEngine::newJack()");
  1831. return new CarlaEngineJack();
  1832. }
  1833. // -----------------------------------------------------------------------
  1834. CARLA_BACKEND_END_NAMESPACE