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.

1996 lines
65KB

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