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.

2127 lines
76KB

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