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.

2300 lines
72KB

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