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

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