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.

2102 lines
68KB

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