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.

2197 lines
73KB

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