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

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