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.

2251 lines
75KB

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