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

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  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, ulong flags, ulong 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, ulong 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, ulong flags, ulong)
  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, ulong 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) noexcept
  495. : CarlaPlugin(engine, id)
  496. {
  497. carla_debug("JackPlugin::JackPlugin(%p, %i)", engine, id);
  498. }
  499. ~JackPlugin() noexcept 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() noexcept override
  514. {
  515. pData->audioIn.count = 0;
  516. pData->audioOut.count = 0;
  517. CarlaPlugin::initBuffers();
  518. }
  519. // -------------------------------------------------------------------
  520. // Information (base)
  521. PluginType getType() const noexcept override
  522. {
  523. return PLUGIN_JACK;
  524. }
  525. PluginCategory getCategory() const noexcept override
  526. {
  527. return PLUGIN_CATEGORY_NONE;
  528. }
  529. void getLabel(char* const strBuf) const noexcept override
  530. {
  531. std::strncpy(strBuf, "zita-rev1", STR_MAX);
  532. }
  533. void getRealName(char* const strBuf) const noexcept override
  534. {
  535. std::strncpy(strBuf, "zita-rev1", STR_MAX);
  536. }
  537. // -------------------------------------------------------------------
  538. // Information (count)
  539. // nothing
  540. // -------------------------------------------------------------------
  541. // Information (current data)
  542. // nothing
  543. // -------------------------------------------------------------------
  544. // Information (per-plugin data)
  545. uint getOptionsAvailable() const noexcept override
  546. {
  547. uint options = 0x0;
  548. //options |= PLUGIN_OPTION_FIXED_BUFFERS;
  549. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  550. //options |= PLUGIN_OPTION_USE_CHUNKS;
  551. {
  552. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  553. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  554. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  555. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  556. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  557. }
  558. return options;
  559. }
  560. // -------------------------------------------------------------------
  561. // Set data (state)
  562. // nothing
  563. // -------------------------------------------------------------------
  564. // Set data (internal stuff)
  565. // -------------------------------------------------------------------
  566. // Set data (plugin-specific stuff)
  567. // -------------------------------------------------------------------
  568. // Set ui stuff
  569. // -------------------------------------------------------------------
  570. // Plugin state
  571. void reload() override
  572. {
  573. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  574. carla_stderr2("JackPlugin::reload() - start");
  575. //const EngineProcessMode processMode(pData->engine->getProccessMode());
  576. // Safely disable plugin for reload
  577. const ScopedDisabler sd(this);
  578. if (pData->active)
  579. deactivate();
  580. clearBuffers();
  581. pData->audioIn.count = 2;
  582. pData->audioOut.count = 2;
  583. bufferSizeChanged(pData->engine->getBufferSize());
  584. //reloadPrograms(true);
  585. if (pData->active)
  586. activate();
  587. carla_stderr2("JackPlugin::reload() - end");
  588. }
  589. // -------------------------------------------------------------------
  590. // Plugin processing
  591. void activate() noexcept override
  592. {
  593. }
  594. void deactivate() noexcept override
  595. {
  596. }
  597. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  598. {
  599. carla_stderr2("JackPlugin::process");
  600. // --------------------------------------------------------------------------------------------------------
  601. // Check if active
  602. if (! (gJackClient.isActive && pData->active))
  603. {
  604. // disable any output sound
  605. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  606. FLOAT_CLEAR(outBuffer[i], static_cast<int>(frames));
  607. carla_stderr2("JackPlugin::process disabled");
  608. return;
  609. }
  610. carla_stderr2("JackPlugin::working");
  611. // --------------------------------------------------------------------------------------------------------
  612. // Check if needs reset
  613. if (pData->needsReset)
  614. {
  615. pData->needsReset = false;
  616. }
  617. processSingle(inBuffer, outBuffer, frames);
  618. }
  619. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
  620. {
  621. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  622. if (pData->audioIn.count > 0)
  623. {
  624. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  625. }
  626. if (pData->audioOut.count > 0)
  627. {
  628. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  629. }
  630. // --------------------------------------------------------------------------------------------------------
  631. // Try lock, silence otherwise
  632. if (pData->engine->isOffline())
  633. {
  634. pData->singleMutex.lock();
  635. }
  636. else if (! pData->singleMutex.tryLock())
  637. {
  638. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  639. FLOAT_CLEAR(outBuffer[i], frames);
  640. return false;
  641. }
  642. // --------------------------------------------------------------------------------------------------------
  643. // Set audio in buffers
  644. if (pData->audioIn.count == 2)
  645. {
  646. gPortAudioIn1.buffer = inBuffer[0];
  647. gPortAudioIn2.buffer = inBuffer[1];
  648. }
  649. else if (pData->audioIn.count == 1)
  650. {
  651. gPortAudioIn1.buffer = inBuffer[0];
  652. }
  653. if (pData->audioOut.count == 2)
  654. {
  655. gPortAudioOut1.buffer = outBuffer[0];
  656. gPortAudioOut2.buffer = outBuffer[1];
  657. }
  658. else if (pData->audioOut.count == 1)
  659. {
  660. gPortAudioOut1.buffer = outBuffer[0];
  661. }
  662. // --------------------------------------------------------------------------------------------------------
  663. // Run plugin
  664. //if (gJackClient.process_cb != nullptr)
  665. // gJackClient.process_cb(frames, gJackClient.process_ptr);
  666. // --------------------------------------------------------------------------------------------------------
  667. // Set audio out buffers
  668. //for (uint32_t i=0; i < pData->audioOut.count; ++i)
  669. // FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getSampleData(static_cast<int>(i)), static_cast<int>(frames));
  670. // --------------------------------------------------------------------------------------------------------
  671. pData->singleMutex.unlock();
  672. return true;
  673. }
  674. void bufferSizeChanged(const uint32_t newBufferSize) override
  675. {
  676. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  677. carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
  678. }
  679. void sampleRateChanged(const double newSampleRate) override
  680. {
  681. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  682. carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
  683. }
  684. // -------------------------------------------------------------------
  685. // Plugin buffers
  686. // nothing
  687. // -------------------------------------------------------------------
  688. // Post-poned UI Stuff
  689. // nothing
  690. // -------------------------------------------------------------------
  691. protected:
  692. // TODO
  693. // -------------------------------------------------------------------
  694. public:
  695. bool init(const char* const filename, const char* const name, const char* const label)
  696. {
  697. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  698. // ---------------------------------------------------------------
  699. // first checks
  700. if (pData->client != nullptr)
  701. {
  702. pData->engine->setLastError("Plugin client is already registered");
  703. return false;
  704. }
  705. if (filename == nullptr || filename[0] == '\0')
  706. {
  707. pData->engine->setLastError("null filename");
  708. return false;
  709. }
  710. if (label == nullptr || label[0] == '\0')
  711. {
  712. pData->engine->setLastError("null label");
  713. return false;
  714. }
  715. // ---------------------------------------------------------------
  716. // get info
  717. if (name != nullptr && name[0] != '\0')
  718. pData->name = pData->engine->getUniquePluginName(name);
  719. else
  720. pData->name = pData->engine->getUniquePluginName("test");
  721. pData->filename = carla_strdup(filename);
  722. // ---------------------------------------------------------------
  723. // register client
  724. pData->client = pData->engine->addClient(this);
  725. if (pData->client == nullptr || ! pData->client->isOk())
  726. {
  727. pData->engine->setLastError("Failed to register plugin client");
  728. return false;
  729. }
  730. // ---------------------------------------------------------------
  731. // load plugin settings
  732. {
  733. // set default options
  734. pData->options = 0x0;
  735. //pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  736. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  737. //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  738. //if (fInstance->acceptsMidi())
  739. {
  740. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  741. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  742. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  743. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  744. }
  745. // set identifier string
  746. CarlaString identifier("JACK/");
  747. //identifier += juceId.toRawUTF8();
  748. pData->identifier = identifier.dup();
  749. // load settings
  750. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  751. }
  752. return true;
  753. }
  754. private:
  755. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JackPlugin)
  756. };
  757. CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init)
  758. {
  759. carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label);
  760. JackPlugin* const plugin(new JackPlugin(init.engine, init.id));
  761. if (! plugin->init(init.filename, init.name, init.label))
  762. {
  763. delete plugin;
  764. return nullptr;
  765. }
  766. plugin->reload();
  767. // if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
  768. // {
  769. // init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!");
  770. // delete plugin;
  771. // return nullptr;
  772. // }
  773. return plugin;
  774. }
  775. CARLA_BACKEND_END_NAMESPACE
  776. // -------------------------------------------------------------------------------------------------------------------