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.

483 lines
14KB

  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 "CarlaUtils.hpp"
  20. #include "jackbridge/JackBridge.hpp"
  21. //#include "CarlaEngine.hpp"
  22. //#include "CarlaPlugin.hpp"
  23. //#include "CarlaBackendUtils.hpp"
  24. //#include "CarlaBridgeUtils.hpp"
  25. //#include "CarlaMIDI.h"
  26. // -------------------------------------------------------------------------------------------------------------------
  27. struct _jack_client {
  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. shutdown_cb = nullptr;
  39. shutdown_ptr = nullptr;
  40. process_cb = nullptr;
  41. process_ptr = nullptr;
  42. }
  43. };
  44. static jack_client_t gJackClient;
  45. // -------------------------------------------------------------------------------------------------------------------
  46. struct _jack_port {
  47. bool used;
  48. char name[128+1];
  49. _jack_port()
  50. : used(false) {}
  51. };
  52. // system ports
  53. static jack_port_t gPortSystemIn1; // 0
  54. static jack_port_t gPortSystemIn2; // 1
  55. static jack_port_t gPortSystemOut1; // 2
  56. static jack_port_t gPortSystemOut2; // 3
  57. // client ports
  58. static jack_port_t gPortAudioIn1; // 4
  59. static jack_port_t gPortAudioIn2; // 5
  60. static jack_port_t gPortAudioOut1; // 6
  61. static jack_port_t gPortAudioOut2; // 7
  62. static jack_port_t gPortMidiIn; // 8
  63. static jack_port_t gPortMidiOut; // 9
  64. // -------------------------------------------------------------------------------------------------------------------
  65. CARLA_EXPORT jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...);
  66. CARLA_EXPORT int jack_client_close(jack_client_t* client);
  67. CARLA_EXPORT int jack_client_name_size();
  68. CARLA_EXPORT char* jack_get_client_name(jack_client_t* client);
  69. CARLA_EXPORT int jack_activate(jack_client_t* client);
  70. CARLA_EXPORT int jack_deactivate(jack_client_t* client);
  71. CARLA_EXPORT int jack_is_realtime(jack_client_t* client);
  72. CARLA_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* client);
  73. CARLA_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* client);
  74. 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);
  75. CARLA_EXPORT const char* jack_port_name(const jack_port_t* port);
  76. CARLA_EXPORT const char** jack_get_ports(jack_client_t*, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags);
  77. CARLA_EXPORT jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name);
  78. CARLA_EXPORT jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id);
  79. CARLA_EXPORT int jack_connect(jack_client_t* client, const char* source_port, const char* destination_port);
  80. CARLA_EXPORT int jack_disconnect(jack_client_t* client, const char* source_port, const char* destination_port);
  81. CARLA_EXPORT void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg);
  82. CARLA_EXPORT int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg);
  83. CARLA_EXPORT void jack_set_info_function(void (*func)(const char*));
  84. CARLA_EXPORT void jack_set_error_function(void (*func)(const char*));
  85. CARLA_EXPORT void jack_free(void* ptr);
  86. // -------------------------------------------------------------------------------------------------------------------
  87. typedef void (*jack_error_callback)(const char* msg);
  88. typedef void (*jack_info_callback)(const char* msg);
  89. jack_error_callback sErrorCallback = nullptr;
  90. jack_info_callback sInfoCallback = nullptr;
  91. // -------------------------------------------------------------------------------------------------------------------
  92. jack_client_t* jack_client_open(const char* client_name, jack_options_t /*options*/, jack_status_t* status, ...)
  93. {
  94. if (carla_is_engine_running())
  95. {
  96. if (status != nullptr)
  97. *status = JackServerStarted;
  98. return nullptr;
  99. }
  100. if (! carla_engine_init("JACK", client_name))
  101. {
  102. if (status != nullptr)
  103. *status = JackServerFailed;
  104. return nullptr;
  105. }
  106. if (! gPortSystemIn1.used)
  107. {
  108. gPortSystemIn1.used = true;
  109. gPortSystemIn2.used = true;
  110. gPortSystemOut1.used = true;
  111. gPortSystemOut2.used = true;
  112. std::strcpy(gPortSystemIn1.name, "system:capture_1");
  113. std::strcpy(gPortSystemIn2.name, "system:capture_2");
  114. std::strcpy(gPortSystemOut1.name, "system:playback_1");
  115. std::strcpy(gPortSystemOut2.name, "system:playback_2");
  116. }
  117. return &gJackClient;
  118. }
  119. int jack_client_close(jack_client_t* client)
  120. {
  121. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  122. if (! carla_is_engine_running())
  123. return -1;
  124. carla_engine_close();
  125. gJackClient.clear();
  126. gPortAudioIn1.used = 0;
  127. gPortAudioIn2.used = 0;
  128. gPortAudioOut1.used = 0;
  129. gPortAudioOut2.used = 0;
  130. gPortMidiIn.used = 0;
  131. gPortMidiOut.used = 0;
  132. return 0;
  133. }
  134. // -------------------------------------------------------------------------------------------------------------------
  135. int jack_client_name_size()
  136. {
  137. return 32+1; // same as JACK1
  138. }
  139. char* jack_get_client_name(jack_client_t* client)
  140. {
  141. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  142. if (const CarlaEngine* const engine = carla_get_engine())
  143. return const_cast<char*>(engine->getName());
  144. return nullptr;
  145. }
  146. // -------------------------------------------------------------------------------------------------------------------
  147. int jack_activate(jack_client_t* client)
  148. {
  149. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  150. return 0;
  151. }
  152. int jack_deactivate(jack_client_t* client)
  153. {
  154. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  155. return 0;
  156. }
  157. int jack_is_realtime(jack_client_t* client)
  158. {
  159. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  160. return 1;
  161. }
  162. // -------------------------------------------------------------------------------------------------------------------
  163. jack_nframes_t jack_get_sample_rate(jack_client_t* client)
  164. {
  165. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  166. return static_cast<uint32_t>(carla_get_sample_rate());
  167. }
  168. jack_nframes_t jack_get_buffer_size(jack_client_t* client)
  169. {
  170. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
  171. return carla_get_buffer_size();
  172. }
  173. // -------------------------------------------------------------------------------------------------------------------
  174. jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long)
  175. {
  176. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  177. if (std::strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) == 0)
  178. {
  179. if (flags & JackPortIsInput)
  180. {
  181. if (gPortAudioIn1.used && gPortAudioIn2.used)
  182. return nullptr;
  183. if (! gPortAudioIn1.used)
  184. {
  185. std::strncpy(gPortAudioIn1.name, port_name, 128);
  186. return &gPortAudioIn1;
  187. }
  188. else
  189. {
  190. std::strncpy(gPortAudioIn2.name, port_name, 128);
  191. return &gPortAudioIn2;
  192. }
  193. }
  194. else
  195. {
  196. if (gPortAudioOut1.used && gPortAudioOut2.used)
  197. return nullptr;
  198. if (! gPortAudioOut1.used)
  199. {
  200. std::strncpy(gPortAudioOut1.name, port_name, 128);
  201. return &gPortAudioOut1;
  202. }
  203. else
  204. {
  205. std::strncpy(gPortAudioOut2.name, port_name, 128);
  206. return &gPortAudioOut2;
  207. }
  208. }
  209. }
  210. if (std::strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0)
  211. {
  212. if (flags & JackPortIsInput)
  213. {
  214. if (gPortMidiIn.used)
  215. return nullptr;
  216. std::strncpy(gPortMidiIn.name, port_name, 128);
  217. return &gPortMidiIn;
  218. }
  219. else
  220. {
  221. if (gPortMidiOut.used)
  222. return nullptr;
  223. std::strncpy(gPortMidiOut.name, port_name, 128);
  224. return &gPortMidiOut;
  225. }
  226. }
  227. return nullptr;
  228. }
  229. // -------------------------------------------------------------------------------------------------------------------
  230. const char* jack_port_name(const jack_port_t* port)
  231. {
  232. return port->name;
  233. }
  234. // -------------------------------------------------------------------------------------------------------------------
  235. const char** jack_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
  236. {
  237. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  238. if (port_name_pattern != nullptr)
  239. {
  240. if (std::strstr("system:playback_", port_name_pattern) == nullptr)
  241. return nullptr;
  242. if (std::strstr("system:capture_", port_name_pattern) == nullptr)
  243. return nullptr;
  244. }
  245. if (type_name_pattern != nullptr)
  246. {
  247. if (std::strstr(JACK_DEFAULT_AUDIO_TYPE, type_name_pattern) == nullptr)
  248. return nullptr;
  249. }
  250. uint numPorts = 0;
  251. if (flags == 0)
  252. {
  253. numPorts = 4;
  254. }
  255. else
  256. {
  257. if (flags & JackPortIsInput)
  258. numPorts += 2;
  259. if (flags & JackPortIsOutput)
  260. numPorts += 2;
  261. }
  262. if (numPorts == 0)
  263. return nullptr;
  264. const char** const ports = new const char*[numPorts+1];
  265. uint i = 0;
  266. if (flags == 0 || (flags & JackPortIsInput) != 0)
  267. {
  268. ports[i++] = gPortSystemIn1.name;
  269. ports[i++] = gPortSystemIn1.name;
  270. }
  271. if (flags == 0 || (flags & JackPortIsOutput) != 0)
  272. {
  273. ports[i++] = gPortSystemOut1.name;
  274. ports[i++] = gPortSystemOut1.name;
  275. }
  276. ports[i++] = nullptr;
  277. return ports;
  278. }
  279. jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name)
  280. {
  281. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  282. CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
  283. if (std::strcmp(port_name, gPortSystemIn1.name) == 0)
  284. return &gPortSystemIn1;
  285. if (std::strcmp(port_name, gPortSystemIn2.name) == 0)
  286. return &gPortSystemIn2;
  287. if (std::strcmp(port_name, gPortSystemOut1.name) == 0)
  288. return &gPortSystemOut1;
  289. if (std::strcmp(port_name, gPortSystemOut2.name) == 0)
  290. return &gPortSystemOut2;
  291. if (gPortAudioIn1.used && std::strcmp(port_name, gPortAudioIn1.name) == 0)
  292. return &gPortAudioIn1;
  293. if (gPortAudioIn2.used && std::strcmp(port_name, gPortAudioIn2.name) == 0)
  294. return &gPortAudioIn2;
  295. if (gPortAudioOut1.used && std::strcmp(port_name, gPortAudioOut1.name) == 0)
  296. return &gPortAudioOut1;
  297. if (gPortAudioOut2.used && std::strcmp(port_name, gPortAudioOut2.name) == 0)
  298. return &gPortAudioOut2;
  299. if (gPortMidiIn.used && std::strcmp(port_name, gPortMidiIn.name) == 0)
  300. return &gPortMidiIn;
  301. if (gPortMidiOut.used && std::strcmp(port_name, gPortMidiOut.name) == 0)
  302. return &gPortMidiOut;
  303. return nullptr;
  304. }
  305. jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id)
  306. {
  307. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
  308. CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
  309. switch (port_id)
  310. {
  311. case 0:
  312. return &gPortSystemIn1;
  313. case 1:
  314. return &gPortSystemIn2;
  315. case 2:
  316. return &gPortSystemOut1;
  317. case 3:
  318. return &gPortSystemOut2;
  319. case 4:
  320. if (gPortAudioIn1.used)
  321. return &gPortAudioIn1;
  322. break;
  323. case 5:
  324. if (gPortAudioIn2.used)
  325. return &gPortAudioIn2;
  326. break;
  327. case 6:
  328. if (gPortAudioOut1.used)
  329. return &gPortAudioOut1;
  330. break;
  331. case 7:
  332. if (gPortAudioOut2.used)
  333. return &gPortAudioOut2;
  334. break;
  335. case 8:
  336. if (gPortMidiIn.used)
  337. return &gPortMidiIn;
  338. break;
  339. case 9:
  340. if (gPortMidiOut.used)
  341. return &gPortMidiOut;
  342. break;
  343. }
  344. return nullptr;
  345. }
  346. // -------------------------------------------------------------------------------------------------------------------
  347. int jack_connect(jack_client_t* client, const char*, const char*)
  348. {
  349. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  350. return 0;
  351. }
  352. int jack_disconnect(jack_client_t* client, const char*, const char*)
  353. {
  354. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  355. return 0;
  356. }
  357. // -------------------------------------------------------------------------------------------------------------------
  358. void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg)
  359. {
  360. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient,);
  361. gJackClient.shutdown_cb = function;
  362. gJackClient.shutdown_ptr = arg;
  363. }
  364. int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
  365. {
  366. CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
  367. gJackClient.process_cb = process_callback;
  368. gJackClient.process_ptr = arg;
  369. return 0;
  370. }
  371. // -------------------------------------------------------------------------------------------------------------------
  372. void jack_set_error_function(void (*func)(const char*))
  373. {
  374. sErrorCallback = func;
  375. }
  376. void jack_set_info_function(void (*func)(const char*))
  377. {
  378. sInfoCallback = func;
  379. }
  380. void jack_free(void* ptr)
  381. {
  382. delete[] (char**)ptr;
  383. }
  384. // -------------------------------------------------------------------------------------------------------------------
  385. CARLA_EXPORT void carla_register_all_plugins();
  386. void carla_register_all_plugins() {}
  387. // -------------------------------------------------------------------------------------------------------------------