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.

2387 lines
77KB

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