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.

1935 lines
69KB

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