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.

CarlaJackPlugin.cpp 29KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. /*
  2. * Carla Jack Plugin
  3. * Copyright (C) 2014 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 "CarlaEngine.hpp"
  18. #include "CarlaHost.h"
  19. #include "CarlaBackendUtils.hpp"
  20. #include "CarlaThread.hpp"
  21. #include "../CarlaBridgeClient.hpp"
  22. #include "../backend/plugin/CarlaPluginInternal.hpp"
  23. #include "CarlaMathUtils.hpp"
  24. #include "jackbridge/JackBridge.hpp"
  25. // -------------------------------------------------------------------------------------------------------------------
  26. struct _jack_client {
  27. bool isActive;
  28. JackShutdownCallback shutdown_cb;
  29. void* shutdown_ptr;
  30. JackProcessCallback process_cb;
  31. void* process_ptr;
  32. _jack_client()
  33. {
  34. clear();
  35. }
  36. void clear()
  37. {
  38. isActive = false;
  39. shutdown_cb = nullptr;
  40. shutdown_ptr = nullptr;
  41. process_cb = nullptr;
  42. process_ptr = nullptr;
  43. }
  44. };
  45. static jack_client_t gJackClient;
  46. // -------------------------------------------------------------------------------------------------------------------
  47. struct _jack_port {
  48. bool used;
  49. char name[128+1];
  50. void* buffer;
  51. _jack_port()
  52. : used(false),
  53. buffer(nullptr) {}
  54. };
  55. // system ports
  56. static jack_port_t gPortSystemIn1; // 0
  57. static jack_port_t gPortSystemIn2; // 1
  58. static jack_port_t gPortSystemOut1; // 2
  59. static jack_port_t gPortSystemOut2; // 3
  60. // client ports
  61. static jack_port_t gPortAudioIn1; // 4
  62. static jack_port_t gPortAudioIn2; // 5
  63. static jack_port_t gPortAudioOut1; // 6
  64. static jack_port_t gPortAudioOut2; // 7
  65. static jack_port_t gPortMidiIn; // 8
  66. static jack_port_t gPortMidiOut; // 9
  67. // -------------------------------------------------------------------------------------------------------------------
  68. CARLA_BRIDGE_START_NAMESPACE
  69. class JackBridgeClient : public CarlaBridgeClient,
  70. CarlaThread
  71. {
  72. public:
  73. JackBridgeClient()
  74. : CarlaBridgeClient(nullptr),
  75. fEngine(nullptr)
  76. {
  77. carla_debug("JackBridgeClient::JackBridgeClient()");
  78. carla_set_engine_callback(callback, this);
  79. const char* const shmIds(std::getenv("ENGINE_BRIDGE_SHM_IDS"));
  80. CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr,);
  81. CARLA_SAFE_ASSERT_RETURN(std::strlen(shmIds) == 6*2,);
  82. char bridgeBaseAudioName[6+1];
  83. char bridgeBaseControlName[6+1];
  84. std::strncpy(bridgeBaseAudioName, shmIds, 6);
  85. std::strncpy(bridgeBaseControlName, shmIds+6, 6);
  86. bridgeBaseAudioName[6] = '\0';
  87. bridgeBaseControlName[6] = '\0';
  88. const char* const clientName(std::getenv("ENGINE_BRIDGE_CLIENT_NAME"));
  89. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr,);
  90. const char* const oscUrl(std::getenv("ENGINE_BRIDGE_OSC_URL"));
  91. CARLA_SAFE_ASSERT_RETURN(oscUrl != nullptr,);
  92. if (! carla_engine_init_bridge(bridgeBaseAudioName, bridgeBaseControlName, clientName))
  93. return;
  94. fEngine = carla_get_engine();
  95. CARLA_SAFE_ASSERT_RETURN(fEngine != nullptr,);
  96. CarlaBridgeClient::oscInit(oscUrl);
  97. fEngine->setOscBridgeData(&fOscData);
  98. carla_add_plugin(CarlaBackend::BINARY_NATIVE, CarlaBackend::PLUGIN_JACK, "bridge", clientName, clientName, nullptr);
  99. sendOscUpdate();
  100. sendOscBridgeUpdate();
  101. }
  102. ~JackBridgeClient() override
  103. {
  104. carla_debug("JackBridgeClient::~JackBridgeClient()");
  105. oscClose();
  106. carla_engine_close();
  107. }
  108. bool isOk() const noexcept
  109. {
  110. return (fEngine != nullptr);
  111. }
  112. protected:
  113. void handleCallback(const CarlaBackend::EngineCallbackOpcode /*action*/, const uint /*pluginId*/, const int /*value1*/, const int /*value2*/, const float /*value3*/, const char* const /*valueStr*/)
  114. {
  115. CARLA_BACKEND_USE_NAMESPACE;
  116. }
  117. void run()
  118. {
  119. for (; carla_is_engine_running();)
  120. {
  121. carla_engine_idle();
  122. CarlaBridgeClient::oscIdle();
  123. carla_msleep(30);
  124. }
  125. }
  126. private:
  127. const CarlaBackend::CarlaEngine* fEngine;
  128. static void callback(void* ptr, CarlaBackend::EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr)
  129. {
  130. carla_debug("CarlaPluginClient::callback(%p, %i:%s, %i, %i, %i, %f, \"%s\")", ptr, action, CarlaBackend::EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
  131. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
  132. return ((JackBridgeClient*)ptr)->handleCallback(action, pluginId, value1, value2, value3, valueStr);
  133. }
  134. };
  135. // -------------------------------------------------------------------------
  136. int CarlaBridgeOsc::handleMsgShow()
  137. {
  138. carla_debug("CarlaBridgeOsc::handleMsgShow()");
  139. return 0;
  140. }
  141. int CarlaBridgeOsc::handleMsgHide()
  142. {
  143. carla_debug("CarlaBridgeOsc::handleMsgHide()");
  144. return 0;
  145. }
  146. int CarlaBridgeOsc::handleMsgQuit()
  147. {
  148. carla_debug("CarlaBridgeOsc::handleMsgQuit()");
  149. if (gJackClient.shutdown_cb != nullptr)
  150. gJackClient.shutdown_cb(gJackClient.shutdown_ptr);
  151. carla_engine_close();
  152. std::exit(0);
  153. return 0;
  154. }
  155. CARLA_BRIDGE_END_NAMESPACE
  156. // -------------------------------------------------------------------------------------------------------------------
  157. CARLA_EXPORT jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...);
  158. CARLA_EXPORT int jack_client_close(jack_client_t* client);
  159. CARLA_EXPORT int jack_client_name_size();
  160. CARLA_EXPORT char* jack_get_client_name(jack_client_t* client);
  161. CARLA_EXPORT int jack_activate(jack_client_t* client);
  162. CARLA_EXPORT int jack_deactivate(jack_client_t* client);
  163. CARLA_EXPORT int jack_is_realtime(jack_client_t* client);
  164. CARLA_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* client);
  165. CARLA_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* client);
  166. CARLA_EXPORT jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size);
  167. CARLA_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames);
  168. CARLA_EXPORT const char* jack_port_name(const jack_port_t* port);
  169. CARLA_EXPORT const char** jack_get_ports(jack_client_t*, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags);
  170. CARLA_EXPORT jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name);
  171. CARLA_EXPORT jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id);
  172. CARLA_EXPORT int jack_connect(jack_client_t* client, const char* source_port, const char* destination_port);
  173. CARLA_EXPORT int jack_disconnect(jack_client_t* client, const char* source_port, const char* destination_port);
  174. CARLA_EXPORT void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg);
  175. CARLA_EXPORT int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg);
  176. CARLA_EXPORT void jack_set_info_function(void (*func)(const char*));
  177. CARLA_EXPORT void jack_set_error_function(void (*func)(const char*));
  178. CARLA_EXPORT void jack_free(void* ptr);
  179. // -------------------------------------------------------------------------------------------------------------------
  180. typedef void (*jack_error_callback)(const char* msg);
  181. typedef void (*jack_info_callback)(const char* msg);
  182. jack_error_callback sErrorCallback = nullptr;
  183. jack_info_callback sInfoCallback = nullptr;
  184. // -------------------------------------------------------------------------------------------------------------------
  185. jack_client_t* jack_client_open(const char* client_name, jack_options_t /*options*/, jack_status_t* status, ...)
  186. {
  187. carla_stderr2("JACKBRIDGE CLIENT OPEN HERE");
  188. if (carla_is_engine_running())
  189. {
  190. if (status != nullptr)
  191. *status = JackServerStarted;
  192. return nullptr;
  193. }
  194. static CarlaBridge::JackBridgeClient bridge;
  195. if (! bridge.isOk())
  196. {
  197. if (status != nullptr)
  198. *status = JackServerFailed;
  199. return nullptr;
  200. }
  201. if (! gPortSystemIn1.used)
  202. {
  203. gPortSystemIn1.used = true;
  204. gPortSystemIn2.used = true;
  205. gPortSystemOut1.used = true;
  206. gPortSystemOut2.used = true;
  207. std::strcpy(gPortSystemIn1.name, "system:capture_1");
  208. std::strcpy(gPortSystemIn2.name, "system:capture_2");
  209. std::strcpy(gPortSystemOut1.name, "system:playback_1");
  210. std::strcpy(gPortSystemOut2.name, "system:playback_2");
  211. }
  212. return &gJackClient;
  213. }
  214. int jack_client_close(jack_client_t* client)
  215. {
  216. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  217. carla_stderr2("JACKBRIDGE CLIENT CLOSE HERE");
  218. if (! carla_is_engine_running())
  219. return -1;
  220. carla_engine_close();
  221. gJackClient.clear();
  222. gPortAudioIn1.used = 0;
  223. gPortAudioIn2.used = 0;
  224. gPortAudioOut1.used = 0;
  225. gPortAudioOut2.used = 0;
  226. gPortMidiIn.used = 0;
  227. gPortMidiOut.used = 0;
  228. return 0;
  229. }
  230. // -------------------------------------------------------------------------------------------------------------------
  231. int jack_client_name_size()
  232. {
  233. return 32+1; // same as JACK1
  234. }
  235. char* jack_get_client_name(jack_client_t* client)
  236. {
  237. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  238. if (const CarlaEngine* const engine = carla_get_engine())
  239. return const_cast<char*>(engine->getName());
  240. return nullptr;
  241. }
  242. // -------------------------------------------------------------------------------------------------------------------
  243. int jack_activate(jack_client_t* client)
  244. {
  245. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  246. gJackClient.isActive = true;
  247. return 0;
  248. }
  249. int jack_deactivate(jack_client_t* client)
  250. {
  251. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  252. gJackClient.isActive = false;
  253. return 0;
  254. }
  255. int jack_is_realtime(jack_client_t* client)
  256. {
  257. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  258. return 1;
  259. }
  260. // -------------------------------------------------------------------------------------------------------------------
  261. jack_nframes_t jack_get_sample_rate(jack_client_t* client)
  262. {
  263. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  264. return static_cast<uint32_t>(carla_get_sample_rate());
  265. }
  266. jack_nframes_t jack_get_buffer_size(jack_client_t* client)
  267. {
  268. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  269. return carla_get_buffer_size();
  270. }
  271. // -------------------------------------------------------------------------------------------------------------------
  272. jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long)
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  275. if (std::strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) == 0)
  276. {
  277. if (flags & JackPortIsInput)
  278. {
  279. if (gPortAudioIn1.used && gPortAudioIn2.used)
  280. return nullptr;
  281. if (! gPortAudioIn1.used)
  282. {
  283. std::strncpy(gPortAudioIn1.name, port_name, 128);
  284. return &gPortAudioIn1;
  285. }
  286. else
  287. {
  288. std::strncpy(gPortAudioIn2.name, port_name, 128);
  289. return &gPortAudioIn2;
  290. }
  291. }
  292. else
  293. {
  294. if (gPortAudioOut1.used && gPortAudioOut2.used)
  295. return nullptr;
  296. if (! gPortAudioOut1.used)
  297. {
  298. std::strncpy(gPortAudioOut1.name, port_name, 128);
  299. return &gPortAudioOut1;
  300. }
  301. else
  302. {
  303. std::strncpy(gPortAudioOut2.name, port_name, 128);
  304. return &gPortAudioOut2;
  305. }
  306. }
  307. }
  308. if (std::strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0)
  309. {
  310. if (flags & JackPortIsInput)
  311. {
  312. if (gPortMidiIn.used)
  313. return nullptr;
  314. std::strncpy(gPortMidiIn.name, port_name, 128);
  315. return &gPortMidiIn;
  316. }
  317. else
  318. {
  319. if (gPortMidiOut.used)
  320. return nullptr;
  321. std::strncpy(gPortMidiOut.name, port_name, 128);
  322. return &gPortMidiOut;
  323. }
  324. }
  325. return nullptr;
  326. }
  327. void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
  328. {
  329. return port->buffer;
  330. }
  331. // -------------------------------------------------------------------------------------------------------------------
  332. const char* jack_port_name(const jack_port_t* port)
  333. {
  334. return port->name;
  335. }
  336. // -------------------------------------------------------------------------------------------------------------------
  337. const char** jack_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  338. {
  339. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  340. if (port_name_pattern != nullptr)
  341. {
  342. if (std::strstr("system:playback_", port_name_pattern) == nullptr)
  343. return nullptr;
  344. if (std::strstr("system:capture_", port_name_pattern) == nullptr)
  345. return nullptr;
  346. }
  347. if (type_name_pattern != nullptr)
  348. {
  349. if (std::strstr(JACK_DEFAULT_AUDIO_TYPE, type_name_pattern) == nullptr)
  350. return nullptr;
  351. }
  352. uint numPorts = 0;
  353. if (flags == 0)
  354. {
  355. numPorts = 4;
  356. }
  357. else
  358. {
  359. if (flags & JackPortIsInput)
  360. numPorts += 2;
  361. if (flags & JackPortIsOutput)
  362. numPorts += 2;
  363. }
  364. if (numPorts == 0)
  365. return nullptr;
  366. const char** const ports = new const char*[numPorts+1];
  367. uint i = 0;
  368. if (flags == 0 || (flags & JackPortIsInput) != 0)
  369. {
  370. ports[i++] = gPortSystemIn1.name;
  371. ports[i++] = gPortSystemIn1.name;
  372. }
  373. if (flags == 0 || (flags & JackPortIsOutput) != 0)
  374. {
  375. ports[i++] = gPortSystemOut1.name;
  376. ports[i++] = gPortSystemOut1.name;
  377. }
  378. ports[i++] = nullptr;
  379. return ports;
  380. }
  381. jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name)
  382. {
  383. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  384. CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
  385. if (std::strcmp(port_name, gPortSystemIn1.name) == 0)
  386. return &gPortSystemIn1;
  387. if (std::strcmp(port_name, gPortSystemIn2.name) == 0)
  388. return &gPortSystemIn2;
  389. if (std::strcmp(port_name, gPortSystemOut1.name) == 0)
  390. return &gPortSystemOut1;
  391. if (std::strcmp(port_name, gPortSystemOut2.name) == 0)
  392. return &gPortSystemOut2;
  393. if (gPortAudioIn1.used && std::strcmp(port_name, gPortAudioIn1.name) == 0)
  394. return &gPortAudioIn1;
  395. if (gPortAudioIn2.used && std::strcmp(port_name, gPortAudioIn2.name) == 0)
  396. return &gPortAudioIn2;
  397. if (gPortAudioOut1.used && std::strcmp(port_name, gPortAudioOut1.name) == 0)
  398. return &gPortAudioOut1;
  399. if (gPortAudioOut2.used && std::strcmp(port_name, gPortAudioOut2.name) == 0)
  400. return &gPortAudioOut2;
  401. if (gPortMidiIn.used && std::strcmp(port_name, gPortMidiIn.name) == 0)
  402. return &gPortMidiIn;
  403. if (gPortMidiOut.used && std::strcmp(port_name, gPortMidiOut.name) == 0)
  404. return &gPortMidiOut;
  405. return nullptr;
  406. }
  407. jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id)
  408. {
  409. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  410. CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
  411. switch (port_id)
  412. {
  413. case 0:
  414. return &gPortSystemIn1;
  415. case 1:
  416. return &gPortSystemIn2;
  417. case 2:
  418. return &gPortSystemOut1;
  419. case 3:
  420. return &gPortSystemOut2;
  421. case 4:
  422. if (gPortAudioIn1.used)
  423. return &gPortAudioIn1;
  424. break;
  425. case 5:
  426. if (gPortAudioIn2.used)
  427. return &gPortAudioIn2;
  428. break;
  429. case 6:
  430. if (gPortAudioOut1.used)
  431. return &gPortAudioOut1;
  432. break;
  433. case 7:
  434. if (gPortAudioOut2.used)
  435. return &gPortAudioOut2;
  436. break;
  437. case 8:
  438. if (gPortMidiIn.used)
  439. return &gPortMidiIn;
  440. break;
  441. case 9:
  442. if (gPortMidiOut.used)
  443. return &gPortMidiOut;
  444. break;
  445. }
  446. return nullptr;
  447. }
  448. // -------------------------------------------------------------------------------------------------------------------
  449. int jack_connect(jack_client_t* client, const char*, const char*)
  450. {
  451. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  452. return 0;
  453. }
  454. int jack_disconnect(jack_client_t* client, const char*, const char*)
  455. {
  456. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  457. return 0;
  458. }
  459. // -------------------------------------------------------------------------------------------------------------------
  460. void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg)
  461. {
  462. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient,);
  463. gJackClient.shutdown_cb = function;
  464. gJackClient.shutdown_ptr = arg;
  465. }
  466. int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
  467. {
  468. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  469. gJackClient.process_cb = process_callback;
  470. gJackClient.process_ptr = arg;
  471. return 0;
  472. }
  473. // -------------------------------------------------------------------------------------------------------------------
  474. void jack_set_error_function(void (*func)(const char*))
  475. {
  476. sErrorCallback = func;
  477. }
  478. void jack_set_info_function(void (*func)(const char*))
  479. {
  480. sInfoCallback = func;
  481. }
  482. void jack_free(void* ptr)
  483. {
  484. delete[] (char**)ptr;
  485. }
  486. // -------------------------------------------------------------------------------------------------------------------
  487. CARLA_EXPORT void carla_register_all_plugins();
  488. void carla_register_all_plugins() {}
  489. // -------------------------------------------------------------------------------------------------------------------
  490. CARLA_BACKEND_START_NAMESPACE
  491. class JackPlugin : public CarlaPlugin
  492. {
  493. public:
  494. JackPlugin(CarlaEngine* const engine, const uint id)
  495. : CarlaPlugin(engine, id)
  496. {
  497. carla_debug("JackPlugin::JackPlugin(%p, %i)", engine, id);
  498. }
  499. ~JackPlugin() override
  500. {
  501. carla_debug("JackPlugin::~JackPlugin()");
  502. pData->singleMutex.lock();
  503. pData->masterMutex.lock();
  504. if (pData->client != nullptr && pData->client->isActive())
  505. pData->client->deactivate();
  506. if (pData->active)
  507. {
  508. deactivate();
  509. pData->active = false;
  510. }
  511. clearBuffers();
  512. }
  513. void clearBuffers() override
  514. {
  515. pData->audioIn.count = 0;
  516. pData->audioOut.count = 0;
  517. }
  518. // -------------------------------------------------------------------
  519. // Information (base)
  520. PluginType getType() const noexcept override
  521. {
  522. return PLUGIN_JACK;
  523. }
  524. PluginCategory getCategory() const noexcept override
  525. {
  526. return PLUGIN_CATEGORY_NONE;
  527. }
  528. void getLabel(char* const strBuf) const noexcept override
  529. {
  530. std::strncpy(strBuf, "zita-rev1", STR_MAX);
  531. }
  532. void getRealName(char* const strBuf) const noexcept override
  533. {
  534. std::strncpy(strBuf, "zita-rev1", STR_MAX);
  535. }
  536. // -------------------------------------------------------------------
  537. // Information (count)
  538. // nothing
  539. // -------------------------------------------------------------------
  540. // Information (current data)
  541. // nothing
  542. // -------------------------------------------------------------------
  543. // Information (per-plugin data)
  544. unsigned int getOptionsAvailable() const noexcept override
  545. {
  546. unsigned int options = 0x0;
  547. //options |= PLUGIN_OPTION_FIXED_BUFFERS;
  548. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  549. //options |= PLUGIN_OPTION_USE_CHUNKS;
  550. {
  551. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  552. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  553. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  554. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  555. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  556. }
  557. return options;
  558. }
  559. // -------------------------------------------------------------------
  560. // Set data (state)
  561. // nothing
  562. // -------------------------------------------------------------------
  563. // Set data (internal stuff)
  564. // -------------------------------------------------------------------
  565. // Set data (plugin-specific stuff)
  566. // -------------------------------------------------------------------
  567. // Set ui stuff
  568. // -------------------------------------------------------------------
  569. // Plugin state
  570. void reload() override
  571. {
  572. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  573. carla_stderr2("JackPlugin::reload() - start");
  574. //const EngineProcessMode processMode(pData->engine->getProccessMode());
  575. // Safely disable plugin for reload
  576. const ScopedDisabler sd(this);
  577. if (pData->active)
  578. deactivate();
  579. clearBuffers();
  580. pData->audioIn.count = 2;
  581. pData->audioOut.count = 2;
  582. bufferSizeChanged(pData->engine->getBufferSize());
  583. //reloadPrograms(true);
  584. if (pData->active)
  585. activate();
  586. carla_stderr2("JackPlugin::reload() - end");
  587. }
  588. // -------------------------------------------------------------------
  589. // Plugin processing
  590. void activate() noexcept override
  591. {
  592. }
  593. void deactivate() noexcept override
  594. {
  595. }
  596. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  597. {
  598. carla_stderr2("JackPlugin::process");
  599. // --------------------------------------------------------------------------------------------------------
  600. // Check if active
  601. if (! (gJackClient.isActive && pData->active))
  602. {
  603. // disable any output sound
  604. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  605. FLOAT_CLEAR(outBuffer[i], static_cast<int>(frames));
  606. carla_stderr2("JackPlugin::process disabled");
  607. return;
  608. }
  609. carla_stderr2("JackPlugin::working");
  610. // --------------------------------------------------------------------------------------------------------
  611. // Check if needs reset
  612. if (pData->needsReset)
  613. {
  614. pData->needsReset = false;
  615. }
  616. processSingle(inBuffer, outBuffer, frames);
  617. }
  618. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  619. {
  620. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  621. if (pData->audioIn.count > 0)
  622. {
  623. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  624. }
  625. if (pData->audioOut.count > 0)
  626. {
  627. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  628. }
  629. // --------------------------------------------------------------------------------------------------------
  630. // Try lock, silence otherwise
  631. if (pData->engine->isOffline())
  632. {
  633. pData->singleMutex.lock();
  634. }
  635. else if (! pData->singleMutex.tryLock())
  636. {
  637. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  638. FLOAT_CLEAR(outBuffer[i], frames);
  639. return false;
  640. }
  641. // --------------------------------------------------------------------------------------------------------
  642. // Set audio in buffers
  643. if (pData->audioIn.count == 2)
  644. {
  645. gPortAudioIn1.buffer = inBuffer[0];
  646. gPortAudioIn2.buffer = inBuffer[1];
  647. }
  648. else if (pData->audioIn.count == 1)
  649. {
  650. gPortAudioIn1.buffer = inBuffer[0];
  651. }
  652. if (pData->audioOut.count == 2)
  653. {
  654. gPortAudioOut1.buffer = outBuffer[0];
  655. gPortAudioOut2.buffer = outBuffer[1];
  656. }
  657. else if (pData->audioOut.count == 1)
  658. {
  659. gPortAudioOut1.buffer = outBuffer[0];
  660. }
  661. // --------------------------------------------------------------------------------------------------------
  662. // Run plugin
  663. //if (gJackClient.process_cb != nullptr)
  664. // gJackClient.process_cb(frames, gJackClient.process_ptr);
  665. // --------------------------------------------------------------------------------------------------------
  666. // Set audio out buffers
  667. //for (uint32_t i=0; i < pData->audioOut.count; ++i)
  668. // FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getSampleData(static_cast<int>(i)), static_cast<int>(frames));
  669. // --------------------------------------------------------------------------------------------------------
  670. pData->singleMutex.unlock();
  671. return true;
  672. }
  673. void bufferSizeChanged(const uint32_t newBufferSize) override
  674. {
  675. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  676. carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
  677. }
  678. void sampleRateChanged(const double newSampleRate) override
  679. {
  680. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  681. carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
  682. }
  683. // -------------------------------------------------------------------
  684. // Plugin buffers
  685. // nothing
  686. // -------------------------------------------------------------------
  687. // Post-poned UI Stuff
  688. // nothing
  689. // -------------------------------------------------------------------
  690. protected:
  691. // TODO
  692. // -------------------------------------------------------------------
  693. public:
  694. bool init(const char* const filename, const char* const name, const char* const label)
  695. {
  696. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  697. // ---------------------------------------------------------------
  698. // first checks
  699. if (pData->client != nullptr)
  700. {
  701. pData->engine->setLastError("Plugin client is already registered");
  702. return false;
  703. }
  704. if (filename == nullptr || filename[0] == '\0')
  705. {
  706. pData->engine->setLastError("null filename");
  707. return false;
  708. }
  709. if (label == nullptr || label[0] == '\0')
  710. {
  711. pData->engine->setLastError("null label");
  712. return false;
  713. }
  714. // ---------------------------------------------------------------
  715. // get info
  716. if (name != nullptr && name[0] != '\0')
  717. pData->name = pData->engine->getUniquePluginName(name);
  718. else
  719. pData->name = pData->engine->getUniquePluginName("test");
  720. pData->filename = carla_strdup(filename);
  721. // ---------------------------------------------------------------
  722. // register client
  723. pData->client = pData->engine->addClient(this);
  724. if (pData->client == nullptr || ! pData->client->isOk())
  725. {
  726. pData->engine->setLastError("Failed to register plugin client");
  727. return false;
  728. }
  729. // ---------------------------------------------------------------
  730. // load plugin settings
  731. {
  732. // set default options
  733. pData->options = 0x0;
  734. //pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  735. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  736. //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  737. //if (fInstance->acceptsMidi())
  738. {
  739. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  740. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  741. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  742. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  743. }
  744. // set identifier string
  745. CarlaString identifier("JACK/");
  746. //identifier += juceId.toRawUTF8();
  747. pData->identifier = identifier.dup();
  748. // load settings
  749. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  750. }
  751. return true;
  752. }
  753. private:
  754. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JackPlugin)
  755. };
  756. CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init)
  757. {
  758. carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label);
  759. JackPlugin* const plugin(new JackPlugin(init.engine, init.id));
  760. if (! plugin->init(init.filename, init.name, init.label))
  761. {
  762. delete plugin;
  763. return nullptr;
  764. }
  765. plugin->reload();
  766. // if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  767. // {
  768. // init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!");
  769. // delete plugin;
  770. // return nullptr;
  771. // }
  772. return plugin;
  773. }
  774. CARLA_BACKEND_END_NAMESPACE
  775. // -------------------------------------------------------------------------------------------------------------------