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 77KB

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