Collection of tools useful for audio production
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.

695 lines
24KB

  1. /*
  2. * Carla Backend
  3. * Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * 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 COPYING file
  16. */
  17. #ifdef CARLA_ENGINE_JACK
  18. #include "carla_engine.hpp"
  19. #include "carla_plugin.hpp"
  20. CARLA_BACKEND_START_NAMESPACE
  21. // -----------------------------------------
  22. class CarlaEngineJack : public CarlaEngine
  23. {
  24. public:
  25. CarlaEngineJack()
  26. : CarlaEngine()
  27. #ifndef BUILD_BRIDGE
  28. # ifdef Q_COMPILER_INITIALIZER_LISTS
  29. , rackJackPorts{nullptr}
  30. # endif
  31. #endif
  32. {
  33. qDebug("CarlaEngineJack::CarlaEngineJack()");
  34. type = CarlaEngineTypeJack;
  35. client = nullptr;
  36. state = JackTransportStopped;
  37. freewheel = false;
  38. memset(&pos, 0, sizeof(jack_position_t));
  39. #ifndef BUILD_BRIDGE
  40. # ifndef Q_COMPILER_INITIALIZER_LISTS
  41. for (unsigned short i=0; i < rackPortCount; i++)
  42. rackJackPorts[i] = nullptr;
  43. # endif
  44. #endif
  45. }
  46. ~CarlaEngineJack()
  47. {
  48. qDebug("CarlaEngineJack::~CarlaEngineJack()");
  49. }
  50. // -------------------------------------
  51. bool init(const char* const clientName)
  52. {
  53. qDebug("CarlaEngineJack::init(\"%s\")", clientName);
  54. freewheel = false;
  55. state = JackTransportStopped;
  56. #ifndef BUILD_BRIDGE
  57. client = jackbridge_client_open(clientName, JackNullOption, nullptr);
  58. if (client)
  59. {
  60. sampleRate = jackbridge_get_sample_rate(client);
  61. bufferSize = jackbridge_get_buffer_size(client);
  62. jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
  63. jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
  64. jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
  65. jackbridge_set_process_callback(client, carla_jack_process_callback, this);
  66. jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
  67. jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
  68. if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
  69. {
  70. rackJackPorts[rackPortAudioIn1] = jackbridge_port_register(client, "in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  71. rackJackPorts[rackPortAudioIn2] = jackbridge_port_register(client, "in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  72. rackJackPorts[rackPortAudioOut1] = jackbridge_port_register(client, "out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  73. rackJackPorts[rackPortAudioOut2] = jackbridge_port_register(client, "out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  74. rackJackPorts[rackPortControlIn] = jackbridge_port_register(client, "control-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  75. rackJackPorts[rackPortControlOut] = jackbridge_port_register(client, "control-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
  76. rackJackPorts[rackPortMidiIn] = jackbridge_port_register(client, "midi-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
  77. rackJackPorts[rackPortMidiOut] = jackbridge_port_register(client, "midi-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
  78. }
  79. if (jackbridge_activate(client) == 0)
  80. {
  81. name = getFixedClientName(jackbridge_get_client_name(client));
  82. CarlaEngine::init(name);
  83. return true;
  84. }
  85. else
  86. {
  87. setLastError("Failed to activate the JACK client");
  88. client = nullptr;
  89. }
  90. }
  91. else
  92. setLastError("Failed to create new JACK client");
  93. return false;
  94. #else
  95. name = getFixedClientName(clientName);
  96. CarlaEngine::init(name);
  97. return true;
  98. #endif
  99. }
  100. bool close()
  101. {
  102. qDebug("CarlaEngineJack::close()");
  103. CarlaEngine::close();
  104. if (name)
  105. {
  106. free((void*)name);
  107. name = nullptr;
  108. }
  109. #ifdef BUILD_BRIDGE
  110. client = nullptr;
  111. return true;
  112. #else
  113. if (jackbridge_deactivate(client) == 0)
  114. {
  115. if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
  116. {
  117. jackbridge_port_unregister(client, rackJackPorts[rackPortAudioIn1]);
  118. jackbridge_port_unregister(client, rackJackPorts[rackPortAudioIn2]);
  119. jackbridge_port_unregister(client, rackJackPorts[rackPortAudioOut1]);
  120. jackbridge_port_unregister(client, rackJackPorts[rackPortAudioOut2]);
  121. jackbridge_port_unregister(client, rackJackPorts[rackPortControlIn]);
  122. jackbridge_port_unregister(client, rackJackPorts[rackPortControlOut]);
  123. jackbridge_port_unregister(client, rackJackPorts[rackPortMidiIn]);
  124. jackbridge_port_unregister(client, rackJackPorts[rackPortMidiOut]);
  125. }
  126. if (jackbridge_client_close(client) == 0)
  127. {
  128. client = nullptr;
  129. return true;
  130. }
  131. else
  132. setLastError("Failed to close the JACK client");
  133. }
  134. else
  135. setLastError("Failed to deactivate the JACK client");
  136. client = nullptr;
  137. #endif
  138. return false;
  139. }
  140. bool isOffline()
  141. {
  142. return freewheel;
  143. }
  144. bool isRunning()
  145. {
  146. return bool(client);
  147. }
  148. CarlaEngineClient* addClient(CarlaPlugin* const plugin)
  149. {
  150. CarlaEngineClientNativeHandle handle;
  151. handle.type = CarlaEngineTypeJack;
  152. #ifdef BUILD_BRIDGE
  153. client = handle.jackClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);
  154. sampleRate = jackbridge_get_sample_rate(client);
  155. bufferSize = jackbridge_get_buffer_size(client);
  156. jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
  157. jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
  158. jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
  159. jackbridge_set_process_callback(handle.jackClient, carla_jack_process_callback, this);
  160. jackbridge_set_latency_callback(handle.jackClient, carla_jack_latency_callback, this);
  161. jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
  162. #else
  163. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  164. {
  165. handle.jackClient = client;
  166. }
  167. else if (processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
  168. {
  169. handle.jackClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);
  170. jackbridge_set_process_callback(handle.jackClient, carla_jack_process_callback_plugin, plugin);
  171. jackbridge_set_latency_callback(handle.jackClient, carla_jack_latency_callback_plugin, plugin);
  172. }
  173. #endif
  174. return new CarlaEngineClient(handle);
  175. }
  176. // -------------------------------------
  177. protected:
  178. void handleSampleRateCallback(double newSampleRate)
  179. {
  180. sampleRate = newSampleRate;
  181. }
  182. void handleBufferSizeCallback(uint32_t newBufferSize)
  183. {
  184. #ifndef BUILD_BRIDGE
  185. if (options.processHighPrecision)
  186. return;
  187. #endif
  188. bufferSizeChanged(newBufferSize);
  189. }
  190. void handleFreewheelCallback(bool isFreewheel)
  191. {
  192. freewheel = isFreewheel;
  193. }
  194. void handleProcessCallback(uint32_t nframes)
  195. {
  196. #ifndef BUILD_BRIDGE
  197. if (maxPluginNumber() == 0)
  198. return;
  199. #endif
  200. state = jackbridge_transport_query(client, &pos);
  201. timeInfo.playing = (state != JackTransportStopped);
  202. if (pos.unique_1 == pos.unique_2)
  203. {
  204. timeInfo.frame = pos.frame;
  205. timeInfo.time = pos.usecs;
  206. if (pos.valid & JackPositionBBT)
  207. {
  208. timeInfo.valid = CarlaEngineTimeBBT;
  209. timeInfo.bbt.bar = pos.bar;
  210. timeInfo.bbt.beat = pos.beat;
  211. timeInfo.bbt.tick = pos.tick;
  212. timeInfo.bbt.bar_start_tick = pos.bar_start_tick;
  213. timeInfo.bbt.beats_per_bar = pos.beats_per_bar;
  214. timeInfo.bbt.beat_type = pos.beat_type;
  215. timeInfo.bbt.ticks_per_beat = pos.ticks_per_beat;
  216. timeInfo.bbt.beats_per_minute = pos.beats_per_minute;
  217. }
  218. else
  219. timeInfo.valid = 0;
  220. }
  221. else
  222. {
  223. timeInfo.frame = 0;
  224. timeInfo.valid = 0;
  225. }
  226. #ifndef BUILD_BRIDGE
  227. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  228. {
  229. for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
  230. {
  231. CarlaPlugin* const plugin = getPluginUnchecked(i);
  232. if (! plugin)
  233. continue;
  234. plugin->engineProcessLock();
  235. if (plugin->enabled())
  236. {
  237. plugin->initBuffers();
  238. processPlugin(plugin, nframes);
  239. }
  240. else
  241. processPluginNOT(plugin, nframes);
  242. plugin->engineProcessUnlock();
  243. }
  244. }
  245. else if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
  246. {
  247. // get buffers from jack
  248. float* audioIn1 = (float*)jackbridge_port_get_buffer(rackJackPorts[rackPortAudioIn1], nframes);
  249. float* audioIn2 = (float*)jackbridge_port_get_buffer(rackJackPorts[rackPortAudioIn2], nframes);
  250. float* audioOut1 = (float*)jackbridge_port_get_buffer(rackJackPorts[rackPortAudioOut1], nframes);
  251. float* audioOut2 = (float*)jackbridge_port_get_buffer(rackJackPorts[rackPortAudioOut2], nframes);
  252. void* controlIn = jackbridge_port_get_buffer(rackJackPorts[rackPortControlIn], nframes);
  253. void* controlOut = jackbridge_port_get_buffer(rackJackPorts[rackPortControlOut], nframes);
  254. void* midiIn = jackbridge_port_get_buffer(rackJackPorts[rackPortMidiIn], nframes);
  255. void* midiOut = jackbridge_port_get_buffer(rackJackPorts[rackPortMidiOut], nframes);
  256. // assert buffers
  257. CARLA_ASSERT(audioIn1);
  258. CARLA_ASSERT(audioIn2);
  259. CARLA_ASSERT(audioOut1);
  260. CARLA_ASSERT(audioOut2);
  261. CARLA_ASSERT(controlIn);
  262. CARLA_ASSERT(controlOut);
  263. CARLA_ASSERT(midiIn);
  264. CARLA_ASSERT(midiOut);
  265. // create audio buffers
  266. float* inBuf[2] = { audioIn1, audioIn2 };
  267. float* outBuf[2] = { audioOut1, audioOut2 };
  268. // initialize control input
  269. memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_ENGINE_CONTROL_EVENTS);
  270. {
  271. jackbridge_midi_event_t jackEvent;
  272. const uint32_t jackEventCount = jackbridge_midi_get_event_count(controlIn);
  273. uint32_t carlaEventIndex = 0;
  274. for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; jackEventIndex++)
  275. {
  276. if (jackbridge_midi_event_get(&jackEvent, controlIn, jackEventIndex) != 0)
  277. continue;
  278. CarlaEngineControlEvent* const carlaEvent = &rackControlEventsIn[carlaEventIndex++];
  279. uint8_t midiStatus = jackEvent.buffer[0];
  280. uint8_t midiChannel = midiStatus & 0x0F;
  281. carlaEvent->time = jackEvent.time;
  282. carlaEvent->channel = midiChannel;
  283. if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
  284. {
  285. uint8_t midiControl = jackEvent.buffer[1];
  286. if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
  287. {
  288. uint8_t midiBank = jackEvent.buffer[2];
  289. carlaEvent->type = CarlaEngineEventMidiBankChange;
  290. carlaEvent->value = midiBank;
  291. }
  292. else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
  293. {
  294. carlaEvent->type = CarlaEngineEventAllSoundOff;
  295. }
  296. else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
  297. {
  298. carlaEvent->type = CarlaEngineEventAllNotesOff;
  299. }
  300. else
  301. {
  302. uint8_t midiValue = jackEvent.buffer[2];
  303. carlaEvent->type = CarlaEngineEventControlChange;
  304. carlaEvent->controller = midiControl;
  305. carlaEvent->value = double(midiValue)/127;
  306. }
  307. }
  308. else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
  309. {
  310. uint8_t midiProgram = jackEvent.buffer[1];
  311. carlaEvent->type = CarlaEngineEventMidiProgramChange;
  312. carlaEvent->value = midiProgram;
  313. }
  314. }
  315. }
  316. // initialize midi input
  317. memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*MAX_ENGINE_MIDI_EVENTS);
  318. {
  319. uint32_t i = 0, j = 0;
  320. jackbridge_midi_event_t jackEvent;
  321. while (jackbridge_midi_event_get(&jackEvent, midiIn, j++) == 0)
  322. {
  323. if (i == MAX_ENGINE_MIDI_EVENTS)
  324. break;
  325. if (jackEvent.size < 4)
  326. {
  327. rackMidiEventsIn[i].time = jackEvent.time;
  328. rackMidiEventsIn[i].size = jackEvent.size;
  329. memcpy(rackMidiEventsIn[i].data, jackEvent.buffer, jackEvent.size);
  330. i += 1;
  331. }
  332. }
  333. }
  334. // process rack
  335. processRack(inBuf, outBuf, nframes);
  336. // output control
  337. {
  338. jackbridge_midi_clear_buffer(controlOut);
  339. for (unsigned short i=0; i < MAX_ENGINE_CONTROL_EVENTS; i++)
  340. {
  341. CarlaEngineControlEvent* const event = &rackControlEventsOut[i];
  342. if (event->type == CarlaEngineEventControlChange && MIDI_IS_CONTROL_BANK_SELECT(event->controller))
  343. event->type = CarlaEngineEventMidiBankChange;
  344. uint8_t data[4] = { 0 };
  345. switch (event->type)
  346. {
  347. case CarlaEngineEventNull:
  348. break;
  349. case CarlaEngineEventControlChange:
  350. data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
  351. data[1] = event->controller;
  352. data[2] = event->value * 127;
  353. jackbridge_midi_event_write(controlOut, event->time, data, 3);
  354. break;
  355. case CarlaEngineEventMidiBankChange:
  356. data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
  357. data[1] = MIDI_CONTROL_BANK_SELECT;
  358. data[2] = event->value;
  359. jackbridge_midi_event_write(controlOut, event->time, data, 3);
  360. break;
  361. case CarlaEngineEventMidiProgramChange:
  362. data[0] = MIDI_STATUS_PROGRAM_CHANGE + event->channel;
  363. data[1] = event->value;
  364. jackbridge_midi_event_write(controlOut, event->time, data, 2);
  365. break;
  366. case CarlaEngineEventAllSoundOff:
  367. data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
  368. data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  369. jackbridge_midi_event_write(controlOut, event->time, data, 2);
  370. break;
  371. case CarlaEngineEventAllNotesOff:
  372. data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
  373. data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  374. jackbridge_midi_event_write(controlOut, event->time, data, 2);
  375. break;
  376. }
  377. }
  378. }
  379. // output midi
  380. {
  381. jackbridge_midi_clear_buffer(midiOut);
  382. for (unsigned short i=0; i < MAX_ENGINE_MIDI_EVENTS; i++)
  383. {
  384. if (rackMidiEventsOut[i].size == 0)
  385. break;
  386. jackbridge_midi_event_write(midiOut, rackMidiEventsOut[i].time, rackMidiEventsOut[i].data, rackMidiEventsOut[i].size);
  387. }
  388. }
  389. }
  390. #else
  391. CarlaPlugin* const plugin = getPluginUnchecked(0);
  392. if (! plugin)
  393. return;
  394. plugin->engineProcessLock();
  395. if (plugin->enabled())
  396. {
  397. plugin->initBuffers();
  398. processPlugin(plugin, nframes);
  399. }
  400. else
  401. processPluginNOT(plugin, nframes);
  402. plugin->engineProcessUnlock();
  403. #endif
  404. }
  405. void handleLatencyCallback(jack_latency_callback_mode_t mode)
  406. {
  407. #ifndef BUILD_BRIDGE
  408. if (processMode != PROCESS_MODE_SINGLE_CLIENT)
  409. return;
  410. #endif
  411. for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
  412. {
  413. CarlaPlugin* const plugin = getPluginUnchecked(i);
  414. if (plugin && plugin->enabled())
  415. latencyPlugin(plugin, mode);
  416. }
  417. }
  418. void handleShutdownCallback()
  419. {
  420. for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
  421. {
  422. CarlaPlugin* const plugin = getPluginUnchecked(i);
  423. if (plugin)
  424. plugin->x_client = nullptr;
  425. }
  426. client = nullptr;
  427. callback(CALLBACK_QUIT, 0, 0, 0, 0.0);
  428. }
  429. // -------------------------------------
  430. private:
  431. jack_client_t* client;
  432. jack_transport_state_t state;
  433. jack_position_t pos;
  434. bool freewheel;
  435. // -------------------------------------
  436. #ifndef BUILD_BRIDGE
  437. enum RackPorts {
  438. rackPortAudioIn1 = 0,
  439. rackPortAudioIn2 = 1,
  440. rackPortAudioOut1 = 2,
  441. rackPortAudioOut2 = 3,
  442. rackPortControlIn = 4,
  443. rackPortControlOut = 5,
  444. rackPortMidiIn = 6,
  445. rackPortMidiOut = 7,
  446. rackPortCount = 8
  447. };
  448. jack_port_t* rackJackPorts[rackPortCount];
  449. #endif
  450. static void processPlugin(CarlaPlugin* const p, const uint32_t nframes)
  451. {
  452. float* inBuffer[p->aIn.count];
  453. float* outBuffer[p->aOut.count];
  454. for (uint32_t i=0; i < p->aIn.count; i++)
  455. inBuffer[i] = p->aIn.ports[i]->getJackAudioBuffer(nframes);
  456. for (uint32_t i=0; i < p->aOut.count; i++)
  457. outBuffer[i] = p->aOut.ports[i]->getJackAudioBuffer(nframes);
  458. #ifndef BUILD_BRIDGE
  459. if (/*options.processHighPrecision*/ 0)
  460. {
  461. float* inBuffer2[p->aIn.count];
  462. float* outBuffer2[p->aOut.count];
  463. for (uint32_t i=0, j; i < nframes; i += 8)
  464. {
  465. for (j=0; j < p->aIn.count; j++)
  466. inBuffer2[j] = inBuffer[j] + i;
  467. for (j=0; j < p->aOut.count; j++)
  468. outBuffer2[j] = outBuffer[j] + i;
  469. p->process(inBuffer2, outBuffer2, 8, i);
  470. }
  471. }
  472. else
  473. #endif
  474. p->process(inBuffer, outBuffer, nframes);
  475. }
  476. static void processPluginNOT(CarlaPlugin* const p, const uint32_t nframes)
  477. {
  478. for (uint32_t i=0; i < p->aIn.count; i++)
  479. carla_zeroF(p->aIn.ports[i]->getJackAudioBuffer(nframes), nframes);
  480. for (uint32_t i=0; i < p->aOut.count; i++)
  481. carla_zeroF(p->aOut.ports[i]->getJackAudioBuffer(nframes), nframes);
  482. }
  483. static void latencyPlugin(CarlaPlugin* const p, jack_latency_callback_mode_t mode)
  484. {
  485. jack_latency_range_t range;
  486. uint32_t pluginLatency = p->x_client->getLatency();
  487. if (pluginLatency == 0)
  488. return;
  489. if (mode == JackCaptureLatency)
  490. {
  491. for (uint32_t i=0; i < p->aIn.count; i++)
  492. {
  493. uint aOutI = (i >= p->aOut.count) ? p->aOut.count : i;
  494. jack_port_t* const portIn = p->aIn.ports[i]->getHandle().jackPort;
  495. jack_port_t* const portOut = p->aOut.ports[aOutI]->getHandle().jackPort;
  496. jackbridge_port_get_latency_range(portIn, mode, &range);
  497. range.min += pluginLatency;
  498. range.max += pluginLatency;
  499. jackbridge_port_set_latency_range(portOut, mode, &range);
  500. }
  501. }
  502. else
  503. {
  504. for (uint32_t i=0; i < p->aOut.count; i++)
  505. {
  506. uint aInI = (i >= p->aIn.count) ? p->aIn.count : i;
  507. jack_port_t* const portIn = p->aIn.ports[aInI]->getHandle().jackPort;
  508. jack_port_t* const portOut = p->aOut.ports[i]->getHandle().jackPort;
  509. jackbridge_port_get_latency_range(portOut, mode, &range);
  510. range.min += pluginLatency;
  511. range.max += pluginLatency;
  512. jackbridge_port_set_latency_range(portIn, mode, &range);
  513. }
  514. }
  515. }
  516. static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg)
  517. {
  518. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  519. _this_->handleSampleRateCallback(newSampleRate);
  520. return 0;
  521. }
  522. static int carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg)
  523. {
  524. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  525. _this_->handleBufferSizeCallback(newBufferSize);
  526. return 0;
  527. }
  528. static void carla_jack_freewheel_callback(int starting, void* arg)
  529. {
  530. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  531. _this_->handleFreewheelCallback(bool(starting));
  532. }
  533. static int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
  534. {
  535. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  536. _this_->handleProcessCallback(nframes);
  537. return 0;
  538. }
  539. static int carla_jack_process_callback_plugin(jack_nframes_t nframes, void* arg)
  540. {
  541. CarlaPlugin* const plugin = (CarlaPlugin*)arg;
  542. if (! plugin)
  543. return 0;
  544. plugin->engineProcessLock();
  545. if (plugin->enabled())
  546. {
  547. plugin->initBuffers();
  548. processPlugin(plugin, nframes);
  549. }
  550. else
  551. processPluginNOT(plugin, nframes);
  552. plugin->engineProcessUnlock();
  553. return 0;
  554. }
  555. static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
  556. {
  557. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  558. _this_->handleLatencyCallback(mode);
  559. }
  560. static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg)
  561. {
  562. CarlaPlugin* const plugin = (CarlaPlugin*)arg;
  563. if (plugin && plugin->enabled())
  564. latencyPlugin(plugin, mode);
  565. }
  566. static void carla_jack_shutdown_callback(void* arg)
  567. {
  568. CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
  569. _this_->handleShutdownCallback();
  570. }
  571. };
  572. // -----------------------------------------
  573. CarlaEngine* CarlaEngine::newJack()
  574. {
  575. return new CarlaEngineJack();
  576. }
  577. // -----------------------------------------
  578. CARLA_BACKEND_END_NAMESPACE
  579. #endif // CARLA_ENGINE_JACK