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.

2418 lines
79KB

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