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.

CarlaStandalone.cpp 74KB

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