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.

697 lines
24KB

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