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.

2290 lines
81KB

  1. /*
  2. * Carla Standalone
  3. * Copyright (C) 2011-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. // TODO:
  18. // Check carla_stderr2("Engine is not running"); <= prepend func name and args
  19. #include "CarlaHost.h"
  20. #include "CarlaMIDI.h"
  21. #include "CarlaEngine.hpp"
  22. #include "CarlaPlugin.hpp"
  23. #include "CarlaBackendUtils.hpp"
  24. #include "CarlaBase64Utils.hpp"
  25. #ifdef HAVE_LIBLO
  26. # include "CarlaOscUtils.hpp"
  27. #endif
  28. #include "juce_audio_formats.h"
  29. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  30. # include "juce_gui_basics.h"
  31. #else
  32. namespace juce {
  33. # include "juce_events/messages/juce_Initialisation.h"
  34. } // namespace juce
  35. #endif
  36. namespace CB = CarlaBackend;
  37. using CB::EngineOptions;
  38. // -------------------------------------------------------------------------------------------------------------------
  39. // Single, standalone engine
  40. struct CarlaBackendStandalone {
  41. CarlaEngine* engine;
  42. EngineCallbackFunc engineCallback;
  43. void* engineCallbackPtr;
  44. #ifndef BUILD_BRIDGE
  45. EngineOptions engineOptions;
  46. #endif
  47. FileCallbackFunc fileCallback;
  48. void* fileCallbackPtr;
  49. CarlaString lastError;
  50. CarlaBackendStandalone() noexcept
  51. : engine(nullptr),
  52. engineCallback(nullptr),
  53. engineCallbackPtr(nullptr),
  54. #ifndef BUILD_BRIDGE
  55. engineOptions(),
  56. #endif
  57. fileCallback(nullptr),
  58. fileCallbackPtr(nullptr),
  59. lastError() {}
  60. ~CarlaBackendStandalone() noexcept
  61. {
  62. CARLA_SAFE_ASSERT(engine == nullptr);
  63. }
  64. CARLA_PREVENT_HEAP_ALLOCATION
  65. CARLA_DECLARE_NON_COPY_STRUCT(CarlaBackendStandalone)
  66. };
  67. static CarlaBackendStandalone gStandalone;
  68. #ifdef HAVE_LIBLO
  69. // -------------------------------------------------------------------------------------------------------------------
  70. // NSM support
  71. #define NSM_API_VERSION_MAJOR 1
  72. #define NSM_API_VERSION_MINOR 2
  73. #define NSM_CLIENT_FEATURES ":switch:"
  74. //#define NSM_CLIENT_FEATURES ":switch:optional-gui:"
  75. class CarlaNSM
  76. {
  77. public:
  78. CarlaNSM() noexcept
  79. : fOscAddress(nullptr),
  80. fOscServer(nullptr),
  81. fOscServerThread(nullptr),
  82. fProjectPath(),
  83. fHasBroadcast(false),
  84. fHasOptionalGui(false),
  85. fHasServerControl(false),
  86. fStarted() {}
  87. ~CarlaNSM()
  88. {
  89. if (fOscServerThread != nullptr)
  90. {
  91. lo_server_thread_stop(fOscServerThread);
  92. lo_server_thread_free(fOscServerThread);
  93. fOscServerThread = nullptr;
  94. fOscServer = nullptr;
  95. }
  96. if (fOscAddress != nullptr)
  97. {
  98. lo_address_free(fOscAddress);
  99. fOscAddress = nullptr;
  100. }
  101. }
  102. bool announce(const int pid, const char* const executableName)
  103. {
  104. CARLA_SAFE_ASSERT_RETURN(pid != 0, false);
  105. CARLA_SAFE_ASSERT_RETURN(executableName != nullptr && executableName[0] != '\0', false);
  106. const char* const NSM_URL(std::getenv("NSM_URL"));
  107. if (NSM_URL == nullptr)
  108. return false;
  109. const lo_address addr = lo_address_new_from_url(NSM_URL);
  110. CARLA_SAFE_ASSERT_RETURN(addr != nullptr, false);
  111. const int proto = lo_address_get_protocol(addr);
  112. if (fOscServerThread == nullptr)
  113. {
  114. // create new OSC server
  115. fOscServerThread = lo_server_thread_new_with_proto(nullptr, proto, _osc_error_handler);
  116. CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr, false);
  117. // register message handlers
  118. lo_server_thread_add_method(fOscServerThread, "/error", "sis", _error_handler, this);
  119. lo_server_thread_add_method(fOscServerThread, "/reply", "ssss", _reply_handler, this);
  120. lo_server_thread_add_method(fOscServerThread, "/nsm/client/open", "sss", _open_handler, this);
  121. lo_server_thread_add_method(fOscServerThread, "/nsm/client/save", "", _save_handler, this);
  122. lo_server_thread_add_method(fOscServerThread, "/nsm/client/session_is_loaded", "", _loaded_handler, this);
  123. lo_server_thread_add_method(fOscServerThread, "/nsm/client/show_optional_gui", "", _show_gui_handler, this);
  124. lo_server_thread_add_method(fOscServerThread, "/nsm/client/hide_optional_gui", "", _hide_gui_handler, this);
  125. lo_server_thread_add_method(fOscServerThread, nullptr, nullptr, _broadcast_handler, this);
  126. fOscServer = lo_server_thread_get_server(fOscServerThread);
  127. }
  128. #ifndef BUILD_ANSI_TEST
  129. lo_send_from(addr, fOscServer, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
  130. "Carla", NSM_CLIENT_FEATURES, executableName, NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid);
  131. #endif
  132. lo_address_free(addr);
  133. return true;
  134. }
  135. void start()
  136. {
  137. CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr,);
  138. CARLA_SAFE_ASSERT_RETURN(! fStarted,);
  139. fStarted = true;
  140. lo_server_thread_start(fOscServerThread);
  141. }
  142. static CarlaNSM& getInstance()
  143. {
  144. static CarlaNSM sInstance;
  145. return sInstance;
  146. }
  147. protected:
  148. int handleError(const char* const method, const int code, const char* const message)
  149. {
  150. carla_stdout("CarlaNSM::handleError(\"%s\", %i, \"%s\")", method, code, message);
  151. if (gStandalone.engineCallback != nullptr)
  152. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 0, code, 0.0f, message);
  153. return 1;
  154. // may be unused
  155. (void)method;
  156. }
  157. int handleReply(const char* const method, const char* const message, const char* const smName, const char* const features,
  158. const lo_message msg)
  159. {
  160. CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr, 1);
  161. carla_stdout("CarlaNSM::handleReply(\"%s\", \"%s\", \"%s\", \"%s\")", method, message, smName, features);
  162. if (std::strcmp(method, "/nsm/server/announce") == 0)
  163. {
  164. char* const addressURL(lo_address_get_url(lo_message_get_source(msg)));
  165. CARLA_SAFE_ASSERT_RETURN(addressURL != nullptr, 0);
  166. if (fOscAddress != nullptr)
  167. lo_address_free(fOscAddress);
  168. fOscAddress = lo_address_new_from_url(addressURL);
  169. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 0);
  170. fHasBroadcast = std::strstr(features, ":broadcast:") != nullptr;
  171. fHasOptionalGui = std::strstr(features, ":optional-gui:") != nullptr;
  172. fHasServerControl = std::strstr(features, ":server_control:") != nullptr;
  173. carla_stdout("Carla started via '%s', message: %s", smName, message);
  174. if (gStandalone.engineCallback != nullptr)
  175. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 1, 0, 0.0f, smName);
  176. // UI starts visible
  177. lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_shown", "");
  178. }
  179. else
  180. {
  181. carla_stdout("Got unknown NSM reply method '%s'", method);
  182. }
  183. return 0;
  184. }
  185. int handleOpen(const char* const projectPath, const char* const displayName, const char* const clientNameId)
  186. {
  187. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  188. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  189. carla_stdout("CarlaNSM::handleOpen(\"%s\", \"%s\", \"%s\")", projectPath, displayName, clientNameId);
  190. if (carla_is_engine_running())
  191. carla_engine_close();
  192. carla_engine_init("JACK", clientNameId);
  193. fProjectPath = projectPath;
  194. fProjectPath += ".carxp";
  195. using namespace juce;
  196. const String jfilename = String(CharPointer_UTF8(fProjectPath));
  197. if (File(jfilename).existsAsFile())
  198. carla_load_project(fProjectPath);
  199. lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");
  200. if (gStandalone.engineCallback != nullptr)
  201. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 2, 0, 0.0f, projectPath);
  202. return 0;
  203. }
  204. int handleSave()
  205. {
  206. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  207. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  208. CARLA_SAFE_ASSERT_RETURN(fProjectPath.isNotEmpty(), 0);
  209. carla_stdout("CarlaNSM::handleSave()");
  210. carla_save_project(fProjectPath);
  211. lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");
  212. if (gStandalone.engineCallback != nullptr)
  213. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 3, 0, 0.0f, nullptr);
  214. return 0;
  215. }
  216. int handleSessionIsLoaded()
  217. {
  218. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  219. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  220. carla_stdout("CarlaNSM::handleSessionIsLoaded()");
  221. if (gStandalone.engineCallback != nullptr)
  222. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 4, 0, 0.0f, nullptr);
  223. return 0;
  224. }
  225. int handleShowOptionalGui()
  226. {
  227. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  228. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  229. carla_stdout("CarlaNSM::handleShowOptionalGui()");
  230. lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_shown", "");
  231. if (gStandalone.engineCallback != nullptr)
  232. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 5, 0, 0.0f, nullptr);
  233. return 0;
  234. }
  235. int handleHideOptionalGui()
  236. {
  237. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  238. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  239. carla_stdout("CarlaNSM::handleHideOptionalGui()");
  240. lo_send_from(fOscAddress, fOscServer, LO_TT_IMMEDIATE, "/nsm/client/gui_is_hidden", "");
  241. if (gStandalone.engineCallback != nullptr)
  242. gStandalone.engineCallback(gStandalone.engineCallbackPtr, CB::ENGINE_CALLBACK_NSM, 0, 6, 0, 0.0f, nullptr);
  243. return 0;
  244. }
  245. int handleBroadcast(const char* const types, lo_arg** const argv, const int argc)
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(fOscAddress != nullptr, 1);
  248. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 1);
  249. carla_stdout("CarlaNSM::handleBroadcast(%s, %p, %i)", types, argv, argc);
  250. // TODO
  251. return 0;
  252. }
  253. private:
  254. lo_address fOscAddress;
  255. lo_server fOscServer;
  256. lo_server_thread fOscServerThread;
  257. CarlaString fProjectPath;
  258. bool fHasBroadcast;
  259. bool fHasOptionalGui;
  260. bool fHasServerControl;
  261. bool fStarted;
  262. #define handlePtr ((CarlaNSM*)data)
  263. static void _osc_error_handler(int num, const char* msg, const char* path)
  264. {
  265. carla_stderr2("CarlaNSM::_osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
  266. }
  267. static int _error_handler(const char*, const char* types, lo_arg** argv, int argc, lo_message, void* data)
  268. {
  269. CARLA_SAFE_ASSERT_RETURN(argc == 3, 1);
  270. CARLA_SAFE_ASSERT_RETURN(std::strcmp(types, "sis") == 0, 1);
  271. const char* const method = &argv[0]->s;
  272. const int code = argv[1]->i;
  273. const char* const message = &argv[2]->s;
  274. return handlePtr->handleError(method, code, message);
  275. }
  276. static int _reply_handler(const char*, const char* types, lo_arg** argv, int argc, lo_message msg, void* data)
  277. {
  278. CARLA_SAFE_ASSERT_RETURN(argc == 4, 1);
  279. CARLA_SAFE_ASSERT_RETURN(std::strcmp(types, "ssss") == 0, 1);
  280. const char* const method = &argv[0]->s;
  281. const char* const message = &argv[1]->s;
  282. const char* const smName = &argv[2]->s;
  283. const char* const features = &argv[3]->s;
  284. return handlePtr->handleReply(method, message, smName, features, msg);
  285. }
  286. static int _open_handler(const char*, const char* types, lo_arg** argv, int argc, lo_message, void* data)
  287. {
  288. CARLA_SAFE_ASSERT_RETURN(argc == 3, 1);
  289. CARLA_SAFE_ASSERT_RETURN(std::strcmp(types, "sss") == 0, 1);
  290. const char* const projectPath = &argv[0]->s;
  291. const char* const displayName = &argv[1]->s;
  292. const char* const clientNameId = &argv[2]->s;
  293. return handlePtr->handleOpen(projectPath, displayName, clientNameId);
  294. }
  295. static int _save_handler(const char*, const char*, lo_arg**, int argc, lo_message, void* data)
  296. {
  297. CARLA_SAFE_ASSERT_RETURN(argc == 0, 1);
  298. return handlePtr->handleSave();
  299. }
  300. static int _loaded_handler(const char*, const char*, lo_arg**, int argc, lo_message, void* data)
  301. {
  302. CARLA_SAFE_ASSERT_RETURN(argc == 0, 1);
  303. return handlePtr->handleSessionIsLoaded();
  304. }
  305. static int _show_gui_handler(const char*, const char*, lo_arg**, int argc, lo_message, void* data)
  306. {
  307. CARLA_SAFE_ASSERT_RETURN(argc == 0, 1);
  308. return handlePtr->handleShowOptionalGui();
  309. }
  310. static int _hide_gui_handler(const char*, const char*, lo_arg**, int argc, lo_message, void* data)
  311. {
  312. CARLA_SAFE_ASSERT_RETURN(argc == 0, 1);
  313. return handlePtr->handleHideOptionalGui();
  314. }
  315. static int _broadcast_handler(const char* path, const char* types, lo_arg** argv, int argc, lo_message, void* data)
  316. {
  317. return handlePtr->handleBroadcast(types, argv, argc);
  318. }
  319. #undef handlePtr
  320. CARLA_PREVENT_HEAP_ALLOCATION
  321. CARLA_DECLARE_NON_COPY_CLASS(CarlaNSM)
  322. };
  323. #endif // HAVE_LIBLO
  324. // -------------------------------------------------------------------------------------------------------------------
  325. // API
  326. #define CARLA_COMMON_NEED_CHECKSTRINGPTR
  327. #include "CarlaHostCommon.cpp"
  328. // -------------------------------------------------------------------------------------------------------------------
  329. uint carla_get_engine_driver_count()
  330. {
  331. carla_debug("carla_get_engine_driver_count()");
  332. return CarlaEngine::getDriverCount();
  333. }
  334. const char* carla_get_engine_driver_name(uint index)
  335. {
  336. carla_debug("carla_get_engine_driver_name(%i)", index);
  337. return CarlaEngine::getDriverName(index);
  338. }
  339. const char* const* carla_get_engine_driver_device_names(uint index)
  340. {
  341. carla_debug("carla_get_engine_driver_device_names(%i)", index);
  342. return CarlaEngine::getDriverDeviceNames(index);
  343. }
  344. const EngineDriverDeviceInfo* carla_get_engine_driver_device_info(uint index, const char* name)
  345. {
  346. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
  347. carla_debug("carla_get_engine_driver_device_info(%i, \"%s\")", index, name);
  348. if (const EngineDriverDeviceInfo* const ret = CarlaEngine::getDriverDeviceInfo(index, name))
  349. {
  350. static EngineDriverDeviceInfo devInfo;
  351. static const uint32_t nullBufferSizes[] = { 0 };
  352. static const double nullSampleRates[] = { 0.0 };
  353. devInfo.hints = ret->hints;
  354. devInfo.bufferSizes = (ret->bufferSizes != nullptr) ? ret->bufferSizes : nullBufferSizes;
  355. devInfo.sampleRates = (ret->sampleRates != nullptr) ? ret->sampleRates : nullSampleRates;
  356. return &devInfo;
  357. }
  358. return nullptr;
  359. }
  360. // -------------------------------------------------------------------------------------------------------------------
  361. CarlaEngine* carla_get_engine()
  362. {
  363. carla_debug("carla_get_engine()");
  364. return gStandalone.engine;
  365. }
  366. // -------------------------------------------------------------------------------------------------------------------
  367. static void carla_engine_init_common()
  368. {
  369. gStandalone.engine->setCallback(gStandalone.engineCallback, gStandalone.engineCallbackPtr);
  370. gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr);
  371. #ifdef BUILD_BRIDGE
  372. using juce::File;
  373. File juceBinaryDir(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory());
  374. /*
  375. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_FORCE_STEREO"))
  376. gStandalone.engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  377. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES"))
  378. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  379. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_PREFER_UI_BRIDGES"))
  380. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  381. */
  382. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_UIS_ALWAYS_ON_TOP"))
  383. gStandalone.engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  384. if (const char* const maxParameters = std::getenv("ENGINE_OPTION_MAX_PARAMETERS"))
  385. gStandalone.engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, std::atoi(maxParameters), nullptr);
  386. if (const char* const uiBridgesTimeout = std::getenv("ENGINE_OPTION_UI_BRIDGES_TIMEOUT"))
  387. gStandalone.engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, std::atoi(uiBridgesTimeout), nullptr);
  388. if (const char* const pathLADSPA = std::getenv("ENGINE_OPTION_PLUGIN_PATH_LADSPA"))
  389. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LADSPA, pathLADSPA);
  390. if (const char* const pathDSSI = std::getenv("ENGINE_OPTION_PLUGIN_PATH_DSSI"))
  391. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_DSSI, pathDSSI);
  392. if (const char* const pathLV2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_LV2"))
  393. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LV2, pathLV2);
  394. if (const char* const pathVST2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_VST2"))
  395. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST2, pathVST2);
  396. if (const char* const pathVST3 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_VST3"))
  397. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST3, pathVST3);
  398. if (const char* const pathAU = std::getenv("ENGINE_OPTION_PLUGIN_PATH_AU"))
  399. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_AU, pathAU);
  400. if (const char* const pathGIG = std::getenv("ENGINE_OPTION_PLUGIN_PATH_GIG"))
  401. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_GIG, pathGIG);
  402. if (const char* const pathSF2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_SF2"))
  403. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SF2, pathSF2);
  404. if (const char* const pathSFZ = std::getenv("ENGINE_OPTION_PLUGIN_PATH_SFZ"))
  405. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SFZ, pathSFZ);
  406. if (const char* const binaryDir = std::getenv("ENGINE_OPTION_PATH_BINARIES"))
  407. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, binaryDir);
  408. else
  409. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, juceBinaryDir.getFullPathName().toRawUTF8());
  410. if (const char* const resourceDir = std::getenv("ENGINE_OPTION_PATH_RESOURCES"))
  411. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, resourceDir);
  412. else
  413. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, juceBinaryDir.getChildFile("resources").getFullPathName().toRawUTF8());
  414. if (const char* const preventBadBehaviour = std::getenv("ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR"))
  415. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, (std::strcmp(preventBadBehaviour, "true") == 0) ? 1 : 0, nullptr);
  416. if (const char* const frontendWinId = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
  417. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, frontendWinId);
  418. #else
  419. gStandalone.engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, gStandalone.engineOptions.forceStereo ? 1 : 0, nullptr);
  420. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, gStandalone.engineOptions.preferPluginBridges ? 1 : 0, nullptr);
  421. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, gStandalone.engineOptions.preferUiBridges ? 1 : 0, nullptr);
  422. gStandalone.engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, gStandalone.engineOptions.uisAlwaysOnTop ? 1 : 0, nullptr);
  423. gStandalone.engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, static_cast<int>(gStandalone.engineOptions.maxParameters), nullptr);
  424. gStandalone.engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, static_cast<int>(gStandalone.engineOptions.uiBridgesTimeout), nullptr);
  425. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_NUM_PERIODS, static_cast<int>(gStandalone.engineOptions.audioNumPeriods), nullptr);
  426. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE, static_cast<int>(gStandalone.engineOptions.audioBufferSize), nullptr);
  427. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, static_cast<int>(gStandalone.engineOptions.audioSampleRate), nullptr);
  428. if (gStandalone.engineOptions.audioDevice != nullptr)
  429. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_DEVICE, 0, gStandalone.engineOptions.audioDevice);
  430. if (gStandalone.engineOptions.pathLADSPA != nullptr)
  431. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LADSPA, gStandalone.engineOptions.pathLADSPA);
  432. if (gStandalone.engineOptions.pathDSSI != nullptr)
  433. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_DSSI, gStandalone.engineOptions.pathDSSI);
  434. if (gStandalone.engineOptions.pathLV2 != nullptr)
  435. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LV2, gStandalone.engineOptions.pathLV2);
  436. if (gStandalone.engineOptions.pathVST2 != nullptr)
  437. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST2, gStandalone.engineOptions.pathVST2);
  438. if (gStandalone.engineOptions.pathVST3 != nullptr)
  439. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST3, gStandalone.engineOptions.pathVST3);
  440. if (gStandalone.engineOptions.pathAU != nullptr)
  441. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_AU, gStandalone.engineOptions.pathAU);
  442. if (gStandalone.engineOptions.pathGIG != nullptr)
  443. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_GIG, gStandalone.engineOptions.pathGIG);
  444. if (gStandalone.engineOptions.pathSF2 != nullptr)
  445. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SF2, gStandalone.engineOptions.pathSF2);
  446. if (gStandalone.engineOptions.pathSFZ != nullptr)
  447. gStandalone.engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SFZ, gStandalone.engineOptions.pathSFZ);
  448. if (gStandalone.engineOptions.binaryDir != nullptr && gStandalone.engineOptions.binaryDir[0] != '\0')
  449. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, gStandalone.engineOptions.binaryDir);
  450. if (gStandalone.engineOptions.resourceDir != nullptr && gStandalone.engineOptions.resourceDir[0] != '\0')
  451. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, gStandalone.engineOptions.resourceDir);
  452. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, gStandalone.engineOptions.preventBadBehaviour ? 1 : 0, nullptr);
  453. if (gStandalone.engineOptions.frontendWinId != 0)
  454. {
  455. char strBuf[STR_MAX+1];
  456. strBuf[STR_MAX] = '\0';
  457. std::snprintf(strBuf, STR_MAX, P_UINTPTR, gStandalone.engineOptions.frontendWinId);
  458. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, strBuf);
  459. }
  460. else
  461. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0");
  462. #endif
  463. }
  464. bool carla_engine_init(const char* driverName, const char* clientName)
  465. {
  466. CARLA_SAFE_ASSERT_RETURN(driverName != nullptr && driverName[0] != '\0', false);
  467. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  468. carla_debug("carla_engine_init(\"%s\", \"%s\")", driverName, clientName);
  469. if (gStandalone.engine != nullptr)
  470. {
  471. carla_stderr2("Engine is already running");
  472. gStandalone.lastError = "Engine is already running";
  473. return false;
  474. }
  475. #ifdef CARLA_OS_WIN
  476. carla_setenv("WINEASIO_CLIENT_NAME", clientName);
  477. #endif
  478. // TODO: make this an option, put somewhere else
  479. if (std::getenv("WINE_RT") == nullptr)
  480. {
  481. carla_setenv("WINE_RT", "15");
  482. carla_setenv("WINE_SVR_RT", "10");
  483. }
  484. gStandalone.engine = CarlaEngine::newDriverByName(driverName);
  485. if (gStandalone.engine == nullptr)
  486. {
  487. carla_stderr2("The seleted audio driver is not available");
  488. gStandalone.lastError = "The seleted audio driver is not available";
  489. return false;
  490. }
  491. #ifdef BUILD_BRIDGE
  492. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, nullptr);
  493. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_JACK, nullptr);
  494. gStandalone.engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, false, nullptr);
  495. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, false, nullptr);
  496. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, false, nullptr);
  497. #else
  498. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, static_cast<int>(gStandalone.engineOptions.processMode), nullptr);
  499. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, static_cast<int>(gStandalone.engineOptions.transportMode), nullptr);
  500. #endif
  501. carla_engine_init_common();
  502. if (gStandalone.engine->init(clientName))
  503. {
  504. #ifndef BUILD_BRIDGE
  505. juce::initialiseJuce_GUI();
  506. #endif
  507. gStandalone.lastError = "No error";
  508. return true;
  509. }
  510. else
  511. {
  512. gStandalone.lastError = gStandalone.engine->getLastError();
  513. delete gStandalone.engine;
  514. gStandalone.engine = nullptr;
  515. return false;
  516. }
  517. }
  518. #ifdef BUILD_BRIDGE
  519. bool carla_engine_init_bridge(const char audioBaseName[6+1], const char rtClientBaseName[6+1], const char nonRtClientBaseName[6+1],
  520. const char nonRtServerBaseName[6+1], const char* clientName)
  521. {
  522. CARLA_SAFE_ASSERT_RETURN(audioBaseName != nullptr && audioBaseName[0] != '\0', false);
  523. CARLA_SAFE_ASSERT_RETURN(rtClientBaseName != nullptr && rtClientBaseName[0] != '\0', false);
  524. CARLA_SAFE_ASSERT_RETURN(nonRtClientBaseName != nullptr && nonRtClientBaseName[0] != '\0', false);
  525. CARLA_SAFE_ASSERT_RETURN(nonRtServerBaseName != nullptr && nonRtServerBaseName[0] != '\0', false);
  526. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  527. carla_debug("carla_engine_init_bridge(\"%s\", \"%s\", \"%s\", \"%s\", \"%s\")", audioBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName, clientName);
  528. if (gStandalone.engine != nullptr)
  529. {
  530. carla_stderr2("Engine is already running");
  531. gStandalone.lastError = "Engine is already running";
  532. return false;
  533. }
  534. gStandalone.engine = CarlaEngine::newBridge(audioBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName);
  535. if (gStandalone.engine == nullptr)
  536. {
  537. carla_stderr2("The seleted audio driver is not available!");
  538. gStandalone.lastError = "The seleted audio driver is not available!";
  539. return false;
  540. }
  541. carla_engine_init_common();
  542. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_BRIDGE, nullptr);
  543. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_BRIDGE, nullptr);
  544. if (gStandalone.engine->init(clientName))
  545. {
  546. gStandalone.lastError = "No error";
  547. return true;
  548. }
  549. else
  550. {
  551. gStandalone.lastError = gStandalone.engine->getLastError();
  552. delete gStandalone.engine;
  553. gStandalone.engine = nullptr;
  554. return false;
  555. }
  556. }
  557. #endif
  558. bool carla_engine_close()
  559. {
  560. carla_debug("carla_engine_close()");
  561. if (gStandalone.engine == nullptr)
  562. {
  563. carla_stderr2("Engine is not running");
  564. gStandalone.lastError = "Engine is not running";
  565. return false;
  566. }
  567. gStandalone.engine->setAboutToClose();
  568. gStandalone.engine->removeAllPlugins();
  569. const bool closed(gStandalone.engine->close());
  570. if (! closed)
  571. gStandalone.lastError = gStandalone.engine->getLastError();
  572. #ifndef BUILD_BRIDGE
  573. juce::shutdownJuce_GUI();
  574. #endif
  575. delete gStandalone.engine;
  576. gStandalone.engine = nullptr;
  577. return closed;
  578. }
  579. void carla_engine_idle()
  580. {
  581. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  582. gStandalone.engine->idle();
  583. }
  584. bool carla_is_engine_running()
  585. {
  586. return (gStandalone.engine != nullptr && gStandalone.engine->isRunning());
  587. }
  588. void carla_set_engine_about_to_close()
  589. {
  590. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  591. carla_debug("carla_set_engine_about_to_close()");
  592. gStandalone.engine->setAboutToClose();
  593. }
  594. void carla_set_engine_callback(EngineCallbackFunc func, void* ptr)
  595. {
  596. carla_debug("carla_set_engine_callback(%p, %p)", func, ptr);
  597. gStandalone.engineCallback = func;
  598. gStandalone.engineCallbackPtr = ptr;
  599. if (gStandalone.engine != nullptr)
  600. gStandalone.engine->setCallback(func, ptr);
  601. //#ifdef WANT_LOGS
  602. // gLogThread.setCallback(func, ptr);
  603. //#endif
  604. }
  605. #ifndef BUILD_BRIDGE
  606. void carla_set_engine_option(EngineOption option, int value, const char* valueStr)
  607. {
  608. carla_debug("carla_set_engine_option(%i:%s, %i, \"%s\")", option, CB::EngineOption2Str(option), value, valueStr);
  609. switch (option)
  610. {
  611. case CB::ENGINE_OPTION_DEBUG:
  612. break;
  613. case CB::ENGINE_OPTION_PROCESS_MODE:
  614. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_PROCESS_MODE_SINGLE_CLIENT && value < CB::ENGINE_PROCESS_MODE_BRIDGE,);
  615. gStandalone.engineOptions.processMode = static_cast<CB::EngineProcessMode>(value);
  616. break;
  617. case CB::ENGINE_OPTION_TRANSPORT_MODE:
  618. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_TRANSPORT_MODE_INTERNAL && value < CB::ENGINE_TRANSPORT_MODE_BRIDGE,);
  619. gStandalone.engineOptions.transportMode = static_cast<CB::EngineTransportMode>(value);
  620. break;
  621. case CB::ENGINE_OPTION_FORCE_STEREO:
  622. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  623. gStandalone.engineOptions.forceStereo = (value != 0);
  624. break;
  625. case CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES:
  626. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  627. gStandalone.engineOptions.preferPluginBridges = (value != 0);
  628. break;
  629. case CB::ENGINE_OPTION_PREFER_UI_BRIDGES:
  630. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  631. gStandalone.engineOptions.preferUiBridges = (value != 0);
  632. break;
  633. case CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP:
  634. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  635. gStandalone.engineOptions.uisAlwaysOnTop = (value != 0);
  636. break;
  637. case CB::ENGINE_OPTION_MAX_PARAMETERS:
  638. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  639. gStandalone.engineOptions.maxParameters = static_cast<uint>(value);
  640. break;
  641. case CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT:
  642. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  643. gStandalone.engineOptions.uiBridgesTimeout = static_cast<uint>(value);
  644. break;
  645. case CB::ENGINE_OPTION_AUDIO_NUM_PERIODS:
  646. CARLA_SAFE_ASSERT_RETURN(value >= 2 && value <= 3,);
  647. gStandalone.engineOptions.audioNumPeriods = static_cast<uint>(value);
  648. break;
  649. case CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE:
  650. CARLA_SAFE_ASSERT_RETURN(value >= 8,);
  651. gStandalone.engineOptions.audioBufferSize = static_cast<uint>(value);
  652. break;
  653. case CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE:
  654. CARLA_SAFE_ASSERT_RETURN(value >= 22050,);
  655. gStandalone.engineOptions.audioSampleRate = static_cast<uint>(value);
  656. break;
  657. case CB::ENGINE_OPTION_AUDIO_DEVICE:
  658. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  659. if (gStandalone.engineOptions.audioDevice != nullptr)
  660. delete[] gStandalone.engineOptions.audioDevice;
  661. gStandalone.engineOptions.audioDevice = carla_strdup_safe(valueStr);
  662. break;
  663. case CB::ENGINE_OPTION_PLUGIN_PATH:
  664. CARLA_SAFE_ASSERT_RETURN(value > CB::PLUGIN_NONE,);
  665. CARLA_SAFE_ASSERT_RETURN(value <= CB::PLUGIN_SFZ,);
  666. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  667. switch (value)
  668. {
  669. case CB::PLUGIN_LADSPA:
  670. if (gStandalone.engineOptions.pathLADSPA != nullptr)
  671. delete[] gStandalone.engineOptions.pathLADSPA;
  672. gStandalone.engineOptions.pathLADSPA = carla_strdup_safe(valueStr);
  673. break;
  674. case CB::PLUGIN_DSSI:
  675. if (gStandalone.engineOptions.pathDSSI != nullptr)
  676. delete[] gStandalone.engineOptions.pathDSSI;
  677. gStandalone.engineOptions.pathDSSI = carla_strdup_safe(valueStr);
  678. break;
  679. case CB::PLUGIN_LV2:
  680. if (gStandalone.engineOptions.pathLV2 != nullptr)
  681. delete[] gStandalone.engineOptions.pathLV2;
  682. gStandalone.engineOptions.pathLV2 = carla_strdup_safe(valueStr);
  683. break;
  684. case CB::PLUGIN_VST2:
  685. if (gStandalone.engineOptions.pathVST2 != nullptr)
  686. delete[] gStandalone.engineOptions.pathVST2;
  687. gStandalone.engineOptions.pathVST2 = carla_strdup_safe(valueStr);
  688. break;
  689. case CB::PLUGIN_VST3:
  690. if (gStandalone.engineOptions.pathVST3 != nullptr)
  691. delete[] gStandalone.engineOptions.pathVST3;
  692. gStandalone.engineOptions.pathVST3 = carla_strdup_safe(valueStr);
  693. break;
  694. case CB::PLUGIN_AU:
  695. if (gStandalone.engineOptions.pathAU != nullptr)
  696. delete[] gStandalone.engineOptions.pathAU;
  697. gStandalone.engineOptions.pathAU = carla_strdup_safe(valueStr);
  698. break;
  699. case CB::PLUGIN_GIG:
  700. if (gStandalone.engineOptions.pathGIG != nullptr)
  701. delete[] gStandalone.engineOptions.pathGIG;
  702. gStandalone.engineOptions.pathGIG = carla_strdup_safe(valueStr);
  703. break;
  704. case CB::PLUGIN_SF2:
  705. if (gStandalone.engineOptions.pathSF2 != nullptr)
  706. delete[] gStandalone.engineOptions.pathSF2;
  707. gStandalone.engineOptions.pathSF2 = carla_strdup_safe(valueStr);
  708. break;
  709. case CB::PLUGIN_SFZ:
  710. if (gStandalone.engineOptions.pathSFZ != nullptr)
  711. delete[] gStandalone.engineOptions.pathSFZ;
  712. gStandalone.engineOptions.pathSFZ = carla_strdup_safe(valueStr);
  713. break;
  714. }
  715. break;
  716. case CB::ENGINE_OPTION_PATH_BINARIES:
  717. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  718. if (gStandalone.engineOptions.binaryDir != nullptr)
  719. delete[] gStandalone.engineOptions.binaryDir;
  720. gStandalone.engineOptions.binaryDir = carla_strdup_safe(valueStr);
  721. break;
  722. case CB::ENGINE_OPTION_PATH_RESOURCES:
  723. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  724. if (gStandalone.engineOptions.resourceDir != nullptr)
  725. delete[] gStandalone.engineOptions.resourceDir;
  726. gStandalone.engineOptions.resourceDir = carla_strdup_safe(valueStr);
  727. break;
  728. case CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR:
  729. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  730. gStandalone.engineOptions.preventBadBehaviour = (value != 0);
  731. break;
  732. case CB::ENGINE_OPTION_FRONTEND_WIN_ID:
  733. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  734. const long long winId(std::strtoll(valueStr, nullptr, 16));
  735. CARLA_SAFE_ASSERT_RETURN(winId >= 0,);
  736. gStandalone.engineOptions.frontendWinId = static_cast<uintptr_t>(winId);
  737. break;
  738. }
  739. if (gStandalone.engine != nullptr)
  740. gStandalone.engine->setOption(option, value, valueStr);
  741. }
  742. #endif
  743. void carla_set_file_callback(FileCallbackFunc func, void* ptr)
  744. {
  745. carla_debug("carla_set_file_callback(%p, %p)", func, ptr);
  746. gStandalone.fileCallback = func;
  747. gStandalone.fileCallbackPtr = ptr;
  748. if (gStandalone.engine != nullptr)
  749. gStandalone.engine->setFileCallback(func, ptr);
  750. }
  751. // -------------------------------------------------------------------------------------------------------------------
  752. bool carla_load_file(const char* filename)
  753. {
  754. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  755. carla_debug("carla_load_file(\"%s\")", filename);
  756. if (gStandalone.engine != nullptr)
  757. return gStandalone.engine->loadFile(filename);
  758. carla_stderr2("Engine is not running");
  759. gStandalone.lastError = "Engine is not running";
  760. return false;
  761. }
  762. bool carla_load_project(const char* filename)
  763. {
  764. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  765. carla_debug("carla_load_project(\"%s\")", filename);
  766. if (gStandalone.engine != nullptr)
  767. return gStandalone.engine->loadProject(filename);
  768. carla_stderr2("Engine is not running");
  769. gStandalone.lastError = "Engine is not running";
  770. return false;
  771. }
  772. bool carla_save_project(const char* filename)
  773. {
  774. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  775. carla_debug("carla_save_project(\"%s\")", filename);
  776. if (gStandalone.engine != nullptr)
  777. return gStandalone.engine->saveProject(filename);
  778. carla_stderr2("Engine was never initiated");
  779. gStandalone.lastError = "Engine was never initiated";
  780. return false;
  781. }
  782. #ifndef BUILD_BRIDGE
  783. // -------------------------------------------------------------------------------------------------------------------
  784. bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint portIdB)
  785. {
  786. carla_debug("carla_patchbay_connect(%u, %u, %u, %u)", groupIdA, portIdA, groupIdB, portIdB);
  787. if (gStandalone.engine != nullptr)
  788. return gStandalone.engine->patchbayConnect(groupIdA, portIdA, groupIdB, portIdB);
  789. carla_stderr2("Engine is not running");
  790. gStandalone.lastError = "Engine is not running";
  791. return false;
  792. }
  793. bool carla_patchbay_disconnect(uint connectionId)
  794. {
  795. carla_debug("carla_patchbay_disconnect(%i)", connectionId);
  796. if (gStandalone.engine != nullptr)
  797. return gStandalone.engine->patchbayDisconnect(connectionId);
  798. carla_stderr2("Engine is not running");
  799. gStandalone.lastError = "Engine is not running";
  800. return false;
  801. }
  802. bool carla_patchbay_refresh(bool external)
  803. {
  804. carla_debug("carla_patchbay_refresh(%s)", bool2str(external));
  805. if (gStandalone.engine != nullptr)
  806. return gStandalone.engine->patchbayRefresh(external);
  807. carla_stderr2("Engine is not running");
  808. gStandalone.lastError = "Engine is not running";
  809. return false;
  810. }
  811. // -------------------------------------------------------------------------------------------------------------------
  812. void carla_transport_play()
  813. {
  814. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  815. carla_debug("carla_transport_play()");
  816. gStandalone.engine->transportPlay();
  817. }
  818. void carla_transport_pause()
  819. {
  820. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  821. carla_debug("carla_transport_pause()");
  822. gStandalone.engine->transportPause();
  823. }
  824. void carla_transport_relocate(uint64_t frame)
  825. {
  826. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  827. carla_debug("carla_transport_relocate(%i)", frame);
  828. gStandalone.engine->transportRelocate(frame);
  829. }
  830. uint64_t carla_get_current_transport_frame()
  831. {
  832. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(), 0);
  833. const CB::EngineTimeInfo& timeInfo(gStandalone.engine->getTimeInfo());
  834. return timeInfo.frame;
  835. }
  836. const CarlaTransportInfo* carla_get_transport_info()
  837. {
  838. static CarlaTransportInfo retInfo;
  839. // reset
  840. retInfo.playing = false;
  841. retInfo.frame = 0;
  842. retInfo.bar = 0;
  843. retInfo.beat = 0;
  844. retInfo.tick = 0;
  845. retInfo.bpm = 0.0;
  846. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(), &retInfo);
  847. const CB::EngineTimeInfo& timeInfo(gStandalone.engine->getTimeInfo());
  848. retInfo.playing = timeInfo.playing;
  849. retInfo.frame = timeInfo.frame;
  850. if (timeInfo.valid & CB::EngineTimeInfo::kValidBBT)
  851. {
  852. retInfo.bar = timeInfo.bbt.bar;
  853. retInfo.beat = timeInfo.bbt.beat;
  854. retInfo.tick = timeInfo.bbt.tick;
  855. retInfo.bpm = timeInfo.bbt.beatsPerMinute;
  856. }
  857. return &retInfo;
  858. }
  859. #endif
  860. // -------------------------------------------------------------------------------------------------------------------
  861. uint32_t carla_get_current_plugin_count()
  862. {
  863. if (gStandalone.engine != nullptr)
  864. return gStandalone.engine->getCurrentPluginCount();
  865. return 0;
  866. }
  867. uint32_t carla_get_max_plugin_number()
  868. {
  869. if (gStandalone.engine != nullptr)
  870. return gStandalone.engine->getMaxPluginNumber();
  871. return 0;
  872. }
  873. // -------------------------------------------------------------------------------------------------------------------
  874. bool carla_add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* name, const char* label, int64_t uniqueId, const void* extraPtr, uint options)
  875. {
  876. carla_debug("carla_add_plugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", btype, CB::BinaryType2Str(btype), ptype, CB::PluginType2Str(ptype), filename, name, label, uniqueId, extraPtr, options);
  877. if (gStandalone.engine != nullptr)
  878. return gStandalone.engine->addPlugin(btype, ptype, filename, name, label, uniqueId, extraPtr, options);
  879. carla_stderr2("Engine is not running");
  880. gStandalone.lastError = "Engine is not running";
  881. return false;
  882. }
  883. bool carla_remove_plugin(uint pluginId)
  884. {
  885. carla_debug("carla_remove_plugin(%i)", pluginId);
  886. if (gStandalone.engine != nullptr)
  887. return gStandalone.engine->removePlugin(pluginId);
  888. carla_stderr2("Engine is not running");
  889. gStandalone.lastError = "Engine is not running";
  890. return false;
  891. }
  892. bool carla_remove_all_plugins()
  893. {
  894. carla_debug("carla_remove_all_plugins()");
  895. if (gStandalone.engine != nullptr)
  896. return gStandalone.engine->removeAllPlugins();
  897. carla_stderr2("Engine is not running");
  898. gStandalone.lastError = "Engine is not running";
  899. return false;
  900. }
  901. #ifndef BUILD_BRIDGE
  902. const char* carla_rename_plugin(uint pluginId, const char* newName)
  903. {
  904. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr);
  905. carla_debug("carla_rename_plugin(%i, \"%s\")", pluginId, newName);
  906. if (gStandalone.engine != nullptr)
  907. return gStandalone.engine->renamePlugin(pluginId, newName);
  908. carla_stderr2("Engine is not running");
  909. gStandalone.lastError = "Engine is not running";
  910. return nullptr;
  911. }
  912. bool carla_clone_plugin(uint pluginId)
  913. {
  914. carla_debug("carla_clone_plugin(%i)", pluginId);
  915. if (gStandalone.engine != nullptr)
  916. return gStandalone.engine->clonePlugin(pluginId);
  917. carla_stderr2("Engine is not running");
  918. gStandalone.lastError = "Engine is not running";
  919. return false;
  920. }
  921. bool carla_replace_plugin(uint pluginId)
  922. {
  923. carla_debug("carla_replace_plugin(%i)", pluginId);
  924. if (gStandalone.engine != nullptr)
  925. return gStandalone.engine->replacePlugin(pluginId);
  926. carla_stderr2("Engine is not running");
  927. gStandalone.lastError = "Engine is not running";
  928. return false;
  929. }
  930. bool carla_switch_plugins(uint pluginIdA, uint pluginIdB)
  931. {
  932. CARLA_SAFE_ASSERT_RETURN(pluginIdA != pluginIdB, false);
  933. carla_debug("carla_switch_plugins(%i, %i)", pluginIdA, pluginIdB);
  934. if (gStandalone.engine != nullptr)
  935. return gStandalone.engine->switchPlugins(pluginIdA, pluginIdB);
  936. carla_stderr2("Engine is not running");
  937. gStandalone.lastError = "Engine is not running";
  938. return false;
  939. }
  940. #endif
  941. // -------------------------------------------------------------------------------------------------------------------
  942. bool carla_load_plugin_state(uint pluginId, const char* filename)
  943. {
  944. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  945. carla_debug("carla_load_plugin_state(%i, \"%s\")", pluginId, filename);
  946. if (gStandalone.engine == nullptr || ! gStandalone.engine->isRunning())
  947. {
  948. carla_stderr2("Engine is not running");
  949. gStandalone.lastError = "Engine is not running";
  950. return false;
  951. }
  952. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  953. return plugin->loadStateFromFile(filename);
  954. carla_stderr2("carla_load_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename);
  955. return false;
  956. }
  957. bool carla_save_plugin_state(uint pluginId, const char* filename)
  958. {
  959. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  960. carla_debug("carla_save_plugin_state(%i, \"%s\")", pluginId, filename);
  961. if (gStandalone.engine == nullptr)
  962. {
  963. carla_stderr2("Engine is not running");
  964. gStandalone.lastError = "Engine is not running";
  965. return false;
  966. }
  967. // allow to save even if engine isn't running
  968. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  969. return plugin->saveStateToFile(filename);
  970. carla_stderr2("carla_save_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename);
  971. return false;
  972. }
  973. // -------------------------------------------------------------------------------------------------------------------
  974. const CarlaPluginInfo* carla_get_plugin_info(uint pluginId)
  975. {
  976. carla_debug("carla_get_plugin_info(%i)", pluginId);
  977. static CarlaPluginInfo info;
  978. // reset
  979. info.type = CB::PLUGIN_NONE;
  980. info.category = CB::PLUGIN_CATEGORY_NONE;
  981. info.hints = 0x0;
  982. info.optionsAvailable = 0x0;
  983. info.optionsEnabled = 0x0;
  984. info.filename = gNullCharPtr;
  985. info.name = gNullCharPtr;
  986. info.iconName = gNullCharPtr;
  987. info.uniqueId = 0;
  988. // cleanup
  989. if (info.label != gNullCharPtr)
  990. {
  991. delete[] info.label;
  992. info.label = gNullCharPtr;
  993. }
  994. if (info.maker != gNullCharPtr)
  995. {
  996. delete[] info.maker;
  997. info.maker = gNullCharPtr;
  998. }
  999. if (info.copyright != gNullCharPtr)
  1000. {
  1001. delete[] info.copyright;
  1002. info.copyright = gNullCharPtr;
  1003. }
  1004. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1005. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1006. {
  1007. char strBufLabel[STR_MAX+1];
  1008. char strBufMaker[STR_MAX+1];
  1009. char strBufCopyright[STR_MAX+1];
  1010. carla_zeroChar(strBufLabel, STR_MAX+1);
  1011. carla_zeroChar(strBufMaker, STR_MAX+1);
  1012. carla_zeroChar(strBufCopyright, STR_MAX+1);
  1013. info.type = plugin->getType();
  1014. info.category = plugin->getCategory();
  1015. info.hints = plugin->getHints();
  1016. info.filename = plugin->getFilename();
  1017. info.name = plugin->getName();
  1018. info.iconName = plugin->getIconName();
  1019. info.uniqueId = plugin->getUniqueId();
  1020. info.optionsAvailable = plugin->getOptionsAvailable();
  1021. info.optionsEnabled = plugin->getOptionsEnabled();
  1022. plugin->getLabel(strBufLabel);
  1023. info.label = carla_strdup_safe(strBufLabel);
  1024. plugin->getMaker(strBufMaker);
  1025. info.maker = carla_strdup_safe(strBufMaker);
  1026. plugin->getCopyright(strBufCopyright);
  1027. info.copyright = carla_strdup_safe(strBufCopyright);
  1028. checkStringPtr(info.filename);
  1029. checkStringPtr(info.name);
  1030. checkStringPtr(info.iconName);
  1031. checkStringPtr(info.label);
  1032. checkStringPtr(info.maker);
  1033. checkStringPtr(info.copyright);
  1034. return &info;
  1035. }
  1036. carla_stderr2("carla_get_plugin_info(%i) - could not find plugin", pluginId);
  1037. return &info;
  1038. }
  1039. const CarlaPortCountInfo* carla_get_audio_port_count_info(uint pluginId)
  1040. {
  1041. carla_debug("carla_get_audio_port_count_info(%i)", pluginId);
  1042. static CarlaPortCountInfo info;
  1043. // reset
  1044. info.ins = 0;
  1045. info.outs = 0;
  1046. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1047. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1048. {
  1049. info.ins = plugin->getAudioInCount();
  1050. info.outs = plugin->getAudioOutCount();
  1051. return &info;
  1052. }
  1053. carla_stderr2("carla_get_audio_port_count_info(%i) - could not find plugin", pluginId);
  1054. return &info;
  1055. }
  1056. const CarlaPortCountInfo* carla_get_midi_port_count_info(uint pluginId)
  1057. {
  1058. carla_debug("carla_get_midi_port_count_info(%i)", pluginId);
  1059. static CarlaPortCountInfo info;
  1060. // reset
  1061. info.ins = 0;
  1062. info.outs = 0;
  1063. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1064. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1065. {
  1066. info.ins = plugin->getMidiInCount();
  1067. info.outs = plugin->getMidiOutCount();
  1068. return &info;
  1069. }
  1070. carla_stderr2("carla_get_midi_port_count_info(%i) - could not find plugin", pluginId);
  1071. return &info;
  1072. }
  1073. const CarlaPortCountInfo* carla_get_parameter_count_info(uint pluginId)
  1074. {
  1075. carla_debug("carla_get_parameter_count_info(%i)", pluginId);
  1076. static CarlaPortCountInfo info;
  1077. // reset
  1078. info.ins = 0;
  1079. info.outs = 0;
  1080. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1081. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1082. {
  1083. plugin->getParameterCountInfo(info.ins, info.outs);
  1084. return &info;
  1085. }
  1086. carla_stderr2("carla_get_parameter_count_info(%i) - could not find plugin", pluginId);
  1087. return &info;
  1088. }
  1089. const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t parameterId)
  1090. {
  1091. carla_debug("carla_get_parameter_info(%i, %i)", pluginId, parameterId);
  1092. static CarlaParameterInfo info;
  1093. // reset
  1094. info.scalePointCount = 0;
  1095. // cleanup
  1096. if (info.name != gNullCharPtr)
  1097. {
  1098. delete[] info.name;
  1099. info.name = gNullCharPtr;
  1100. }
  1101. if (info.symbol != gNullCharPtr)
  1102. {
  1103. delete[] info.symbol;
  1104. info.symbol = gNullCharPtr;
  1105. }
  1106. if (info.unit != gNullCharPtr)
  1107. {
  1108. delete[] info.unit;
  1109. info.unit = gNullCharPtr;
  1110. }
  1111. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1112. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1113. {
  1114. if (parameterId < plugin->getParameterCount())
  1115. {
  1116. char strBufName[STR_MAX+1];
  1117. char strBufSymbol[STR_MAX+1];
  1118. char strBufUnit[STR_MAX+1];
  1119. carla_zeroChar(strBufName, STR_MAX+1);
  1120. carla_zeroChar(strBufSymbol, STR_MAX+1);
  1121. carla_zeroChar(strBufUnit, STR_MAX+1);
  1122. info.scalePointCount = plugin->getParameterScalePointCount(parameterId);
  1123. plugin->getParameterName(parameterId, strBufName);
  1124. info.name = carla_strdup_safe(strBufName);
  1125. plugin->getParameterSymbol(parameterId, strBufSymbol);
  1126. info.symbol = carla_strdup_safe(strBufSymbol);
  1127. plugin->getParameterUnit(parameterId, strBufUnit);
  1128. info.unit = carla_strdup_safe(strBufUnit);
  1129. checkStringPtr(info.name);
  1130. checkStringPtr(info.symbol);
  1131. checkStringPtr(info.unit);
  1132. }
  1133. else
  1134. carla_stderr2("carla_get_parameter_info(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1135. return &info;
  1136. }
  1137. carla_stderr2("carla_get_parameter_info(%i, %i) - could not find plugin", pluginId, parameterId);
  1138. return &info;
  1139. }
  1140. const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, uint32_t parameterId, uint32_t scalePointId)
  1141. {
  1142. carla_debug("carla_get_parameter_scalepoint_info(%i, %i, %i)", pluginId, parameterId, scalePointId);
  1143. CARLA_ASSERT(gStandalone.engine != nullptr);
  1144. static CarlaScalePointInfo info;
  1145. // reset
  1146. info.value = 0.0f;
  1147. // cleanup
  1148. if (info.label != gNullCharPtr)
  1149. {
  1150. delete[] info.label;
  1151. info.label = gNullCharPtr;
  1152. }
  1153. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1154. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1155. {
  1156. if (parameterId < plugin->getParameterCount())
  1157. {
  1158. if (scalePointId < plugin->getParameterScalePointCount(parameterId))
  1159. {
  1160. char strBufLabel[STR_MAX+1];
  1161. carla_zeroChar(strBufLabel, STR_MAX+1);
  1162. info.value = plugin->getParameterScalePointValue(parameterId, scalePointId);
  1163. plugin->getParameterScalePointLabel(parameterId, scalePointId, strBufLabel);
  1164. info.label = carla_strdup_safe(strBufLabel);
  1165. checkStringPtr(info.label);
  1166. }
  1167. else
  1168. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - scalePointId out of bounds", pluginId, parameterId, scalePointId);
  1169. }
  1170. else
  1171. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, scalePointId);
  1172. return &info;
  1173. }
  1174. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - could not find plugin", pluginId, parameterId, scalePointId);
  1175. return &info;
  1176. }
  1177. // -------------------------------------------------------------------------------------------------------------------
  1178. const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterId)
  1179. {
  1180. carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId);
  1181. static const ParameterData fallbackParameterData = { CB::PARAMETER_UNKNOWN, 0x0, CB::PARAMETER_NULL, -1, -1, 0 };
  1182. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParameterData);
  1183. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1184. {
  1185. if (parameterId < plugin->getParameterCount())
  1186. return &plugin->getParameterData(parameterId);
  1187. carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1188. return &fallbackParameterData;
  1189. }
  1190. carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId);
  1191. return &fallbackParameterData;
  1192. }
  1193. const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId)
  1194. {
  1195. carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId);
  1196. static const ParameterRanges fallbackParamRanges = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f };
  1197. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges);
  1198. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1199. {
  1200. if (parameterId < plugin->getParameterCount())
  1201. return &plugin->getParameterRanges(parameterId);
  1202. carla_stderr2("carla_get_parameter_ranges(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1203. return &fallbackParamRanges;
  1204. }
  1205. carla_stderr2("carla_get_parameter_ranges(%i, %i) - could not find plugin", pluginId, parameterId);
  1206. return &fallbackParamRanges;
  1207. }
  1208. const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiProgramId)
  1209. {
  1210. carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId);
  1211. static MidiProgramData midiProgData;
  1212. // reset
  1213. midiProgData.bank = 0;
  1214. midiProgData.program = 0;
  1215. midiProgData.name = gNullCharPtr;
  1216. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &midiProgData);
  1217. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1218. {
  1219. if (midiProgramId < plugin->getMidiProgramCount())
  1220. {
  1221. const MidiProgramData& ret(plugin->getMidiProgramData(midiProgramId));
  1222. carla_copyStruct<MidiProgramData>(midiProgData, ret);
  1223. checkStringPtr(midiProgData.name);
  1224. return &midiProgData;
  1225. }
  1226. carla_stderr2("carla_get_midi_program_data(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1227. return &midiProgData;
  1228. }
  1229. carla_stderr2("carla_get_midi_program_data(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1230. return &midiProgData;
  1231. }
  1232. const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId)
  1233. {
  1234. carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId);
  1235. static CustomData customData;
  1236. // reset
  1237. customData.type = gNullCharPtr;
  1238. customData.key = gNullCharPtr;
  1239. customData.value = gNullCharPtr;
  1240. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &customData);
  1241. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1242. {
  1243. if (customDataId < plugin->getCustomDataCount())
  1244. {
  1245. const CustomData& ret(plugin->getCustomData(customDataId));
  1246. carla_copyStruct<CustomData>(customData, ret);
  1247. checkStringPtr(customData.type);
  1248. checkStringPtr(customData.key);
  1249. checkStringPtr(customData.value);
  1250. return &customData;
  1251. }
  1252. carla_stderr2("carla_get_custom_data(%i, %i) - customDataId out of bounds", pluginId, customDataId);
  1253. return &customData;
  1254. }
  1255. carla_stderr2("carla_get_custom_data(%i, %i) - could not find plugin", pluginId, customDataId);
  1256. return &customData;
  1257. }
  1258. const char* carla_get_chunk_data(uint pluginId)
  1259. {
  1260. carla_debug("carla_get_chunk_data(%i)", pluginId);
  1261. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1262. static CarlaString chunkData;
  1263. // cleanup
  1264. chunkData.clear();
  1265. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1266. {
  1267. if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS)
  1268. {
  1269. void* data = nullptr;
  1270. const std::size_t dataSize(plugin->getChunkData(&data));
  1271. if (data != nullptr && dataSize > 0)
  1272. {
  1273. chunkData = CarlaString::asBase64(data, static_cast<std::size_t>(dataSize));
  1274. return chunkData;
  1275. }
  1276. else
  1277. carla_stderr2("carla_get_chunk_data(%i) - got invalid chunk data", pluginId);
  1278. }
  1279. else
  1280. carla_stderr2("carla_get_chunk_data(%i) - plugin does not use chunks", pluginId);
  1281. return nullptr;
  1282. }
  1283. carla_stderr2("carla_get_chunk_data(%i) - could not find plugin", pluginId);
  1284. return nullptr;
  1285. }
  1286. // -------------------------------------------------------------------------------------------------------------------
  1287. uint32_t carla_get_parameter_count(uint pluginId)
  1288. {
  1289. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1290. carla_debug("carla_get_parameter_count(%i)", pluginId);
  1291. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1292. return plugin->getParameterCount();
  1293. carla_stderr2("carla_get_parameter_count(%i) - could not find plugin", pluginId);
  1294. return 0;
  1295. }
  1296. uint32_t carla_get_program_count(uint pluginId)
  1297. {
  1298. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1299. carla_debug("carla_get_program_count(%i)", pluginId);
  1300. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1301. return plugin->getProgramCount();
  1302. carla_stderr2("carla_get_program_count(%i) - could not find plugin", pluginId);
  1303. return 0;
  1304. }
  1305. uint32_t carla_get_midi_program_count(uint pluginId)
  1306. {
  1307. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1308. carla_debug("carla_get_midi_program_count(%i)", pluginId);
  1309. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1310. return plugin->getMidiProgramCount();
  1311. carla_stderr2("carla_get_midi_program_count(%i) - could not find plugin", pluginId);
  1312. return 0;
  1313. }
  1314. uint32_t carla_get_custom_data_count(uint pluginId)
  1315. {
  1316. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1317. carla_debug("carla_get_custom_data_count(%i)", pluginId);
  1318. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1319. return plugin->getCustomDataCount();
  1320. carla_stderr2("carla_get_custom_data_count(%i) - could not find plugin", pluginId);
  1321. return 0;
  1322. }
  1323. // -------------------------------------------------------------------------------------------------------------------
  1324. const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId)
  1325. {
  1326. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1327. carla_debug("carla_get_parameter_text(%i, %i)", pluginId, parameterId);
  1328. static char textBuf[STR_MAX+1];
  1329. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1330. {
  1331. if (parameterId < plugin->getParameterCount())
  1332. {
  1333. carla_zeroChar(textBuf, STR_MAX+1);
  1334. plugin->getParameterText(parameterId, textBuf);
  1335. return textBuf;
  1336. }
  1337. carla_stderr2("carla_get_parameter_text(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1338. return nullptr;
  1339. }
  1340. carla_stderr2("carla_get_parameter_text(%i, %i) - could not find plugin", pluginId, parameterId);
  1341. return nullptr;
  1342. }
  1343. const char* carla_get_program_name(uint pluginId, uint32_t programId)
  1344. {
  1345. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1346. carla_debug("carla_get_program_name(%i, %i)", pluginId, programId);
  1347. static char programName[STR_MAX+1];
  1348. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1349. {
  1350. if (programId < plugin->getProgramCount())
  1351. {
  1352. carla_zeroChar(programName, STR_MAX+1);
  1353. plugin->getProgramName(programId, programName);
  1354. return programName;
  1355. }
  1356. carla_stderr2("carla_get_program_name(%i, %i) - programId out of bounds", pluginId, programId);
  1357. return nullptr;
  1358. }
  1359. carla_stderr2("carla_get_program_name(%i, %i) - could not find plugin", pluginId, programId);
  1360. return nullptr;
  1361. }
  1362. const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId)
  1363. {
  1364. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1365. carla_debug("carla_get_midi_program_name(%i, %i)", pluginId, midiProgramId);
  1366. static char midiProgramName[STR_MAX+1];
  1367. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1368. {
  1369. if (midiProgramId < plugin->getMidiProgramCount())
  1370. {
  1371. carla_zeroChar(midiProgramName, STR_MAX+1);
  1372. plugin->getMidiProgramName(midiProgramId, midiProgramName);
  1373. return midiProgramName;
  1374. }
  1375. carla_stderr2("carla_get_midi_program_name(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1376. return nullptr;
  1377. }
  1378. carla_stderr2("carla_get_midi_program_name(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1379. return nullptr;
  1380. }
  1381. const char* carla_get_real_plugin_name(uint pluginId)
  1382. {
  1383. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1384. carla_debug("carla_get_real_plugin_name(%i)", pluginId);
  1385. static char realPluginName[STR_MAX+1];
  1386. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1387. {
  1388. carla_zeroChar(realPluginName, STR_MAX+1);
  1389. plugin->getRealName(realPluginName);
  1390. return realPluginName;
  1391. }
  1392. carla_stderr2("carla_get_real_plugin_name(%i) - could not find plugin", pluginId);
  1393. return nullptr;
  1394. }
  1395. // -------------------------------------------------------------------------------------------------------------------
  1396. int32_t carla_get_current_program_index(uint pluginId)
  1397. {
  1398. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1);
  1399. carla_debug("carla_get_current_program_index(%i)", pluginId);
  1400. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1401. return plugin->getCurrentProgram();
  1402. carla_stderr2("carla_get_current_program_index(%i) - could not find plugin", pluginId);
  1403. return -1;
  1404. }
  1405. int32_t carla_get_current_midi_program_index(uint pluginId)
  1406. {
  1407. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1);
  1408. carla_debug("carla_get_current_midi_program_index(%i)", pluginId);
  1409. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1410. return plugin->getCurrentMidiProgram();
  1411. carla_stderr2("carla_get_current_midi_program_index(%i) - could not find plugin", pluginId);
  1412. return -1;
  1413. }
  1414. // -------------------------------------------------------------------------------------------------------------------
  1415. float carla_get_default_parameter_value(uint pluginId, uint32_t parameterId)
  1416. {
  1417. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1418. carla_debug("carla_get_default_parameter_value(%i, %i)", pluginId, parameterId);
  1419. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1420. {
  1421. if (parameterId < plugin->getParameterCount())
  1422. return plugin->getParameterRanges(parameterId).def;
  1423. carla_stderr2("carla_get_default_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1424. return 0.0f;
  1425. }
  1426. carla_stderr2("carla_get_default_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1427. return 0.0f;
  1428. }
  1429. float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId)
  1430. {
  1431. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1432. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1433. {
  1434. if (parameterId < plugin->getParameterCount())
  1435. return plugin->getParameterValue(parameterId);
  1436. carla_stderr2("carla_get_current_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1437. return 0.0f;
  1438. }
  1439. carla_stderr2("carla_get_current_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1440. return 0.0f;
  1441. }
  1442. float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId)
  1443. {
  1444. #ifdef BUILD_BRIDGE
  1445. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1446. #else
  1447. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, (parameterId == CB::PARAMETER_CTRL_CHANNEL) ? -1.0f : 0.0f);
  1448. #endif
  1449. CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f);
  1450. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1451. return plugin->getInternalParameterValue(parameterId);
  1452. carla_stderr2("carla_get_internal_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1453. return 0.0f;
  1454. }
  1455. // -------------------------------------------------------------------------------------------------------------------
  1456. float carla_get_input_peak_value(uint pluginId, bool isLeft)
  1457. {
  1458. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1459. return gStandalone.engine->getInputPeak(pluginId, isLeft);
  1460. }
  1461. float carla_get_output_peak_value(uint pluginId, bool isLeft)
  1462. {
  1463. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1464. return gStandalone.engine->getOutputPeak(pluginId, isLeft);
  1465. }
  1466. // -------------------------------------------------------------------------------------------------------------------
  1467. void carla_set_active(uint pluginId, bool onOff)
  1468. {
  1469. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1470. carla_debug("carla_set_active(%i, %s)", pluginId, bool2str(onOff));
  1471. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1472. return plugin->setActive(onOff, true, false);
  1473. carla_stderr2("carla_set_active(%i, %s) - could not find plugin", pluginId, bool2str(onOff));
  1474. }
  1475. #ifndef BUILD_BRIDGE
  1476. void carla_set_drywet(uint pluginId, float value)
  1477. {
  1478. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1479. carla_debug("carla_set_drywet(%i, %f)", pluginId, value);
  1480. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1481. return plugin->setDryWet(value, true, false);
  1482. carla_stderr2("carla_set_drywet(%i, %f) - could not find plugin", pluginId, value);
  1483. }
  1484. void carla_set_volume(uint pluginId, float value)
  1485. {
  1486. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1487. carla_debug("carla_set_volume(%i, %f)", pluginId, value);
  1488. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1489. return plugin->setVolume(value, true, false);
  1490. carla_stderr2("carla_set_volume(%i, %f) - could not find plugin", pluginId, value);
  1491. }
  1492. void carla_set_balance_left(uint pluginId, float value)
  1493. {
  1494. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1495. carla_debug("carla_set_balance_left(%i, %f)", pluginId, value);
  1496. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1497. return plugin->setBalanceLeft(value, true, false);
  1498. carla_stderr2("carla_set_balance_left(%i, %f) - could not find plugin", pluginId, value);
  1499. }
  1500. void carla_set_balance_right(uint pluginId, float value)
  1501. {
  1502. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1503. carla_debug("carla_set_balance_right(%i, %f)", pluginId, value);
  1504. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1505. return plugin->setBalanceRight(value, true, false);
  1506. carla_stderr2("carla_set_balance_right(%i, %f) - could not find plugin", pluginId, value);
  1507. }
  1508. void carla_set_panning(uint pluginId, float value)
  1509. {
  1510. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1511. carla_debug("carla_set_panning(%i, %f)", pluginId, value);
  1512. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1513. return plugin->setPanning(value, true, false);
  1514. carla_stderr2("carla_set_panning(%i, %f) - could not find plugin", pluginId, value);
  1515. }
  1516. void carla_set_ctrl_channel(uint pluginId, int8_t channel)
  1517. {
  1518. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1519. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);
  1520. carla_debug("carla_set_ctrl_channel(%i, %i)", pluginId, channel);
  1521. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1522. return plugin->setCtrlChannel(channel, true, false);
  1523. carla_stderr2("carla_set_ctrl_channel(%i, %i) - could not find plugin", pluginId, channel);
  1524. }
  1525. void carla_set_option(uint pluginId, uint option, bool yesNo)
  1526. {
  1527. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1528. carla_debug("carla_set_option(%i, %i, %s)", pluginId, option, bool2str(yesNo));
  1529. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1530. return plugin->setOption(option, yesNo, false);
  1531. carla_stderr2("carla_set_option(%i, %i, %s) - could not find plugin", pluginId, option, bool2str(yesNo));
  1532. }
  1533. #endif
  1534. // -------------------------------------------------------------------------------------------------------------------
  1535. void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value)
  1536. {
  1537. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1538. carla_debug("carla_set_parameter_value(%i, %i, %f)", pluginId, parameterId, value);
  1539. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1540. {
  1541. if (parameterId < plugin->getParameterCount())
  1542. return plugin->setParameterValue(parameterId, value, true, true, false);
  1543. carla_stderr2("carla_set_parameter_value(%i, %i, %f) - parameterId out of bounds", pluginId, parameterId, value);
  1544. return;
  1545. }
  1546. carla_stderr2("carla_set_parameter_value(%i, %i, %f) - could not find plugin", pluginId, parameterId, value);
  1547. }
  1548. #ifndef BUILD_BRIDGE
  1549. void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8_t channel)
  1550. {
  1551. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1552. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1553. carla_debug("carla_set_parameter_midi_channel(%i, %i, %i)", pluginId, parameterId, channel);
  1554. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1555. {
  1556. if (parameterId < plugin->getParameterCount())
  1557. return plugin->setParameterMidiChannel(parameterId, channel, true, false);
  1558. carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, channel);
  1559. return;
  1560. }
  1561. carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - could not find plugin", pluginId, parameterId, channel);
  1562. }
  1563. void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc)
  1564. {
  1565. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1566. CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,);
  1567. carla_debug("carla_set_parameter_midi_cc(%i, %i, %i)", pluginId, parameterId, cc);
  1568. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1569. {
  1570. if (parameterId < plugin->getParameterCount())
  1571. return plugin->setParameterMidiCC(parameterId, cc, true, false);
  1572. carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, cc);
  1573. return;
  1574. }
  1575. carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - could not find plugin", pluginId, parameterId, cc);
  1576. }
  1577. #endif
  1578. // -------------------------------------------------------------------------------------------------------------------
  1579. void carla_set_program(uint pluginId, uint32_t programId)
  1580. {
  1581. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1582. carla_debug("carla_set_program(%i, %i)", pluginId, programId);
  1583. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1584. {
  1585. if (programId < plugin->getProgramCount())
  1586. return plugin->setProgram(static_cast<int32_t>(programId), true, true, false);
  1587. carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId);
  1588. return;
  1589. }
  1590. carla_stderr2("carla_set_program(%i, %i) - could not find plugin", pluginId, programId);
  1591. }
  1592. void carla_set_midi_program(uint pluginId, uint32_t midiProgramId)
  1593. {
  1594. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1595. carla_debug("carla_set_midi_program(%i, %i)", pluginId, midiProgramId);
  1596. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1597. {
  1598. if (midiProgramId < plugin->getMidiProgramCount())
  1599. return plugin->setMidiProgram(static_cast<int32_t>(midiProgramId), true, true, false);
  1600. carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1601. return;
  1602. }
  1603. carla_stderr2("carla_set_midi_program(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1604. }
  1605. // -------------------------------------------------------------------------------------------------------------------
  1606. void carla_set_custom_data(uint pluginId, const char* type, const char* key, const char* value)
  1607. {
  1608. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1609. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  1610. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  1611. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  1612. carla_debug("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\")", pluginId, type, key, value);
  1613. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1614. return plugin->setCustomData(type, key, value, true);
  1615. carla_stderr2("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\") - could not find plugin", pluginId, type, key, value);
  1616. }
  1617. void carla_set_chunk_data(uint pluginId, const char* chunkData)
  1618. {
  1619. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1620. CARLA_SAFE_ASSERT_RETURN(chunkData != nullptr && chunkData[0] != '\0',);
  1621. carla_debug("carla_set_chunk_data(%i, \"%s\")", pluginId, chunkData);
  1622. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1623. {
  1624. if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS)
  1625. {
  1626. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(chunkData));
  1627. return plugin->setChunkData(chunk.data(), chunk.size());
  1628. }
  1629. carla_stderr2("carla_set_chunk_data(%i, \"%s\") - plugin does not use chunks", pluginId, chunkData);
  1630. return;
  1631. }
  1632. carla_stderr2("carla_set_chunk_data(%i, \"%s\") - could not find plugin", pluginId, chunkData);
  1633. }
  1634. // -------------------------------------------------------------------------------------------------------------------
  1635. void carla_prepare_for_save(uint pluginId)
  1636. {
  1637. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1638. carla_debug("carla_prepare_for_save(%i)", pluginId);
  1639. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1640. return plugin->prepareForSave();
  1641. carla_stderr2("carla_prepare_for_save(%i) - could not find plugin", pluginId);
  1642. }
  1643. void carla_reset_parameters(uint pluginId)
  1644. {
  1645. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1646. carla_debug("carla_reset_parameters(%i)", pluginId);
  1647. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1648. return plugin->resetParameters();
  1649. carla_stderr2("carla_reset_parameters(%i) - could not find plugin", pluginId);
  1650. }
  1651. void carla_randomize_parameters(uint pluginId)
  1652. {
  1653. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1654. carla_debug("carla_randomize_parameters(%i)", pluginId);
  1655. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1656. return plugin->randomizeParameters();
  1657. carla_stderr2("carla_randomize_parameters(%i) - could not find plugin", pluginId);
  1658. }
  1659. #ifndef BUILD_BRIDGE
  1660. void carla_send_midi_note(uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity)
  1661. {
  1662. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  1663. carla_debug("carla_send_midi_note(%i, %i, %i, %i)", pluginId, channel, note, velocity);
  1664. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1665. return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
  1666. carla_stderr2("carla_send_midi_note(%i, %i, %i, %i) - could not find plugin", pluginId, channel, note, velocity);
  1667. }
  1668. #endif
  1669. void carla_show_custom_ui(uint pluginId, bool yesNo)
  1670. {
  1671. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1672. carla_debug("carla_show_custom_ui(%i, %s)", pluginId, bool2str(yesNo));
  1673. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1674. return plugin->showCustomUI(yesNo);
  1675. carla_stderr2("carla_show_custom_ui(%i, %s) - could not find plugin", pluginId, bool2str(yesNo));
  1676. }
  1677. // -------------------------------------------------------------------------------------------------------------------
  1678. uint32_t carla_get_buffer_size()
  1679. {
  1680. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1681. carla_debug("carla_get_buffer_size()");
  1682. return gStandalone.engine->getBufferSize();
  1683. }
  1684. double carla_get_sample_rate()
  1685. {
  1686. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0);
  1687. carla_debug("carla_get_sample_rate()");
  1688. return gStandalone.engine->getSampleRate();
  1689. }
  1690. // -------------------------------------------------------------------------------------------------------------------
  1691. const char* carla_get_last_error()
  1692. {
  1693. carla_debug("carla_get_last_error()");
  1694. if (gStandalone.engine != nullptr)
  1695. return gStandalone.engine->getLastError();
  1696. return gStandalone.lastError;
  1697. }
  1698. const char* carla_get_host_osc_url_tcp()
  1699. {
  1700. carla_debug("carla_get_host_osc_url_tcp()");
  1701. #ifdef HAVE_LIBLO
  1702. if (gStandalone.engine == nullptr)
  1703. {
  1704. carla_stderr2("Engine is not running");
  1705. gStandalone.lastError = "Engine is not running";
  1706. return nullptr;
  1707. }
  1708. return gStandalone.engine->getOscServerPathTCP();
  1709. #else
  1710. return nullptr;
  1711. #endif
  1712. }
  1713. const char* carla_get_host_osc_url_udp()
  1714. {
  1715. carla_debug("carla_get_host_osc_url_udp()");
  1716. #ifdef HAVE_LIBLO
  1717. if (gStandalone.engine == nullptr)
  1718. {
  1719. carla_stderr2("Engine is not running");
  1720. gStandalone.lastError = "Engine is not running";
  1721. return nullptr;
  1722. }
  1723. return gStandalone.engine->getOscServerPathUDP();
  1724. #else
  1725. return nullptr;
  1726. #endif
  1727. }
  1728. // -------------------------------------------------------------------------------------------------------------------
  1729. bool carla_nsm_init(int pid, const char* executableName)
  1730. {
  1731. #ifdef HAVE_LIBLO
  1732. return CarlaNSM::getInstance().announce(pid, executableName);
  1733. #else
  1734. return false;
  1735. // unused
  1736. (void)pid; (void)executableName;
  1737. #endif
  1738. }
  1739. void carla_nsm_ready()
  1740. {
  1741. #ifdef HAVE_LIBLO
  1742. CarlaNSM::getInstance().start();
  1743. #endif
  1744. }
  1745. // -------------------------------------------------------------------------------------------------------------------
  1746. #include "CarlaPluginUI.cpp"
  1747. #include "CarlaDssiUtils.cpp"
  1748. #include "CarlaPatchbayUtils.cpp"
  1749. #include "CarlaPipeUtils.cpp"
  1750. #include "CarlaStateUtils.cpp"
  1751. #include "CarlaJuceEvents.cpp"
  1752. // -------------------------------------------------------------------------------------------------------------------