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.

2011 lines
64KB

  1. /*
  2. * Carla JACK Engine
  3. * Copyright (C) 2012-2013 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 "CarlaBackendUtils.hpp"
  19. #include "CarlaMIDI.h"
  20. #include "List.hpp"
  21. #include "jackbridge/JackBridge.hpp"
  22. #include <cmath>
  23. #include <QtCore/QStringList>
  24. #define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon"
  25. CARLA_BACKEND_START_NAMESPACE
  26. #if 0
  27. } // Fix editor indentation
  28. #endif
  29. class CarlaEngineJack;
  30. // -----------------------------------------------------------------------
  31. // Fallback data
  32. static const EngineEvent kFallbackJackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } };
  33. // -----------------------------------------------------------------------
  34. // Carla Engine JACK-Audio port
  35. class CarlaEngineJackAudioPort : public CarlaEngineAudioPort
  36. {
  37. public:
  38. CarlaEngineJackAudioPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  39. : CarlaEngineAudioPort(engine, isInput),
  40. fClient(client),
  41. fPort(port)
  42. {
  43. carla_debug("CarlaEngineJackAudioPort::CarlaEngineJackAudioPort(%s, %p, %p)", bool2str(isInput), client, port);
  44. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  45. {
  46. CARLA_ASSERT(client != nullptr && port != nullptr);
  47. }
  48. else
  49. {
  50. CARLA_ASSERT(client == nullptr && port == nullptr);
  51. }
  52. }
  53. ~CarlaEngineJackAudioPort() override
  54. {
  55. carla_debug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()");
  56. if (fClient != nullptr && fPort != nullptr)
  57. {
  58. jackbridge_port_unregister(fClient, fPort);
  59. fClient = nullptr;
  60. fPort = nullptr;
  61. }
  62. }
  63. void initBuffer() override
  64. {
  65. if (fPort == nullptr)
  66. return CarlaEngineAudioPort::initBuffer();
  67. const uint32_t bufferSize(fEngine.getBufferSize());
  68. fBuffer = (float*)jackbridge_port_get_buffer(fPort, bufferSize);
  69. if (! fIsInput)
  70. FLOAT_CLEAR(fBuffer, bufferSize);
  71. }
  72. private:
  73. jack_client_t* fClient;
  74. jack_port_t* fPort;
  75. friend class CarlaEngineJack;
  76. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackAudioPort)
  77. };
  78. // -----------------------------------------------------------------------
  79. // Carla Engine JACK-CV port
  80. class CarlaEngineJackCVPort : public CarlaEngineCVPort
  81. {
  82. public:
  83. CarlaEngineJackCVPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  84. : CarlaEngineCVPort(engine, isInput),
  85. fClient(client),
  86. fPort(port)
  87. {
  88. carla_debug("CarlaEngineJackCVPort::CarlaEngineJackCVPort(%s, %p, %p)", bool2str(isInput), client, port);
  89. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  90. {
  91. CARLA_ASSERT(client != nullptr && port != nullptr);
  92. }
  93. else
  94. {
  95. CARLA_ASSERT(client == nullptr && port == nullptr);
  96. }
  97. }
  98. ~CarlaEngineJackCVPort() override
  99. {
  100. carla_debug("CarlaEngineJackCVPort::~CarlaEngineJackCVPort()");
  101. if (fClient != nullptr && fPort != nullptr)
  102. {
  103. jackbridge_port_unregister(fClient, fPort);
  104. fClient = nullptr;
  105. fPort = nullptr;
  106. }
  107. }
  108. void initBuffer() override
  109. {
  110. if (fPort == nullptr)
  111. return CarlaEngineCVPort::initBuffer();
  112. const uint32_t bufferSize(fEngine.getBufferSize());
  113. fBuffer = (float*)jackbridge_port_get_buffer(fPort, bufferSize);
  114. if (! fIsInput)
  115. FLOAT_CLEAR(fBuffer, bufferSize);
  116. }
  117. private:
  118. jack_client_t* fClient;
  119. jack_port_t* fPort;
  120. friend class CarlaEngineJack;
  121. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackCVPort)
  122. };
  123. // -----------------------------------------------------------------------
  124. // Carla Engine JACK-Event port
  125. class CarlaEngineJackEventPort : public CarlaEngineEventPort
  126. {
  127. public:
  128. CarlaEngineJackEventPort(const CarlaEngine& engine, const bool isInput, jack_client_t* const client, jack_port_t* const port)
  129. : CarlaEngineEventPort(engine, isInput),
  130. fClient(client),
  131. fPort(port),
  132. fJackBuffer(nullptr)
  133. {
  134. carla_debug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %p, %p)", bool2str(isInput), client, port);
  135. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  136. {
  137. CARLA_ASSERT(client != nullptr && port != nullptr);
  138. }
  139. else
  140. {
  141. CARLA_ASSERT(client == nullptr && port == nullptr);
  142. }
  143. }
  144. ~CarlaEngineJackEventPort() override
  145. {
  146. carla_debug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()");
  147. if (fClient != nullptr && fPort != nullptr)
  148. {
  149. jackbridge_port_unregister(fClient, fPort);
  150. fClient = nullptr;
  151. fPort = nullptr;
  152. }
  153. }
  154. void initBuffer() override
  155. {
  156. if (fPort == nullptr)
  157. return CarlaEngineEventPort::initBuffer();
  158. fJackBuffer = jackbridge_port_get_buffer(fPort, fEngine.getBufferSize());
  159. if (! fIsInput)
  160. jackbridge_midi_clear_buffer(fJackBuffer);
  161. }
  162. uint32_t getEventCount() const override
  163. {
  164. if (fPort == nullptr)
  165. return CarlaEngineEventPort::getEventCount();
  166. CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
  167. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, 0);
  168. return jackbridge_midi_get_event_count(fJackBuffer);
  169. }
  170. const EngineEvent& getEvent(const uint32_t index) override
  171. {
  172. if (fPort == nullptr)
  173. return CarlaEngineEventPort::getEvent(index);
  174. CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackJackEngineEvent);
  175. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, kFallbackJackEngineEvent);
  176. return getEventUnchecked(index);
  177. }
  178. const EngineEvent& getEventUnchecked(const uint32_t index) override
  179. {
  180. jack_midi_event_t jackEvent;
  181. if (! jackbridge_midi_event_get(&jackEvent, fJackBuffer, index))
  182. return kFallbackJackEngineEvent;
  183. CARLA_SAFE_ASSERT_RETURN(jackEvent.size <= 0xFF /* uint8_t max */, kFallbackJackEngineEvent);
  184. fRetEvent.time = jackEvent.time;
  185. fRetEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer);
  186. return fRetEvent;
  187. }
  188. bool writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) override
  189. {
  190. if (fPort == nullptr)
  191. return CarlaEngineEventPort::writeControlEvent(time, channel, type, param, value);
  192. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  193. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  194. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  195. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  196. CARLA_SAFE_ASSERT_RETURN(param < 0x5F, false);
  197. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  198. if (type == kEngineControlEventTypeParameter)
  199. {
  200. CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  201. }
  202. uint8_t size = 0;
  203. uint8_t data[3] = { 0, 0, 0 };
  204. EngineControlEvent ctrlEvent = { type, param, carla_fixValue<float>(0.0f, 1.0f, value) };
  205. ctrlEvent.dumpToMidiData(channel, size, data);
  206. if (size == 0)
  207. return false;
  208. return jackbridge_midi_event_write(fJackBuffer, time, data, size);
  209. }
  210. bool writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) override
  211. {
  212. if (fPort == nullptr)
  213. return CarlaEngineEventPort::writeMidiEvent(time, channel, port, size, data);
  214. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  215. CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, false);
  216. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  217. CARLA_SAFE_ASSERT_RETURN(size > 0, false);
  218. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  219. jack_midi_data_t jdata[size];
  220. jdata[0] = static_cast<jack_midi_data_t>(MIDI_GET_STATUS_FROM_DATA(data) + channel);
  221. for (uint8_t i=1; i < size; ++i)
  222. jdata[i] = data[i];
  223. return jackbridge_midi_event_write(fJackBuffer, time, jdata, size);
  224. }
  225. private:
  226. jack_client_t* fClient;
  227. jack_port_t* fPort;
  228. void* fJackBuffer;
  229. EngineEvent fRetEvent;
  230. friend class CarlaEngineJack;
  231. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackEventPort)
  232. };
  233. // -----------------------------------------------------------------------
  234. // Jack Engine client
  235. class CarlaEngineJackClient : public CarlaEngineClient
  236. {
  237. public:
  238. CarlaEngineJackClient(const CarlaEngine& engine, jack_client_t* const client)
  239. : CarlaEngineClient(engine),
  240. fClient(client),
  241. fUseClient(engine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || engine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  242. {
  243. carla_debug("CarlaEngineJackClient::CarlaEngineJackClient(%p)", client);
  244. if (fUseClient)
  245. {
  246. CARLA_ASSERT(fClient != nullptr);
  247. }
  248. else
  249. {
  250. CARLA_ASSERT(fClient == nullptr);
  251. }
  252. }
  253. ~CarlaEngineJackClient() override
  254. {
  255. carla_debug("CarlaEngineClient::~CarlaEngineClient()");
  256. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS && fClient != nullptr)
  257. jackbridge_client_close(fClient);
  258. }
  259. void activate() override
  260. {
  261. carla_debug("CarlaEngineJackClient::activate()");
  262. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  263. {
  264. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr && ! fActive,);
  265. jackbridge_activate(fClient);
  266. }
  267. CarlaEngineClient::activate();
  268. }
  269. void deactivate() override
  270. {
  271. carla_debug("CarlaEngineJackClient::deactivate()");
  272. if (fEngine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr && fActive,);
  275. jackbridge_deactivate(fClient);
  276. }
  277. CarlaEngineClient::deactivate();
  278. }
  279. bool isOk() const noexcept override
  280. {
  281. if (fUseClient)
  282. return (fClient != nullptr);
  283. return CarlaEngineClient::isOk();
  284. }
  285. #if 0
  286. void setLatency(const uint32_t samples) noexcept override
  287. {
  288. CarlaEngineClient::setLatency(samples);
  289. if (fUseClient && fClient != nullptr)
  290. {
  291. // try etc
  292. jackbridge_recompute_total_latencies(fClient);
  293. }
  294. }
  295. #endif
  296. CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) override
  297. {
  298. carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput));
  299. jack_port_t* port = nullptr;
  300. // Create JACK port first, if needed
  301. if (fUseClient && fClient != nullptr)
  302. {
  303. switch (portType)
  304. {
  305. case kEnginePortTypeNull:
  306. break;
  307. case kEnginePortTypeAudio:
  308. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  309. break;
  310. case kEnginePortTypeCV:
  311. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsControlVoltage | (isInput ? JackPortIsInput : JackPortIsOutput), 0);
  312. break;
  313. case kEnginePortTypeEvent:
  314. port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
  315. break;
  316. }
  317. }
  318. // Create Engine port
  319. switch (portType)
  320. {
  321. case kEnginePortTypeNull:
  322. break;
  323. case kEnginePortTypeAudio:
  324. return new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port);
  325. case kEnginePortTypeCV:
  326. return new CarlaEngineJackCVPort(fEngine, isInput, fClient, port);
  327. case kEnginePortTypeEvent:
  328. return new CarlaEngineJackEventPort(fEngine, isInput, fClient, port);
  329. }
  330. carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput));
  331. return nullptr;
  332. }
  333. private:
  334. jack_client_t* fClient;
  335. const bool fUseClient;
  336. friend class CarlaEngineJack;
  337. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient)
  338. };
  339. // -----------------------------------------------------------------------
  340. // Jack Engine
  341. class CarlaEngineJack : public CarlaEngine
  342. {
  343. public:
  344. CarlaEngineJack()
  345. : CarlaEngine(),
  346. fClient(nullptr),
  347. fTransportState(JackTransportStopped),
  348. fFreewheel(false),
  349. #ifdef BUILD_BRIDGE
  350. fHasQuit(false)
  351. #else
  352. fLastGroupId(0),
  353. fLastPortId(0),
  354. fLastConnectionId(0)
  355. #endif
  356. {
  357. carla_debug("CarlaEngineJack::CarlaEngineJack()");
  358. #ifdef BUILD_BRIDGE
  359. pData->options.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  360. #else
  361. carla_fill<jack_port_t*>(fRackPorts, kRackPortCount, nullptr);
  362. #endif
  363. // FIXME: Always enable JACK transport for now
  364. pData->options.transportMode = ENGINE_TRANSPORT_MODE_JACK;
  365. carla_zeroStruct<jack_position_t>(fTransportPos);
  366. }
  367. ~CarlaEngineJack() override
  368. {
  369. carla_debug("CarlaEngineJack::~CarlaEngineJack()");
  370. CARLA_ASSERT(fClient == nullptr);
  371. #ifndef BUILD_BRIDGE
  372. fUsedGroupNames.clear();
  373. fUsedPortNames.clear();
  374. fUsedConnections.clear();
  375. fGroupIconsChanged.clear();
  376. #endif
  377. }
  378. // -------------------------------------------------------------------
  379. // Maximum values
  380. unsigned int getMaxClientNameSize() const noexcept override
  381. {
  382. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  383. {
  384. unsigned int ret = 0;
  385. try {
  386. ret = static_cast<unsigned int>(jackbridge_client_name_size());
  387. }
  388. catch (...) {}
  389. return ret;
  390. }
  391. return CarlaEngine::getMaxClientNameSize();
  392. }
  393. unsigned int getMaxPortNameSize() const noexcept override
  394. {
  395. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT || pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  396. {
  397. unsigned int ret = 0;
  398. try {
  399. ret = static_cast<unsigned int>(jackbridge_port_name_size());
  400. }
  401. catch (...) {}
  402. return ret;
  403. }
  404. return CarlaEngine::getMaxPortNameSize();
  405. }
  406. // -------------------------------------------------------------------
  407. // Virtual, per-engine type calls
  408. bool init(const char* const clientName) override
  409. {
  410. carla_debug("CarlaEngineJack::init(\"%s\")", clientName);
  411. fFreewheel = false;
  412. fTransportState = JackTransportStopped;
  413. carla_zeroStruct<jack_position_t>(fTransportPos);
  414. #ifndef BUILD_BRIDGE
  415. fLastGroupId = 0;
  416. fLastPortId = 0;
  417. fLastConnectionId = 0;
  418. fUsedGroupNames.clear();
  419. fUsedPortNames.clear();
  420. fUsedConnections.clear();
  421. fGroupIconsChanged.clear();
  422. fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);
  423. if (fClient != nullptr)
  424. {
  425. pData->bufferSize = jackbridge_get_buffer_size(fClient);
  426. pData->sampleRate = jackbridge_get_sample_rate(fClient);
  427. jackbridge_custom_publish_data(fClient, URI_CANVAS_ICON, "carla", 6);
  428. jackbridge_custom_set_data_appearance_callback(fClient, carla_jack_custom_appearance_callback, this);
  429. jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
  430. jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
  431. jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
  432. jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
  433. jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
  434. jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);
  435. const char* const jackClientName(jackbridge_get_client_name(fClient));
  436. initJackPatchbay(jackClientName);
  437. jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
  438. jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
  439. jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);
  440. jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);
  441. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  442. {
  443. fRackPorts[kRackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  444. fRackPorts[kRackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  445. fRackPorts[kRackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  446. fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  447. fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  448. fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
  449. }
  450. if (jackbridge_activate(fClient))
  451. {
  452. CarlaEngine::init(jackClientName);
  453. return true;
  454. }
  455. else
  456. {
  457. setLastError("Failed to activate the JACK client");
  458. jackbridge_client_close(fClient);
  459. fClient = nullptr;
  460. }
  461. }
  462. else
  463. setLastError("Failed to create new JACK client");
  464. return false;
  465. #else
  466. if (pData->bufferSize == 0 || pData->sampleRate == 0.0)
  467. {
  468. // open temp client to get initial buffer-size and sample-rate values
  469. if (jack_client_t* tmpClient = jackbridge_client_open(clientName, JackNullOption, nullptr))
  470. {
  471. pData->bufferSize = jackbridge_get_buffer_size(tmpClient);
  472. pData->sampleRate = jackbridge_get_sample_rate(tmpClient);
  473. jackbridge_client_close(tmpClient);
  474. }
  475. }
  476. return CarlaEngine::init(clientName);
  477. #endif
  478. }
  479. bool close() override
  480. {
  481. carla_debug("CarlaEngineJack::close()");
  482. CarlaEngine::close();
  483. #ifdef BUILD_BRIDGE
  484. fClient = nullptr;
  485. fHasQuit = true;
  486. return true;
  487. #else
  488. if (jackbridge_deactivate(fClient))
  489. {
  490. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  491. {
  492. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn1]);
  493. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioIn2]);
  494. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut1]);
  495. jackbridge_port_unregister(fClient, fRackPorts[kRackPortAudioOut2]);
  496. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventIn]);
  497. jackbridge_port_unregister(fClient, fRackPorts[kRackPortEventOut]);
  498. carla_fill<jack_port_t*>(fRackPorts, kRackPortCount, nullptr);
  499. }
  500. if (jackbridge_client_close(fClient))
  501. {
  502. fClient = nullptr;
  503. return true;
  504. }
  505. else
  506. setLastError("Failed to close the JACK client");
  507. }
  508. else
  509. setLastError("Failed to deactivate the JACK client");
  510. fClient = nullptr;
  511. fUsedGroupNames.clear();
  512. fUsedPortNames.clear();
  513. fUsedConnections.clear();
  514. fGroupIconsChanged.clear();
  515. #endif
  516. return false;
  517. }
  518. #ifndef BUILD_BRIDGE
  519. void idle() override
  520. {
  521. CarlaEngine::idle();
  522. if (fGroupIconsChanged.count() == 0)
  523. return;
  524. static bool checkIcons = false;
  525. if (! checkIcons)
  526. {
  527. checkIcons = true; // check them next time
  528. return;
  529. }
  530. checkIcons = false;
  531. void* data;
  532. size_t dataSize;
  533. List<int> groupIconsCopy;
  534. fGroupIconsChanged.spliceAppend(groupIconsCopy, true);
  535. for (List<int>::Itenerator it = groupIconsCopy.begin(); it.valid(); it.next())
  536. {
  537. const int& groupId(*it);
  538. const char* const groupName(getGroupName(groupId));
  539. data = nullptr;
  540. dataSize = 0;
  541. if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0)
  542. {
  543. const char* const icon((const char*)data);
  544. CARLA_ASSERT(std::strlen(icon)+1 == dataSize);
  545. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ICON_CHANGED, 0, groupId, 0, 0.0f, icon);
  546. jackbridge_free(data);
  547. }
  548. }
  549. groupIconsCopy.clear();
  550. }
  551. #endif
  552. bool isRunning() const noexcept override
  553. {
  554. #ifdef BUILD_BRIDGE
  555. return (fClient != nullptr || ! fHasQuit);
  556. #else
  557. return (fClient != nullptr);
  558. #endif
  559. }
  560. bool isOffline() const noexcept override
  561. {
  562. return fFreewheel;
  563. }
  564. EngineType getType() const noexcept override
  565. {
  566. return kEngineTypeJack;
  567. }
  568. const char* getCurrentDriverName() const noexcept override
  569. {
  570. return "JACK";
  571. }
  572. CarlaEngineClient* addClient(CarlaPlugin* const plugin) override
  573. {
  574. const char* const iconName(plugin->getIconName());
  575. jack_client_t* client = nullptr;
  576. #ifdef BUILD_BRIDGE
  577. client = fClient = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);
  578. CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);
  579. pData->bufferSize = jackbridge_get_buffer_size(client);
  580. pData->sampleRate = jackbridge_get_sample_rate(client);
  581. jackbridge_custom_publish_data(client, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  582. jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
  583. jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
  584. jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
  585. jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
  586. jackbridge_set_process_callback(client, carla_jack_process_callback, this);
  587. jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
  588. #else
  589. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  590. {
  591. client = fClient;
  592. }
  593. else if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  594. {
  595. client = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);
  596. CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);
  597. jackbridge_custom_publish_data(client, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  598. jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin);
  599. jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin);
  600. }
  601. #endif
  602. return new CarlaEngineJackClient(*this, client);
  603. }
  604. #ifndef BUILD_BRIDGE
  605. const char* renamePlugin(const unsigned int id, const char* const newName) override
  606. {
  607. CARLA_ASSERT(pData->curPluginCount > 0);
  608. CARLA_ASSERT(id < pData->curPluginCount);
  609. CARLA_ASSERT(pData->plugins != nullptr);
  610. CARLA_ASSERT(newName != nullptr);
  611. if (pData->plugins == nullptr)
  612. {
  613. setLastError("Critical error: no plugins are currently loaded!");
  614. return nullptr;
  615. }
  616. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  617. if (plugin == nullptr)
  618. {
  619. carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id);
  620. return nullptr;
  621. }
  622. CARLA_ASSERT(plugin->getId() == id);
  623. bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT);
  624. const char* name = getUniquePluginName(newName);
  625. // TODO - use rename port if single-client
  626. // JACK client rename
  627. if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  628. {
  629. CarlaEngineJackClient* const client((CarlaEngineJackClient*)plugin->getEngineClient());
  630. #if 0
  631. if (bridge.client_rename_ptr != nullptr)
  632. {
  633. name = bridge.client_rename_ptr(client->fClient, name);
  634. }
  635. else
  636. #endif
  637. {
  638. // we should not be able to do this, jack really needs to allow client rename
  639. needsReinit = true;
  640. if (jack_client_t* jclient = jackbridge_client_open(name, JackNullOption, nullptr))
  641. {
  642. const char* const iconName(plugin->getIconName());
  643. jackbridge_custom_publish_data(jclient, URI_CANVAS_ICON, iconName, std::strlen(iconName)+1);
  644. // close old client
  645. plugin->setEnabled(false);
  646. if (client->isActive())
  647. client->deactivate();
  648. plugin->clearBuffers();
  649. jackbridge_client_close(client->fClient);
  650. // set new client data
  651. name = jackbridge_get_client_name(jclient);
  652. jackbridge_set_process_callback(jclient, carla_jack_process_callback_plugin, plugin);
  653. jackbridge_set_latency_callback(jclient, carla_jack_latency_callback_plugin, plugin);
  654. client->fClient = jclient;
  655. }
  656. }
  657. }
  658. if (name == nullptr)
  659. return nullptr;
  660. // Rename
  661. plugin->setName(name);
  662. if (needsReinit)
  663. {
  664. // reload plugin to recreate its ports
  665. const SaveState& saveState(plugin->getSaveState());
  666. plugin->reload();
  667. plugin->loadSaveState(saveState);
  668. }
  669. return name;
  670. }
  671. // -------------------------------------------------------------------
  672. // Patchbay
  673. bool patchbayConnect(int portA, int portB) override
  674. {
  675. CARLA_ASSERT(fClient != nullptr);
  676. if (fClient == nullptr)
  677. {
  678. setLastError("Invalid JACK client");
  679. return false;
  680. }
  681. char portNameA[STR_MAX+1];
  682. char portNameB[STR_MAX+1];
  683. getFullPortName(portA, portNameA);
  684. getFullPortName(portB, portNameB);
  685. if (! jackbridge_connect(fClient, portNameA, portNameB))
  686. {
  687. setLastError("JACK operation failed");
  688. return false;
  689. }
  690. return true;
  691. }
  692. bool patchbayDisconnect(int connectionId) override
  693. {
  694. CARLA_ASSERT(fClient != nullptr);
  695. if (fClient == nullptr)
  696. {
  697. setLastError("Invalid JACK client");
  698. return false;
  699. }
  700. for (List<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
  701. {
  702. const ConnectionToId& connectionToId(*it);
  703. if (connectionToId.id == connectionId)
  704. {
  705. char portNameOut[STR_MAX+1];
  706. char portNameIn[STR_MAX+1];
  707. getFullPortName(connectionToId.portOut, portNameOut);
  708. getFullPortName(connectionToId.portIn, portNameIn);
  709. if (! jackbridge_disconnect(fClient, portNameOut, portNameIn))
  710. {
  711. setLastError("JACK operation failed");
  712. return false;
  713. }
  714. return true;
  715. }
  716. }
  717. setLastError("Failed to find the requested connection");
  718. return false;
  719. }
  720. bool patchbayRefresh() override
  721. {
  722. CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);
  723. fLastGroupId = 0;
  724. fLastPortId = 0;
  725. fLastConnectionId = 0;
  726. fUsedGroupNames.clear();
  727. fUsedPortNames.clear();
  728. fUsedConnections.clear();
  729. fGroupIconsChanged.clear();
  730. initJackPatchbay(jackbridge_get_client_name(fClient));
  731. return true;
  732. }
  733. #endif
  734. // -------------------------------------------------------------------
  735. // Transport
  736. void transportPlay() override
  737. {
  738. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  739. CarlaEngine::transportPlay();
  740. else if (fClient != nullptr)
  741. jackbridge_transport_start(fClient);
  742. }
  743. void transportPause() override
  744. {
  745. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  746. CarlaEngine::transportPause();
  747. else if (fClient != nullptr)
  748. jackbridge_transport_stop(fClient);
  749. }
  750. void transportRelocate(const uint64_t frame) override
  751. {
  752. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  753. CarlaEngine::transportRelocate(frame);
  754. else if (fClient != nullptr)
  755. jackbridge_transport_locate(fClient, static_cast<jack_nframes_t>(frame));
  756. }
  757. // -------------------------------------------------------------------
  758. protected:
  759. void handleJackBufferSizeCallback(const uint32_t newBufferSize)
  760. {
  761. if (pData->bufferSize == newBufferSize)
  762. return;
  763. pData->bufferSize = newBufferSize;
  764. bufferSizeChanged(newBufferSize);
  765. }
  766. void handleJackSampleRateCallback(const double newSampleRate)
  767. {
  768. if (pData->sampleRate == newSampleRate)
  769. return;
  770. pData->sampleRate = newSampleRate;
  771. sampleRateChanged(newSampleRate);
  772. }
  773. void handleJackFreewheelCallback(const bool isFreewheel)
  774. {
  775. if (fFreewheel == isFreewheel)
  776. return;
  777. fFreewheel = isFreewheel;
  778. offlineModeChanged(isFreewheel);
  779. }
  780. void saveTransportInfo()
  781. {
  782. if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
  783. return;
  784. fTransportPos.unique_1 = fTransportPos.unique_2 + 1; // invalidate
  785. fTransportState = jackbridge_transport_query(fClient, &fTransportPos);
  786. pData->timeInfo.playing = (fTransportState == JackTransportRolling);
  787. if (fTransportPos.unique_1 == fTransportPos.unique_2)
  788. {
  789. pData->timeInfo.frame = fTransportPos.frame;
  790. pData->timeInfo.usecs = fTransportPos.usecs;
  791. if (fTransportPos.valid & JackPositionBBT)
  792. {
  793. pData->timeInfo.valid = EngineTimeInfo::kValidBBT;
  794. pData->timeInfo.bbt.bar = fTransportPos.bar;
  795. pData->timeInfo.bbt.beat = fTransportPos.beat;
  796. pData->timeInfo.bbt.tick = fTransportPos.tick;
  797. pData->timeInfo.bbt.barStartTick = fTransportPos.bar_start_tick;
  798. pData->timeInfo.bbt.beatsPerBar = fTransportPos.beats_per_bar;
  799. pData->timeInfo.bbt.beatType = fTransportPos.beat_type;
  800. pData->timeInfo.bbt.ticksPerBeat = fTransportPos.ticks_per_beat;
  801. pData->timeInfo.bbt.beatsPerMinute = fTransportPos.beats_per_minute;
  802. }
  803. else
  804. pData->timeInfo.valid = 0x0;
  805. }
  806. else
  807. {
  808. pData->timeInfo.frame = 0;
  809. pData->timeInfo.valid = 0x0;
  810. }
  811. }
  812. void handleJackProcessCallback(const uint32_t nframes)
  813. {
  814. saveTransportInfo();
  815. if (pData->curPluginCount == 0)
  816. {
  817. #ifndef BUILD_BRIDGE
  818. // pass-through
  819. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  820. {
  821. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  822. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  823. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  824. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  825. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  826. FLOAT_COPY(audioOut1, audioIn1, nframes);
  827. FLOAT_COPY(audioOut2, audioIn2, nframes);
  828. jackbridge_midi_clear_buffer(eventOut);
  829. }
  830. #endif
  831. return runPendingRtEvents();
  832. }
  833. #ifdef BUILD_BRIDGE
  834. CarlaPlugin* const plugin(pData->plugins[0].plugin);
  835. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  836. {
  837. plugin->initBuffers();
  838. processPlugin(plugin, nframes);
  839. plugin->unlock();
  840. }
  841. return runPendingRtEvents();
  842. #else
  843. if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  844. {
  845. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  846. {
  847. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  848. if (plugin != nullptr && plugin->isEnabled() && plugin->tryLock(fFreewheel))
  849. {
  850. plugin->initBuffers();
  851. processPlugin(plugin, nframes);
  852. plugin->unlock();
  853. }
  854. }
  855. return runPendingRtEvents();
  856. }
  857. if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  858. {
  859. // get buffers from jack
  860. float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn1], nframes);
  861. float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioIn2], nframes);
  862. float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut1], nframes);
  863. float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[kRackPortAudioOut2], nframes);
  864. void* const eventIn = jackbridge_port_get_buffer(fRackPorts[kRackPortEventIn], nframes);
  865. void* const eventOut = jackbridge_port_get_buffer(fRackPorts[kRackPortEventOut], nframes);
  866. // assert buffers
  867. CARLA_ASSERT(audioIn1 != nullptr);
  868. CARLA_ASSERT(audioIn2 != nullptr);
  869. CARLA_ASSERT(audioOut1 != nullptr);
  870. CARLA_ASSERT(audioOut2 != nullptr);
  871. CARLA_ASSERT(eventIn != nullptr);
  872. CARLA_ASSERT(eventOut != nullptr);
  873. // create audio buffers
  874. float* inBuf[2] = { audioIn1, audioIn2 };
  875. float* outBuf[2] = { audioOut1, audioOut2 };
  876. // initialize input events
  877. carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount);
  878. {
  879. uint32_t engineEventIndex = 0;
  880. jack_midi_event_t jackEvent;
  881. const uint32_t jackEventCount(jackbridge_midi_get_event_count(eventIn));
  882. for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; ++jackEventIndex)
  883. {
  884. if (! jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex))
  885. continue;
  886. CARLA_SAFE_ASSERT_CONTINUE(jackEvent.size <= 0xFF /* uint8_t max */);
  887. EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
  888. engineEvent.time = jackEvent.time;
  889. engineEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer);
  890. if (engineEventIndex >= kEngineMaxInternalEventCount)
  891. break;
  892. }
  893. }
  894. // process rack
  895. processRack(inBuf, outBuf, nframes);
  896. // output control
  897. {
  898. jackbridge_midi_clear_buffer(eventOut);
  899. for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i)
  900. {
  901. const EngineEvent& engineEvent(pData->bufEvents.out[i]);
  902. uint8_t size = 0;
  903. uint8_t data[3] = { 0, 0, 0 };
  904. uint8_t* dataPtr = data;
  905. switch (engineEvent.type)
  906. {
  907. case kEngineEventTypeNull:
  908. break;
  909. case kEngineEventTypeControl:
  910. {
  911. const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
  912. ctrlEvent.dumpToMidiData(engineEvent.channel, size, data);
  913. break;
  914. }
  915. case kEngineEventTypeMidi:
  916. {
  917. const EngineMidiEvent& midiEvent(engineEvent.midi);
  918. size = midiEvent.size;
  919. if (size > EngineMidiEvent::kDataSize && midiEvent.dataExt != nullptr)
  920. dataPtr = midiEvent.dataExt;
  921. else
  922. dataPtr = midiEvent.dataExt;
  923. break;
  924. }
  925. }
  926. if (size > 0)
  927. jackbridge_midi_event_write(eventOut, engineEvent.time, dataPtr, size);
  928. }
  929. }
  930. return runPendingRtEvents();
  931. }
  932. #endif // ! BUILD_BRIDGE
  933. runPendingRtEvents();
  934. }
  935. void handleJackLatencyCallback(const jack_latency_callback_mode_t mode)
  936. {
  937. if (pData->options.processMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  938. return;
  939. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  940. {
  941. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  942. if (plugin != nullptr && plugin->isEnabled())
  943. latencyPlugin(plugin, mode);
  944. }
  945. }
  946. #ifndef BUILD_BRIDGE
  947. void handleCustomAppearanceCallback(const char* client_name, const char* key, jack_custom_change_t change)
  948. {
  949. if ((change == JackCustomAdded || change == JackCustomReplaced) && std::strcmp(key, URI_CANVAS_ICON) == 0)
  950. {
  951. const int groupId (getGroupId(client_name));
  952. if (groupId == -1)
  953. return;
  954. fGroupIconsChanged.append(groupId);
  955. }
  956. }
  957. void handleJackClientRegistrationCallback(const char* const name, const bool reg)
  958. {
  959. // do nothing on client registration, wait for first port
  960. if (reg) return;
  961. const int id(getGroupId(name)); // also checks name nullness
  962. if (id == -1)
  963. return;
  964. GroupNameToId groupNameId(id, name);
  965. fUsedGroupNames.removeAll(groupNameId);
  966. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_REMOVED, 0, id, 0, 0.0f, name);
  967. }
  968. void handleJackPortRegistrationCallback(const jack_port_id_t port, const bool reg)
  969. {
  970. jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  971. const char* const portName(jackbridge_port_short_name(jackPort));
  972. const char* const fullPortName(jackbridge_port_name(jackPort));
  973. CARLA_ASSERT(jackPort != nullptr);
  974. CARLA_ASSERT(portName != nullptr);
  975. CARLA_ASSERT(fullPortName != nullptr);
  976. if (jackPort == nullptr)
  977. return;
  978. if (portName == nullptr)
  979. return;
  980. if (fullPortName == nullptr)
  981. return;
  982. CarlaString groupName(fullPortName);
  983. groupName.truncate(groupName.rfind(portName)-1);
  984. int groupId = getGroupId(groupName);
  985. if (reg)
  986. {
  987. const int jackPortFlags(jackbridge_port_flags(jackPort));
  988. if (groupId == -1)
  989. {
  990. groupId = fLastGroupId++;
  991. GroupNameToId groupNameToId(groupId, groupName);
  992. fUsedGroupNames.append(groupNameToId);
  993. if (jackPortFlags & JackPortIsPhysical)
  994. {
  995. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupId, 0, 0.0f, groupName);
  996. // hardware
  997. }
  998. else
  999. {
  1000. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupId, 0, 0.0f, groupName);
  1001. fGroupIconsChanged.append(groupId);
  1002. // "application"
  1003. }
  1004. }
  1005. bool portIsInput = (jackPortFlags & JackPortIsInput);
  1006. bool portIsAudio = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);
  1007. bool portIsCV = (jackPortFlags & JackPortIsControlVoltage);
  1008. unsigned int canvasPortFlags = 0x0;
  1009. canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0;
  1010. canvasPortFlags |= portIsAudio ? PATCHBAY_PORT_TYPE_AUDIO : PATCHBAY_PORT_TYPE_MIDI;
  1011. if (portIsAudio && portIsCV)
  1012. canvasPortFlags |= PATCHBAY_PORT_TYPE_CV;
  1013. PortNameToId portNameToId(groupId, fLastPortId++, portName, fullPortName);
  1014. fUsedPortNames.append(portNameToId);
  1015. callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, groupId, portNameToId.portId, canvasPortFlags, 0.0f, portName);
  1016. }
  1017. else
  1018. {
  1019. const int portId(getPortId(fullPortName));
  1020. CARLA_ASSERT(groupId != -1);
  1021. CARLA_ASSERT(portId != -1);
  1022. if (groupId == -1 || portId == -1)
  1023. return;
  1024. PortNameToId portNameId(groupId, portId, portName, fullPortName);
  1025. fUsedPortNames.removeOne(portNameId);
  1026. callback(ENGINE_CALLBACK_PATCHBAY_PORT_REMOVED, 0, groupId, portId, 0.0f, portName);
  1027. }
  1028. }
  1029. void handleJackPortConnectCallback(const jack_port_id_t a, const jack_port_id_t b, const bool connect)
  1030. {
  1031. jack_port_t* const jackPortA(jackbridge_port_by_id(fClient, a));
  1032. jack_port_t* const jackPortB(jackbridge_port_by_id(fClient, b));
  1033. const char* const fullPortNameA(jackbridge_port_name(jackPortA));
  1034. const char* const fullPortNameB(jackbridge_port_name(jackPortB));
  1035. CARLA_ASSERT(jackPortA != nullptr);
  1036. CARLA_ASSERT(jackPortB != nullptr);
  1037. CARLA_ASSERT(fullPortNameA != nullptr);
  1038. CARLA_ASSERT(fullPortNameB != nullptr);
  1039. if (jackPortA == nullptr)
  1040. return;
  1041. if (jackPortB == nullptr)
  1042. return;
  1043. if (fullPortNameA == nullptr)
  1044. return;
  1045. if (fullPortNameB == nullptr)
  1046. return;
  1047. const int portIdA(getPortId(fullPortNameA));
  1048. const int portIdB(getPortId(fullPortNameB));
  1049. if (portIdA == -1 || portIdB == -1)
  1050. return;
  1051. if (connect)
  1052. {
  1053. ConnectionToId connectionToId(fLastConnectionId++, portIdA, portIdB);
  1054. fUsedConnections.append(connectionToId);
  1055. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, portIdA, portIdB, 0.0f, nullptr);
  1056. }
  1057. else
  1058. {
  1059. for (List<ConnectionToId>::Itenerator it = fUsedConnections.begin(); it.valid(); it.next())
  1060. {
  1061. const ConnectionToId& connectionToId(*it);
  1062. if (connectionToId.portOut == portIdA && connectionToId.portIn == portIdB)
  1063. {
  1064. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, 0, connectionToId.id, 0, 0.0f, nullptr);
  1065. fUsedConnections.remove(it);
  1066. break;
  1067. }
  1068. }
  1069. }
  1070. }
  1071. void handleJackClientRenameCallback(const char* const oldName, const char* const newName)
  1072. {
  1073. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1074. {
  1075. GroupNameToId& groupNameToId(*it);
  1076. if (std::strcmp(groupNameToId.name, oldName) == 0)
  1077. {
  1078. groupNameToId.rename(newName);
  1079. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_RENAMED, 0, groupNameToId.id, 0, 0.0f, newName);
  1080. break;
  1081. }
  1082. }
  1083. }
  1084. void handleJackPortRenameCallback(const jack_port_id_t port, const char* const oldName, const char* const newName)
  1085. {
  1086. jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port));
  1087. const char* const portName(jackbridge_port_short_name(jackPort));
  1088. CARLA_ASSERT(jackPort != nullptr);
  1089. CARLA_ASSERT(portName != nullptr);
  1090. if (jackPort == nullptr)
  1091. return;
  1092. if (portName == nullptr)
  1093. return;
  1094. CarlaString groupName(newName);
  1095. groupName.truncate(groupName.rfind(portName)-1);
  1096. const int groupId(getGroupId(groupName));
  1097. CARLA_ASSERT(groupId != -1);
  1098. if (groupId == -1)
  1099. return;
  1100. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1101. {
  1102. PortNameToId& portNameId(*it);
  1103. if (std::strcmp(portNameId.fullName, oldName) == 0)
  1104. {
  1105. CARLA_ASSERT(portNameId.groupId == groupId);
  1106. portNameId.rename(portName, newName);
  1107. callback(ENGINE_CALLBACK_PATCHBAY_PORT_RENAMED, 0, groupId, portNameId.portId, 0.0f, newName);
  1108. break;
  1109. }
  1110. }
  1111. }
  1112. #endif
  1113. void handleJackShutdownCallback()
  1114. {
  1115. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1116. {
  1117. //CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1118. //if (plugin)
  1119. // plugin->x_client = nullptr;
  1120. }
  1121. fClient = nullptr;
  1122. callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
  1123. }
  1124. // -------------------------------------------------------------------
  1125. private:
  1126. jack_client_t* fClient;
  1127. jack_position_t fTransportPos;
  1128. jack_transport_state_t fTransportState;
  1129. bool fFreewheel;
  1130. // -------------------------------------------------------------------
  1131. #ifdef BUILD_BRIDGE
  1132. bool fHasQuit;
  1133. #else
  1134. enum RackPorts {
  1135. kRackPortAudioIn1 = 0,
  1136. kRackPortAudioIn2 = 1,
  1137. kRackPortAudioOut1 = 2,
  1138. kRackPortAudioOut2 = 3,
  1139. kRackPortEventIn = 4,
  1140. kRackPortEventOut = 5,
  1141. kRackPortCount = 6
  1142. };
  1143. jack_port_t* fRackPorts[kRackPortCount];
  1144. struct GroupNameToId {
  1145. int id;
  1146. char name[STR_MAX+1];
  1147. GroupNameToId()
  1148. {
  1149. id = -1;
  1150. name[0] = '\0';
  1151. }
  1152. GroupNameToId(const int id, const char name[])
  1153. {
  1154. this->id = id;
  1155. std::strncpy(this->name, name, STR_MAX);
  1156. this->name[STR_MAX] = '\0';
  1157. }
  1158. void rename(const char name[])
  1159. {
  1160. std::strncpy(this->name, name, STR_MAX);
  1161. this->name[STR_MAX] = '\0';
  1162. }
  1163. bool operator==(const GroupNameToId& groupNameId)
  1164. {
  1165. if (groupNameId.id != id)
  1166. return false;
  1167. if (std::strcmp(groupNameId.name, name) != 0)
  1168. return false;
  1169. return true;
  1170. }
  1171. };
  1172. struct PortNameToId {
  1173. int groupId;
  1174. int portId;
  1175. char name[STR_MAX+1];
  1176. char fullName[STR_MAX+1]; // unique
  1177. PortNameToId()
  1178. {
  1179. groupId = -1;
  1180. portId = -1;
  1181. name[0] = '\0';
  1182. fullName[0] = '\0';
  1183. }
  1184. PortNameToId(const int groupId, const int portId, const char name[], const char fullName[])
  1185. {
  1186. this->groupId = groupId;
  1187. this->portId = portId;
  1188. std::strncpy(this->name, name, STR_MAX);
  1189. this->name[STR_MAX] = '\0';
  1190. std::strncpy(this->fullName, fullName, STR_MAX);
  1191. this->fullName[STR_MAX] = '\0';
  1192. }
  1193. void rename(const char name[], const char fullName[])
  1194. {
  1195. std::strncpy(this->name, name, STR_MAX);
  1196. this->name[STR_MAX] = '\0';
  1197. std::strncpy(this->fullName, fullName, STR_MAX);
  1198. this->fullName[STR_MAX] = '\0';
  1199. }
  1200. bool operator==(const PortNameToId& portNameId)
  1201. {
  1202. if (portNameId.groupId != groupId)
  1203. return false;
  1204. if (portNameId.portId != portId)
  1205. return false;
  1206. if (std::strcmp(portNameId.name, name) != 0)
  1207. return false;
  1208. if (std::strcmp(portNameId.fullName, fullName) != 0)
  1209. return false;
  1210. return true;
  1211. }
  1212. };
  1213. struct ConnectionToId {
  1214. int id;
  1215. int portOut;
  1216. int portIn;
  1217. ConnectionToId()
  1218. {
  1219. id = -1;
  1220. portOut = -1;
  1221. portIn = -1;
  1222. }
  1223. ConnectionToId(const int id, const int portOut, const int portIn)
  1224. {
  1225. this->id = id;
  1226. this->portOut = portOut;
  1227. this->portIn = portIn;
  1228. }
  1229. bool operator==(const ConnectionToId& connectionId)
  1230. {
  1231. if (connectionId.id != id)
  1232. return false;
  1233. if (connectionId.portOut != portOut)
  1234. return false;
  1235. if (connectionId.portIn != portIn)
  1236. return false;
  1237. return true;
  1238. }
  1239. };
  1240. int fLastGroupId;
  1241. int fLastPortId;
  1242. int fLastConnectionId;
  1243. List<GroupNameToId> fUsedGroupNames;
  1244. List<PortNameToId> fUsedPortNames;
  1245. List<ConnectionToId> fUsedConnections;
  1246. List<int> fGroupIconsChanged;
  1247. int getGroupId(const char* const name)
  1248. {
  1249. CARLA_ASSERT(name != nullptr);
  1250. if (name == nullptr)
  1251. return -1;
  1252. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1253. {
  1254. const GroupNameToId& groupNameId(*it);
  1255. if (std::strcmp(groupNameId.name, name) == 0)
  1256. return groupNameId.id;
  1257. }
  1258. return -1;
  1259. }
  1260. const char* getGroupName(const int groupId)
  1261. {
  1262. CARLA_ASSERT(groupId >= 0);
  1263. static const char fallback[1] = { '\0' };
  1264. if (groupId < 0)
  1265. return fallback;
  1266. for (List<GroupNameToId>::Itenerator it = fUsedGroupNames.begin(); it.valid(); it.next())
  1267. {
  1268. const GroupNameToId& groupNameId(*it);
  1269. if (groupNameId.id == groupId)
  1270. return groupNameId.name;
  1271. }
  1272. return fallback;
  1273. }
  1274. int getPortId(const char* const fullName)
  1275. {
  1276. CARLA_ASSERT(fullName != nullptr);
  1277. if (fullName == nullptr)
  1278. return -1;
  1279. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1280. {
  1281. const PortNameToId& portNameId(*it);
  1282. if (std::strcmp(portNameId.fullName, fullName) == 0)
  1283. return portNameId.portId;
  1284. }
  1285. return -1;
  1286. }
  1287. void getFullPortName(const int portId, char nameBuf[STR_MAX+1])
  1288. {
  1289. for (List<PortNameToId>::Itenerator it = fUsedPortNames.begin(); it.valid(); it.next())
  1290. {
  1291. const PortNameToId& portNameId(*it);
  1292. if (portNameId.portId == portId)
  1293. {
  1294. std::strncpy(nameBuf, portNameId.fullName, STR_MAX);
  1295. nameBuf[STR_MAX] = '\0';
  1296. return;
  1297. }
  1298. }
  1299. nameBuf[0] = '\0';
  1300. }
  1301. void initJackPatchbay(const char* const ourName)
  1302. {
  1303. CARLA_ASSERT(fLastGroupId == 0);
  1304. CARLA_ASSERT(fLastPortId == 0);
  1305. CARLA_ASSERT(fLastConnectionId == 0);
  1306. CARLA_ASSERT(ourName != nullptr);
  1307. #ifdef HAVE_JUCE
  1308. using namespace juce;
  1309. // query initial jack ports
  1310. StringArray parsedGroups;
  1311. // our client
  1312. if (ourName != nullptr)
  1313. {
  1314. parsedGroups.add(String(ourName));
  1315. GroupNameToId groupNameToId(fLastGroupId++, ourName);
  1316. fUsedGroupNames.append(groupNameToId);
  1317. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupNameToId.id, 0, 0.0f, ourName);
  1318. // carla
  1319. }
  1320. if (const char** ports = jackbridge_get_ports(fClient, nullptr, nullptr, 0))
  1321. {
  1322. for (int i=0; ports[i] != nullptr; ++i)
  1323. {
  1324. jack_port_t* const jackPort(jackbridge_port_by_name(fClient, ports[i]));
  1325. const char* const portName(jackbridge_port_short_name(jackPort));
  1326. const char* const fullPortName(ports[i]);
  1327. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1328. CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr);
  1329. const int jackPortFlags(jackbridge_port_flags(jackPort));
  1330. int groupId = -1;
  1331. CarlaString groupName(fullPortName);
  1332. groupName.truncate(groupName.rfind(portName)-1);
  1333. String qGroupName(groupName);
  1334. if (parsedGroups.contains(qGroupName))
  1335. {
  1336. groupId = getGroupId(groupName);
  1337. CARLA_ASSERT(groupId != -1);
  1338. }
  1339. else
  1340. {
  1341. groupId = fLastGroupId++;
  1342. parsedGroups.add(qGroupName);
  1343. GroupNameToId groupNameToId(groupId, groupName);
  1344. fUsedGroupNames.append(groupNameToId);
  1345. void* data = nullptr;
  1346. size_t dataSize = 0;
  1347. if (jackPortFlags & JackPortIsPhysical)
  1348. {
  1349. // "hardware"
  1350. }
  1351. else if (jackbridge_custom_get_data(fClient, groupName, URI_CANVAS_ICON, &data, &dataSize) && data != nullptr && dataSize != 0)
  1352. {
  1353. //const char* const icon((const char*)data);
  1354. //CARLA_ASSERT(std::strlen(icon)+1 == dataSize);
  1355. // icon
  1356. }
  1357. callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, 0, groupId, 0, 0.0f, groupName);
  1358. }
  1359. bool portIsInput = (jackPortFlags & JackPortIsInput);
  1360. bool portIsAudio = (std::strcmp(jackbridge_port_type(jackPort), JACK_DEFAULT_AUDIO_TYPE) == 0);
  1361. bool portIsCV = (jackPortFlags & JackPortIsControlVoltage);
  1362. unsigned int canvasPortFlags = 0x0;
  1363. canvasPortFlags |= portIsInput ? PATCHBAY_PORT_IS_INPUT : 0x0;
  1364. canvasPortFlags |= portIsAudio ? PATCHBAY_PORT_TYPE_AUDIO : PATCHBAY_PORT_TYPE_MIDI;
  1365. if (portIsAudio && portIsCV)
  1366. canvasPortFlags |= PATCHBAY_PORT_TYPE_CV;
  1367. PortNameToId portNameToId(groupId, fLastPortId++, portName, fullPortName);
  1368. fUsedPortNames.append(portNameToId);
  1369. callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, groupId, portNameToId.portId, canvasPortFlags, 0.0f, portName);
  1370. }
  1371. #if 0
  1372. jackbridge_free(ports);
  1373. }
  1374. // query connections, after all ports are in place
  1375. if (const char** ports = jackbridge_get_ports(fClient, nullptr, nullptr, JackPortIsOutput))
  1376. {
  1377. #endif
  1378. for (int i=0; ports[i] != nullptr; ++i)
  1379. {
  1380. jack_port_t* const jackPort(jackbridge_port_by_name(fClient, ports[i]));
  1381. const char* const fullPortName(ports[i]);
  1382. CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr);
  1383. #if 1
  1384. const int jackPortFlags(jackbridge_port_flags(jackPort));
  1385. if (jackPortFlags & JackPortIsInput)
  1386. continue;
  1387. #endif
  1388. const int thisPortId(getPortId(fullPortName));
  1389. if (thisPortId == -1)
  1390. continue;
  1391. if (const char** connections = jackbridge_port_get_all_connections(fClient, jackPort))
  1392. {
  1393. for (int j=0; connections[j] != nullptr; ++j)
  1394. {
  1395. const int targetPortId(getPortId(connections[j]));
  1396. ConnectionToId connectionToId(fLastConnectionId++, thisPortId, targetPortId);
  1397. fUsedConnections.append(connectionToId);
  1398. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, thisPortId, targetPortId, 0.0f, nullptr);
  1399. }
  1400. jackbridge_free(connections);
  1401. }
  1402. else
  1403. carla_stderr("jack_port_get_all_connections failed for port %s", fullPortName);
  1404. }
  1405. jackbridge_free(ports);
  1406. }
  1407. #endif
  1408. }
  1409. #endif
  1410. // -------------------------------------
  1411. void processPlugin(CarlaPlugin* const plugin, const uint32_t nframes)
  1412. {
  1413. const uint32_t inCount(plugin->getAudioInCount());
  1414. const uint32_t outCount(plugin->getAudioOutCount());
  1415. float* inBuffer[inCount];
  1416. float* outBuffer[outCount];
  1417. float inPeaks[2] = { 0.0f };
  1418. float outPeaks[2] = { 0.0f };
  1419. for (uint32_t i=0; i < inCount; ++i)
  1420. {
  1421. CarlaEngineAudioPort* const port(plugin->getAudioInPort(i));
  1422. inBuffer[i] = port->getBuffer();
  1423. }
  1424. for (uint32_t i=0; i < outCount; ++i)
  1425. {
  1426. CarlaEngineAudioPort* const port(plugin->getAudioOutPort(i));
  1427. outBuffer[i] = port->getBuffer();
  1428. }
  1429. for (uint32_t i=0; i < inCount && i < 2; ++i)
  1430. {
  1431. for (uint32_t j=0; j < nframes; ++j)
  1432. {
  1433. const float absV(std::abs(inBuffer[i][j]));
  1434. if (absV > inPeaks[i])
  1435. inPeaks[i] = absV;
  1436. }
  1437. }
  1438. plugin->process(inBuffer, outBuffer, nframes);
  1439. for (uint32_t i=0; i < outCount && i < 2; ++i)
  1440. {
  1441. for (uint32_t j=0; j < nframes; ++j)
  1442. {
  1443. const float absV(std::abs(outBuffer[i][j]));
  1444. if (absV > outPeaks[i])
  1445. outPeaks[i] = absV;
  1446. }
  1447. }
  1448. setPluginPeaks(plugin->getId(), inPeaks, outPeaks);
  1449. }
  1450. void latencyPlugin(CarlaPlugin* const plugin, jack_latency_callback_mode_t mode)
  1451. {
  1452. //const uint32_t inCount(plugin->audioInCount());
  1453. //const uint32_t outCount(plugin->audioOutCount());
  1454. const uint32_t latency(plugin->getLatencyInFrames());
  1455. if (latency == 0)
  1456. return;
  1457. //jack_latency_range_t range;
  1458. // TODO
  1459. if (mode == JackCaptureLatency)
  1460. {
  1461. #if 0
  1462. for (uint32_t i=0; i < inCount; ++i)
  1463. {
  1464. uint32_t aOutI = (i >= outCount) ? outCount : i;
  1465. jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioInPort(plugin, i))->kPort;
  1466. jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioOutPort(plugin, aOutI))->kPort;
  1467. jackbridge_port_get_latency_range(portIn, mode, &range);
  1468. range.min += latency;
  1469. range.max += latency;
  1470. jackbridge_port_set_latency_range(portOut, mode, &range);
  1471. }
  1472. #endif
  1473. }
  1474. else
  1475. {
  1476. #if 0
  1477. for (uint32_t i=0; i < outCount; ++i)
  1478. {
  1479. uint32_t aInI = (i >= inCount) ? inCount : i;
  1480. jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioInPort(plugin, aInI))->kPort;
  1481. jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)CarlaPluginGetAudioOutPort(plugin, i))->kPort;
  1482. jackbridge_port_get_latency_range(portOut, mode, &range);
  1483. range.min += latency;
  1484. range.max += latency;
  1485. jackbridge_port_set_latency_range(portIn, mode, &range);
  1486. }
  1487. #endif
  1488. }
  1489. }
  1490. // -------------------------------------
  1491. #define handlePtr ((CarlaEngineJack*)arg)
  1492. static int carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg)
  1493. {
  1494. handlePtr->handleJackBufferSizeCallback(newBufferSize);
  1495. return 0;
  1496. }
  1497. static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg)
  1498. {
  1499. handlePtr->handleJackSampleRateCallback(newSampleRate);
  1500. return 0;
  1501. }
  1502. static void carla_jack_freewheel_callback(int starting, void* arg)
  1503. {
  1504. handlePtr->handleJackFreewheelCallback(bool(starting));
  1505. }
  1506. static int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
  1507. {
  1508. handlePtr->handleJackProcessCallback(nframes);
  1509. return 0;
  1510. }
  1511. static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
  1512. {
  1513. handlePtr->handleJackLatencyCallback(mode);
  1514. }
  1515. #ifndef BUILD_BRIDGE
  1516. static void carla_jack_custom_appearance_callback(const char* client_name, const char* key, jack_custom_change_t change, void* arg)
  1517. {
  1518. handlePtr->handleCustomAppearanceCallback(client_name, key, change);
  1519. }
  1520. static void carla_jack_client_registration_callback(const char* name, int reg, void* arg)
  1521. {
  1522. handlePtr->handleJackClientRegistrationCallback(name, (reg != 0));
  1523. }
  1524. static void carla_jack_port_registration_callback(jack_port_id_t port, int reg, void* arg)
  1525. {
  1526. handlePtr->handleJackPortRegistrationCallback(port, (reg != 0));
  1527. }
  1528. static void carla_jack_port_connect_callback(jack_port_id_t a, jack_port_id_t b, int connect, void* arg)
  1529. {
  1530. handlePtr->handleJackPortConnectCallback(a, b, (connect != 0));
  1531. }
  1532. static int carla_jack_client_rename_callback(const char* oldName, const char* newName, void* arg)
  1533. {
  1534. handlePtr->handleJackClientRenameCallback(oldName, newName);
  1535. return 0;
  1536. }
  1537. static int carla_jack_port_rename_callback(jack_port_id_t port, const char* oldName, const char* newName, void* arg)
  1538. {
  1539. handlePtr->handleJackPortRenameCallback(port, oldName, newName);
  1540. return 0;
  1541. }
  1542. #endif
  1543. static void carla_jack_shutdown_callback(void* arg)
  1544. {
  1545. handlePtr->handleJackShutdownCallback();
  1546. }
  1547. #undef handlePtr
  1548. // -------------------------------------------------------------------
  1549. #ifndef BUILD_BRIDGE
  1550. static int carla_jack_process_callback_plugin(jack_nframes_t nframes, void* arg)
  1551. {
  1552. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1553. if (plugin != nullptr && plugin->isEnabled())
  1554. {
  1555. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1556. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,0);
  1557. if (plugin->tryLock(engine->fFreewheel))
  1558. {
  1559. plugin->initBuffers();
  1560. engine->saveTransportInfo();
  1561. engine->processPlugin(plugin, nframes);
  1562. plugin->unlock();
  1563. }
  1564. }
  1565. return 0;
  1566. }
  1567. static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg)
  1568. {
  1569. CarlaPlugin* const plugin((CarlaPlugin*)arg);
  1570. if (plugin != nullptr && plugin->isEnabled())
  1571. {
  1572. CarlaEngineJack* const engine((CarlaEngineJack*)plugin->getEngine());
  1573. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
  1574. engine->latencyPlugin(plugin, mode);
  1575. }
  1576. }
  1577. #endif
  1578. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJack)
  1579. };
  1580. // -----------------------------------------------------------------------
  1581. CarlaEngine* CarlaEngine::newJack()
  1582. {
  1583. carla_debug("CarlaEngine::newJack()");
  1584. return new CarlaEngineJack();
  1585. }
  1586. // -----------------------------------------------------------------------
  1587. CARLA_BACKEND_END_NAMESPACE