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.

CarlaEngineNative.cpp 110KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2023 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 "CarlaDefines.h"
  18. #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
  19. # error This file should not be compiled if building alternative-arch bridges
  20. #endif
  21. #ifdef CARLA_OS_WASM
  22. # define CARLA_ENGINE_WITHOUT_UI
  23. #endif
  24. #include "CarlaEngineInit.hpp"
  25. #include "CarlaEngineInternal.hpp"
  26. #include "CarlaPlugin.hpp"
  27. #include "CarlaBackendUtils.hpp"
  28. #include "CarlaBase64Utils.hpp"
  29. #include "CarlaBinaryUtils.hpp"
  30. #include "CarlaMathUtils.hpp"
  31. #include "CarlaStateUtils.hpp"
  32. #include "CarlaExternalUI.hpp"
  33. #include "CarlaHost.h"
  34. #include "CarlaNative.hpp"
  35. #include "CarlaNativePlugin.h"
  36. #include "water/files/File.h"
  37. #include "water/streams/MemoryOutputStream.h"
  38. #include "water/xml/XmlDocument.h"
  39. #include "water/xml/XmlElement.h"
  40. #ifdef CARLA_OS_WIN
  41. # include <direct.h>
  42. #endif
  43. #ifdef USING_JUCE
  44. # include "carla_juce/carla_juce.h"
  45. #endif
  46. using water::File;
  47. using water::MemoryOutputStream;
  48. using water::String;
  49. using water::XmlDocument;
  50. using water::XmlElement;
  51. CARLA_BACKEND_START_NAMESPACE
  52. static const uint32_t kNumInParams = 100;
  53. static const uint32_t kNumOutParams = 10;
  54. static const uint16_t kUiWidth = 1024;
  55. static const uint16_t kUiHeight = 712;
  56. // -----------------------------------------------------------------------
  57. #ifndef CARLA_ENGINE_WITHOUT_UI
  58. class CarlaEngineNative;
  59. class CarlaEngineNativeUI : public CarlaExternalUI
  60. {
  61. public:
  62. CarlaEngineNativeUI(CarlaEngineNative* const engine)
  63. : fEngine(engine)
  64. {
  65. carla_debug("CarlaEngineNativeUI::CarlaEngineNativeUI(%p)", engine);
  66. }
  67. ~CarlaEngineNativeUI() noexcept override
  68. {
  69. carla_debug("CarlaEngineNativeUI::~CarlaEngineNativeUI()");
  70. }
  71. protected:
  72. bool msgReceived(const char* const msg) noexcept override;
  73. private:
  74. CarlaEngineNative* const fEngine;
  75. void _updateParamValues(const CarlaPluginPtr& plugin,
  76. uint32_t pluginId,
  77. bool sendCallback, bool sendPluginHost) const noexcept;
  78. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeUI)
  79. };
  80. #endif
  81. // -----------------------------------------------------------------------
  82. class CarlaEngineNative : public CarlaEngine
  83. {
  84. public:
  85. CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay,
  86. const bool withMidiIn, const bool withMidiOut,
  87. const uint32_t inChan = 2, uint32_t outChan = 2,
  88. const uint32_t cvIns = 0, const uint32_t cvOuts = 0)
  89. : CarlaEngine(),
  90. pHost(host),
  91. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  92. // if not running inside Carla, we will have to run event loop ourselves
  93. kNeedsJuceEvents(host->dispatcher(pHost->handle,
  94. NATIVE_HOST_OPCODE_INTERNAL_PLUGIN, 0, 0, nullptr, 0.0f) == 0),
  95. fJuceMsgMgr(),
  96. fJuceMsgMutex(),
  97. #endif
  98. kIsPatchbay(isPatchbay),
  99. kHasMidiIn(withMidiIn),
  100. kHasMidiOut(withMidiOut),
  101. fIsActive(false),
  102. fIsRunning(false),
  103. fUsesEmbed(false),
  104. #ifndef CARLA_ENGINE_WITHOUT_UI
  105. fUiServer(this),
  106. #endif
  107. fLastScaleFactor(1.0f),
  108. fLastProjectFolder(),
  109. fPluginDeleterMutex(),
  110. fOptionsForced(false)
  111. {
  112. carla_debug("CarlaEngineNative::CarlaEngineNative()");
  113. carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
  114. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  115. if (kNeedsJuceEvents)
  116. fJuceMsgMgr.incRef();
  117. #endif
  118. pData->bufferSize = pHost->get_buffer_size(pHost->handle);
  119. pData->sampleRate = pHost->get_sample_rate(pHost->handle);
  120. pData->initTime(nullptr);
  121. #ifndef BUILD_BRIDGE
  122. // Forced OSC setup when running as plugin
  123. pData->options.oscEnabled = true;
  124. pData->options.oscPortTCP = -1;
  125. pData->options.oscPortUDP = 0;
  126. #endif
  127. if (outChan == 0)
  128. outChan = inChan;
  129. // set-up engine
  130. if (kIsPatchbay)
  131. {
  132. pData->options.processMode = ENGINE_PROCESS_MODE_PATCHBAY;
  133. pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
  134. pData->options.forceStereo = false;
  135. pData->options.preferPluginBridges = false;
  136. pData->options.preferUiBridges = false;
  137. init("Carla-Patchbay");
  138. pData->graph.create(inChan, outChan, cvIns, cvOuts, withMidiIn, withMidiOut);
  139. }
  140. else
  141. {
  142. CARLA_SAFE_ASSERT(inChan == 2);
  143. CARLA_SAFE_ASSERT(outChan == 2);
  144. pData->options.processMode = ENGINE_PROCESS_MODE_CONTINUOUS_RACK;
  145. pData->options.transportMode = ENGINE_TRANSPORT_MODE_PLUGIN;
  146. pData->options.forceStereo = true;
  147. pData->options.preferPluginBridges = false;
  148. pData->options.preferUiBridges = false;
  149. init("Carla-Rack");
  150. pData->graph.create(0, 0, 0, 0); // FIXME?
  151. }
  152. if (pData->options.resourceDir != nullptr)
  153. delete[] pData->options.resourceDir;
  154. if (pData->options.binaryDir != nullptr)
  155. delete[] pData->options.binaryDir;
  156. const water::String binaryDir(File(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory()).getFullPathName());
  157. pData->options.resourceDir = carla_strdup(pHost->resourceDir);
  158. pData->options.binaryDir = carla_strdup(binaryDir.toRawUTF8());
  159. }
  160. ~CarlaEngineNative() override
  161. {
  162. CARLA_SAFE_ASSERT(! fIsActive);
  163. carla_debug("CarlaEngineNative::~CarlaEngineNative() - START");
  164. pData->aboutToClose = true;
  165. fIsRunning = false;
  166. {
  167. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  168. const ScopedJuceMessageThreadRunner sjmtr(*this, true);
  169. #endif
  170. removeAllPlugins();
  171. //runPendingRtEvents();
  172. close();
  173. pData->graph.destroy();
  174. }
  175. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  176. if (kNeedsJuceEvents)
  177. fJuceMsgMgr.decRef();
  178. #endif
  179. carla_debug("CarlaEngineNative::~CarlaEngineNative() - END");
  180. }
  181. // -------------------------------------
  182. // CarlaEngine virtual calls
  183. bool init(const char* const clientName) override
  184. {
  185. carla_debug("CarlaEngineNative::init(\"%s\")", clientName);
  186. fIsRunning = true;
  187. if (! pData->init(clientName))
  188. {
  189. close();
  190. setLastError("Failed to init internal data");
  191. return false;
  192. }
  193. pData->bufferSize = pHost->get_buffer_size(pHost->handle);
  194. pData->sampleRate = pHost->get_sample_rate(pHost->handle);
  195. return true;
  196. }
  197. bool close() override
  198. {
  199. fIsRunning = false;
  200. CarlaEngine::close();
  201. return true;
  202. }
  203. bool hasIdleOnMainThread() const noexcept override
  204. {
  205. return false;
  206. }
  207. bool isRunning() const noexcept override
  208. {
  209. return fIsRunning;
  210. }
  211. bool isOffline() const noexcept override
  212. {
  213. return pHost->is_offline(pHost->handle);
  214. }
  215. bool usesConstantBufferSize() const noexcept override
  216. {
  217. // TODO LV2 hosts can report this, till then we allow this
  218. return true;
  219. }
  220. EngineType getType() const noexcept override
  221. {
  222. return kEngineTypePlugin;
  223. }
  224. const char* getCurrentDriverName() const noexcept override
  225. {
  226. return "Plugin";
  227. }
  228. const char* getCurrentProjectFolder() const noexcept override
  229. {
  230. CARLA_SAFE_ASSERT_RETURN(pHost != nullptr, nullptr);
  231. static char filetype[] = "carla\0";
  232. try {
  233. return (const char*)(uintptr_t)pHost->dispatcher(pHost->handle,
  234. NATIVE_HOST_OPCODE_GET_FILE_PATH,
  235. 0, 0,
  236. (void*)filetype,
  237. 0.0f);
  238. } CARLA_SAFE_EXCEPTION_RETURN("get_file_path", nullptr);
  239. }
  240. void callback(const bool sendHost, const bool sendOsc,
  241. const EngineCallbackOpcode action, const uint pluginId,
  242. const int value1, const int value2, const int value3,
  243. const float valuef, const char* const valueStr) noexcept override
  244. {
  245. CarlaEngine::callback(sendHost, sendOsc, action, pluginId, value1, value2, value3, valuef, valueStr);
  246. #ifndef CARLA_ENGINE_WITHOUT_UI
  247. if (sendHost)
  248. uiServerCallback(action, pluginId, value1, value2, value3, valuef, valueStr);
  249. #endif
  250. switch (action)
  251. {
  252. case ENGINE_CALLBACK_IDLE:
  253. if (! pData->aboutToClose)
  254. pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_HOST_IDLE, 0, 0, nullptr, 0.0f);
  255. break;
  256. case ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED:
  257. if (sendHost && value1 >= 0)
  258. {
  259. uint32_t rindex = static_cast<uint32_t>(value1);
  260. if (_getRealIndexForPluginParameter(pluginId, rindex))
  261. {
  262. fParameters[rindex] = valuef;
  263. if (fUsesEmbed
  264. #ifndef CARLA_ENGINE_WITHOUT_UI
  265. || fUiServer.isPipeRunning()
  266. #endif
  267. )
  268. {
  269. pHost->ui_parameter_changed(pHost->handle, rindex, valuef);
  270. }
  271. else
  272. {
  273. static uint last_pluginId = pluginId;
  274. static int last_value1 = value1;
  275. static bool init = true;
  276. if (init || last_pluginId != pluginId || last_value1 != value1)
  277. {
  278. init = false;
  279. last_pluginId = pluginId;
  280. last_value1 = value1;
  281. carla_stdout("Plugin with id %d triggered parameter %d update while UI is hidden",
  282. pluginId, value1);
  283. }
  284. }
  285. }
  286. }
  287. break;
  288. case ENGINE_CALLBACK_UI_STATE_CHANGED:
  289. if (sendHost && fUsesEmbed)
  290. pHost->ui_closed(pHost->handle);
  291. break;
  292. default:
  293. break;
  294. }
  295. }
  296. const char* runFileCallback(FileCallbackOpcode action,
  297. bool isDir, const char* title, const char* filter) noexcept override
  298. {
  299. switch (action)
  300. {
  301. case FILE_CALLBACK_DEBUG:
  302. return nullptr;
  303. case FILE_CALLBACK_OPEN:
  304. return pHost->ui_open_file(pHost->handle, isDir, title, filter);
  305. case FILE_CALLBACK_SAVE:
  306. return pHost->ui_save_file(pHost->handle, isDir, title, filter);
  307. }
  308. return nullptr;
  309. }
  310. // -------------------------------------------------------------------
  311. void touchPluginParameter(const uint id, const uint32_t parameterId, const bool touch) noexcept override
  312. {
  313. setParameterTouchFromUI(id, parameterId, touch);
  314. }
  315. // -------------------------------------------------------------------
  316. void setParameterValueFromUI(const uint32_t pluginId, const uint32_t index, const float value)
  317. {
  318. uint32_t rindex = index;
  319. if (_getRealIndexForPluginParameter(pluginId, rindex))
  320. {
  321. fParameters[rindex] = value;
  322. pHost->ui_parameter_changed(pHost->handle, rindex, value);
  323. }
  324. }
  325. void setParameterTouchFromUI(const uint32_t pluginId, const uint32_t index, const bool touch)
  326. {
  327. uint32_t rindex = index;
  328. if (_getRealIndexForPluginParameter(pluginId, rindex))
  329. {
  330. pHost->dispatcher(pHost->handle,
  331. NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER,
  332. static_cast<int32_t>(rindex),
  333. touch ? 1 : 0,
  334. nullptr, 0.0f);
  335. }
  336. }
  337. void reloadFromUI()
  338. {
  339. carla_zeroFloats(fParameters, kNumInParams+kNumOutParams);
  340. pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_RELOAD_PARAMETERS, 0, 0, nullptr, 0.0f);
  341. }
  342. protected:
  343. // -------------------------------------------------------------------
  344. void bufferSizeChanged(const uint32_t newBufferSize)
  345. {
  346. if (pData->bufferSize == newBufferSize)
  347. return;
  348. #ifndef CARLA_ENGINE_WITHOUT_UI
  349. {
  350. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  351. if (fUiServer.writeMessage("buffer-size\n"))
  352. {
  353. char tmpBuf[STR_MAX+1];
  354. carla_zeroChars(tmpBuf, STR_MAX+1);
  355. std::snprintf(tmpBuf, STR_MAX, "%i\n", newBufferSize);
  356. if (fUiServer.writeMessage(tmpBuf))
  357. fUiServer.flushMessages();
  358. }
  359. }
  360. #endif
  361. pData->bufferSize = newBufferSize;
  362. CarlaEngine::bufferSizeChanged(newBufferSize);
  363. }
  364. void sampleRateChanged(const double newSampleRate)
  365. {
  366. if (carla_isEqual(pData->sampleRate, newSampleRate))
  367. return;
  368. #ifndef CARLA_ENGINE_WITHOUT_UI
  369. {
  370. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  371. if (fUiServer.writeMessage("sample-rate\n"))
  372. {
  373. char tmpBuf[STR_MAX+1];
  374. carla_zeroChars(tmpBuf, STR_MAX+1);
  375. {
  376. const CarlaScopedLocale csl;
  377. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", newSampleRate);
  378. }
  379. if (fUiServer.writeMessage(tmpBuf))
  380. fUiServer.flushMessages();
  381. }
  382. }
  383. #endif
  384. pData->sampleRate = newSampleRate;
  385. CarlaEngine::sampleRateChanged(newSampleRate);
  386. }
  387. #ifndef CARLA_ENGINE_WITHOUT_UI
  388. // -------------------------------------------------------------------
  389. void uiServerSendPluginInfo(const CarlaPluginPtr& plugin)
  390. {
  391. char tmpBuf[STR_MAX+1];
  392. carla_zeroChars(tmpBuf, STR_MAX+1);
  393. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  394. const uint pluginId(plugin->getId());
  395. std::snprintf(tmpBuf, STR_MAX, "PLUGIN_INFO_%i\n", pluginId);
  396. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  397. std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:" P_INT64 ":%i:%i\n",
  398. plugin->getType(), plugin->getCategory(),
  399. plugin->getHints(), plugin->getUniqueId(),
  400. plugin->getOptionsAvailable(), plugin->getOptionsEnabled());
  401. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  402. if (const char* const filename = plugin->getFilename())
  403. {
  404. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(filename),);
  405. }
  406. else
  407. {
  408. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  409. }
  410. if (const char* const name = plugin->getName())
  411. {
  412. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(name),);
  413. }
  414. else
  415. {
  416. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  417. }
  418. if (const char* const iconName = plugin->getIconName())
  419. {
  420. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(iconName),);
  421. }
  422. else
  423. {
  424. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  425. }
  426. if (plugin->getRealName(tmpBuf)) {
  427. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  428. } else {
  429. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  430. }
  431. if (plugin->getLabel(tmpBuf)) {
  432. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  433. } else {
  434. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  435. }
  436. if (plugin->getMaker(tmpBuf)) {
  437. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  438. } else {
  439. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  440. }
  441. if (plugin->getCopyright(tmpBuf)) {
  442. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  443. } else {
  444. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  445. }
  446. std::snprintf(tmpBuf, STR_MAX, "AUDIO_COUNT_%i:%i:%i\n",
  447. pluginId, plugin->getAudioInCount(), plugin->getAudioOutCount());
  448. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  449. std::snprintf(tmpBuf, STR_MAX, "MIDI_COUNT_%i:%i:%i\n",
  450. pluginId, plugin->getMidiInCount(), plugin->getMidiOutCount());
  451. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  452. fUiServer.flushMessages();
  453. }
  454. void uiServerSendPluginParameters(const CarlaPluginPtr& plugin)
  455. {
  456. char tmpBuf[STR_MAX+1];
  457. carla_zeroChars(tmpBuf, STR_MAX+1);
  458. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  459. const CarlaScopedLocale csl;
  460. const uint pluginId(plugin->getId());
  461. for (int32_t i=PARAMETER_ACTIVE; i>PARAMETER_MAX; --i)
  462. {
  463. std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%i\n", pluginId, i);
  464. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  465. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getInternalParameterValue(i)));
  466. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  467. fUiServer.flushMessages();
  468. }
  469. uint32_t ins, outs, count;
  470. plugin->getParameterCountInfo(ins, outs);
  471. count = plugin->getParameterCount();
  472. std::snprintf(tmpBuf, STR_MAX, "PARAMETER_COUNT_%i:%i:%i:%i\n", pluginId, ins, outs, count);
  473. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  474. for (uint32_t i=0; i<count; ++i)
  475. {
  476. const ParameterData& paramData(plugin->getParameterData(i));
  477. const ParameterRanges& paramRanges(plugin->getParameterRanges(i));
  478. std::snprintf(tmpBuf, STR_MAX, "PARAMETER_DATA_%i:%i\n", pluginId, i);
  479. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  480. std::snprintf(tmpBuf, STR_MAX, "%i:%i:%i:%i\n", paramData.type, paramData.hints,
  481. paramData.mappedControlIndex, paramData.midiChannel);
  482. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  483. std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g\n", static_cast<double>(paramData.mappedMinimum),
  484. static_cast<double>(paramData.mappedMaximum));
  485. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  486. if (plugin->getParameterName(i, tmpBuf)) {
  487. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  488. } else {
  489. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  490. }
  491. if (plugin->getParameterUnit(i, tmpBuf)) {
  492. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  493. } else {
  494. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  495. }
  496. if (plugin->getParameterComment(i, tmpBuf)) {
  497. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  498. } else {
  499. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  500. }
  501. if (plugin->getParameterGroupName(i, tmpBuf)) {
  502. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  503. } else {
  504. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  505. }
  506. std::snprintf(tmpBuf, STR_MAX, "PARAMETER_RANGES_%i:%i\n", pluginId, i);
  507. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  508. std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g:%.12g:%.12g\n",
  509. static_cast<double>(paramRanges.def),
  510. static_cast<double>(paramRanges.min),
  511. static_cast<double>(paramRanges.max),
  512. static_cast<double>(paramRanges.step),
  513. static_cast<double>(paramRanges.stepSmall),
  514. static_cast<double>(paramRanges.stepLarge));
  515. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  516. std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", pluginId, i);
  517. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  518. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(i)));
  519. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  520. }
  521. fUiServer.flushMessages();
  522. }
  523. void uiServerSendPluginPrograms(const CarlaPluginPtr& plugin)
  524. {
  525. char tmpBuf[STR_MAX+1];
  526. carla_zeroChars(tmpBuf, STR_MAX+1);
  527. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  528. const uint pluginId(plugin->getId());
  529. uint32_t count = plugin->getProgramCount();
  530. std::snprintf(tmpBuf, STR_MAX, "PROGRAM_COUNT_%i:%i:%i\n", pluginId, count, plugin->getCurrentProgram());
  531. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  532. for (uint32_t i=0; i<count; ++i)
  533. {
  534. std::snprintf(tmpBuf, STR_MAX, "PROGRAM_NAME_%i:%i\n", pluginId, i);
  535. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  536. if (plugin->getProgramName(i, tmpBuf)) {
  537. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(tmpBuf),);
  538. } else {
  539. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  540. }
  541. }
  542. fUiServer.flushMessages();
  543. count = plugin->getMidiProgramCount();
  544. std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_COUNT_%i:%i:%i\n",
  545. pluginId, count, plugin->getCurrentMidiProgram());
  546. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  547. for (uint32_t i=0; i<count; ++i)
  548. {
  549. std::snprintf(tmpBuf, STR_MAX, "MIDI_PROGRAM_DATA_%i:%i\n", pluginId, i);
  550. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  551. const MidiProgramData& mpData(plugin->getMidiProgramData(i));
  552. std::snprintf(tmpBuf, STR_MAX, "%i:%i\n", mpData.bank, mpData.program);
  553. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  554. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(mpData.name),);
  555. }
  556. fUiServer.flushMessages();
  557. }
  558. void uiServerSendPluginProperties(const CarlaPluginPtr& plugin)
  559. {
  560. char tmpBuf[STR_MAX+1];
  561. carla_zeroChars(tmpBuf, STR_MAX+1);
  562. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  563. const uint pluginId(plugin->getId());
  564. uint32_t count = plugin->getCustomDataCount();
  565. std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_COUNT_%i:%i\n", pluginId, count);
  566. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  567. for (uint32_t i=0; i<count; ++i)
  568. {
  569. const CustomData& customData(plugin->getCustomData(i));
  570. CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  571. if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_PROPERTY) != 0)
  572. continue;
  573. std::snprintf(tmpBuf, STR_MAX, "CUSTOM_DATA_%i:%i\n", pluginId, i);
  574. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  575. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.type),);
  576. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.key),);
  577. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(customData.value),);
  578. }
  579. fUiServer.flushMessages();
  580. }
  581. void uiServerCallback(const EngineCallbackOpcode action, const uint pluginId,
  582. const int value1, const int value2, const int value3,
  583. const float valuef, const char* const valueStr)
  584. {
  585. if (! fIsRunning)
  586. return;
  587. if (! fUiServer.isPipeRunning())
  588. return;
  589. switch (action)
  590. {
  591. case ENGINE_CALLBACK_UPDATE:
  592. if (const CarlaPluginPtr plugin = getPlugin(pluginId))
  593. {
  594. if (plugin->isEnabled())
  595. {
  596. CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
  597. uiServerSendPluginProperties(plugin);
  598. }
  599. }
  600. break;
  601. case ENGINE_CALLBACK_RELOAD_INFO:
  602. if (const CarlaPluginPtr plugin = getPlugin(pluginId))
  603. {
  604. if (plugin->isEnabled())
  605. {
  606. CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
  607. uiServerSendPluginInfo(plugin);
  608. }
  609. }
  610. break;
  611. case ENGINE_CALLBACK_RELOAD_PARAMETERS:
  612. if (const CarlaPluginPtr plugin = getPlugin(pluginId))
  613. {
  614. if (plugin->isEnabled())
  615. {
  616. CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
  617. uiServerSendPluginParameters(plugin);
  618. }
  619. }
  620. break;
  621. case ENGINE_CALLBACK_RELOAD_PROGRAMS:
  622. if (const CarlaPluginPtr plugin = getPlugin(pluginId))
  623. {
  624. if (plugin->isEnabled())
  625. {
  626. CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
  627. uiServerSendPluginPrograms(plugin);
  628. }
  629. }
  630. break;
  631. case ENGINE_CALLBACK_RELOAD_ALL:
  632. case ENGINE_CALLBACK_PLUGIN_ADDED:
  633. case ENGINE_CALLBACK_PLUGIN_RENAMED:
  634. if (const CarlaPluginPtr plugin = getPlugin(pluginId))
  635. {
  636. if (plugin->isEnabled())
  637. {
  638. CARLA_SAFE_ASSERT_BREAK(plugin->getId() == pluginId);
  639. uiServerSendPluginInfo(plugin);
  640. uiServerSendPluginParameters(plugin);
  641. uiServerSendPluginPrograms(plugin);
  642. uiServerSendPluginProperties(plugin);
  643. }
  644. }
  645. break;
  646. default:
  647. break;
  648. }
  649. char tmpBuf[STR_MAX+1];
  650. carla_zeroChars(tmpBuf, STR_MAX+1);
  651. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  652. std::snprintf(tmpBuf, STR_MAX, "ENGINE_CALLBACK_%i\n", int(action));
  653. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  654. std::snprintf(tmpBuf, STR_MAX, "%u\n", pluginId);
  655. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  656. std::snprintf(tmpBuf, STR_MAX, "%i\n", value1);
  657. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  658. std::snprintf(tmpBuf, STR_MAX, "%i\n", value2);
  659. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  660. std::snprintf(tmpBuf, STR_MAX, "%i\n", value3);
  661. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  662. {
  663. const CarlaScopedLocale csl;
  664. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(valuef));
  665. }
  666. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  667. if (valueStr != nullptr) {
  668. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(valueStr),);
  669. } else {
  670. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeEmptyMessage(),);
  671. }
  672. fUiServer.flushMessages();
  673. }
  674. void uiServerInfo()
  675. {
  676. CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
  677. CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
  678. char tmpBuf[STR_MAX+1];
  679. carla_zeroChars(tmpBuf, STR_MAX+1);
  680. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  681. #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
  682. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("osc-urls\n"),);
  683. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathTCP()),);
  684. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(pData->osc.getServerPathUDP()),);
  685. #endif
  686. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("max-plugin-number\n"),);
  687. std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->maxPluginNumber);
  688. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  689. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("buffer-size\n"),);
  690. std::snprintf(tmpBuf, STR_MAX, "%i\n", pData->bufferSize);
  691. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  692. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("sample-rate\n"),);
  693. {
  694. const CarlaScopedLocale csl;
  695. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", pData->sampleRate);
  696. }
  697. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  698. fUiServer.flushMessages();
  699. }
  700. void uiServerOptions()
  701. {
  702. CARLA_SAFE_ASSERT_RETURN(fIsRunning,);
  703. CARLA_SAFE_ASSERT_RETURN(fUiServer.isPipeRunning(),);
  704. char tmpBuf[STR_MAX+1];
  705. carla_zeroChars(tmpBuf, STR_MAX+1);
  706. const EngineOptions& options(pData->options);
  707. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  708. const char* const optionsForcedStr(fOptionsForced ? "true\n" : "false\n");
  709. const std::size_t optionsForcedStrSize(fOptionsForced ? 5 : 6);
  710. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PROCESS_MODE);
  711. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  712. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  713. std::snprintf(tmpBuf, STR_MAX, "%i\n", options.processMode);
  714. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  715. fUiServer.flushMessages();
  716. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_TRANSPORT_MODE);
  717. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  718. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  719. std::snprintf(tmpBuf, STR_MAX, "%i\n", options.transportMode);
  720. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  721. fUiServer.flushMessages();
  722. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_FORCE_STEREO);
  723. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  724. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  725. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.forceStereo ? "true\n" : "false\n"),);
  726. fUiServer.flushMessages();
  727. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_PLUGIN_BRIDGES);
  728. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  729. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  730. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferPluginBridges ? "true\n" : "false\n"),);
  731. fUiServer.flushMessages();
  732. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PREFER_UI_BRIDGES);
  733. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  734. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  735. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.preferUiBridges ? "true\n" : "false\n"),);
  736. fUiServer.flushMessages();
  737. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UIS_ALWAYS_ON_TOP);
  738. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  739. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  740. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(options.uisAlwaysOnTop ? "true\n" : "false\n"),);
  741. fUiServer.flushMessages();
  742. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_MAX_PARAMETERS);
  743. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  744. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  745. std::snprintf(tmpBuf, STR_MAX, "%i\n", options.maxParameters);
  746. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  747. fUiServer.flushMessages();
  748. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_UI_BRIDGES_TIMEOUT);
  749. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  750. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(optionsForcedStr, optionsForcedStrSize),);
  751. std::snprintf(tmpBuf, STR_MAX, "%i\n", options.uiBridgesTimeout);
  752. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  753. fUiServer.flushMessages();
  754. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_BINARIES);
  755. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  756. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
  757. std::snprintf(tmpBuf, STR_MAX, "%s\n", options.binaryDir);
  758. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  759. fUiServer.flushMessages();
  760. std::snprintf(tmpBuf, STR_MAX, "ENGINE_OPTION_%i\n", ENGINE_OPTION_PATH_RESOURCES);
  761. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  762. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("true\n", 5),);
  763. std::snprintf(tmpBuf, STR_MAX, "%s\n", options.resourceDir);
  764. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  765. fUiServer.flushMessages();
  766. }
  767. #endif
  768. // -------------------------------------------------------------------
  769. // Plugin parameter calls
  770. uint32_t getParameterCount() const
  771. {
  772. return kNumInParams + kNumOutParams;
  773. }
  774. const NativeParameter* getParameterInfo(const uint32_t index) const
  775. {
  776. static NativeParameter param;
  777. static char strBufName[STR_MAX+1];
  778. static char strBufUnit[STR_MAX+1];
  779. static char strBufComment[STR_MAX+1];
  780. static char strBufGroupName[STR_MAX+1];
  781. carla_zeroChars(strBufName, STR_MAX+1);
  782. carla_zeroChars(strBufUnit, STR_MAX+1);
  783. carla_zeroChars(strBufComment, STR_MAX+1);
  784. carla_zeroChars(strBufGroupName, STR_MAX+1);
  785. uint32_t rindex = index;
  786. if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
  787. {
  788. const ParameterData& paramData(plugin->getParameterData(rindex));
  789. const ParameterRanges& paramRanges(plugin->getParameterRanges(rindex));
  790. if (! plugin->getParameterName(rindex, strBufName))
  791. strBufName[0] = '\0';
  792. if (! plugin->getParameterUnit(rindex, strBufUnit))
  793. strBufUnit[0] = '\0';
  794. if (! plugin->getParameterComment(rindex, strBufComment))
  795. strBufComment[0] = '\0';
  796. if (! plugin->getParameterGroupName(rindex, strBufGroupName))
  797. std::snprintf(strBufGroupName, STR_MAX, "%u:%s", plugin->getId(), plugin->getName());
  798. uint hints = 0x0;
  799. if (paramData.hints & PARAMETER_IS_BOOLEAN)
  800. hints |= NATIVE_PARAMETER_IS_BOOLEAN;
  801. if (paramData.hints & PARAMETER_IS_INTEGER)
  802. hints |= NATIVE_PARAMETER_IS_INTEGER;
  803. if (paramData.hints & PARAMETER_IS_LOGARITHMIC)
  804. hints |= NATIVE_PARAMETER_IS_LOGARITHMIC;
  805. if (paramData.hints & PARAMETER_IS_AUTOMATABLE)
  806. hints |= NATIVE_PARAMETER_IS_AUTOMATABLE;
  807. if (paramData.hints & PARAMETER_USES_SAMPLERATE)
  808. hints |= NATIVE_PARAMETER_USES_SAMPLE_RATE;
  809. if (paramData.hints & PARAMETER_USES_SCALEPOINTS)
  810. hints |= NATIVE_PARAMETER_USES_SCALEPOINTS;
  811. if (paramData.type == PARAMETER_INPUT || paramData.type == PARAMETER_OUTPUT)
  812. {
  813. if (paramData.hints & PARAMETER_IS_ENABLED)
  814. hints |= NATIVE_PARAMETER_IS_ENABLED;
  815. if (paramData.type == PARAMETER_OUTPUT)
  816. hints |= NATIVE_PARAMETER_IS_OUTPUT;
  817. }
  818. param.hints = static_cast<NativeParameterHints>(hints);
  819. param.name = strBufName;
  820. param.unit = strBufUnit;
  821. param.comment = strBufComment;
  822. param.groupName = strBufGroupName;
  823. param.ranges.def = paramRanges.def;
  824. param.ranges.min = paramRanges.min;
  825. param.ranges.max = paramRanges.max;
  826. param.ranges.step = paramRanges.step;
  827. param.ranges.stepSmall = paramRanges.stepSmall;
  828. param.ranges.stepLarge = paramRanges.stepLarge;
  829. param.scalePointCount = 0; // TODO
  830. param.scalePoints = nullptr;
  831. return &param;
  832. }
  833. param.hints = index < kNumInParams ? static_cast<NativeParameterHints>(0x0) : NATIVE_PARAMETER_IS_OUTPUT;
  834. param.name = "Unused";
  835. param.unit = "";
  836. param.ranges.def = 0.0f;
  837. param.ranges.min = 0.0f;
  838. param.ranges.max = 1.0f;
  839. param.ranges.step = 0.01f;
  840. param.ranges.stepSmall = 0.001f;
  841. param.ranges.stepLarge = 0.1f;
  842. param.scalePointCount = 0;
  843. param.scalePoints = nullptr;
  844. return &param;
  845. }
  846. float getParameterValue(const uint32_t index) const
  847. {
  848. uint32_t rindex = index;
  849. if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
  850. return plugin->getParameterValue(rindex);
  851. return fParameters[index];
  852. }
  853. // -------------------------------------------------------------------
  854. // Plugin state calls
  855. void setParameterValue(const uint32_t index, const float value)
  856. {
  857. uint32_t rindex = index;
  858. if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
  859. plugin->setParameterValueRT(rindex, value, 0, false);
  860. fParameters[index] = value;
  861. }
  862. // -------------------------------------------------------------------
  863. // Plugin process calls
  864. void activate()
  865. {
  866. #if 0
  867. for (uint i=0; i < pData->curPluginCount; ++i)
  868. {
  869. CarlaPluginPtr plugin = pData->plugins[i].plugin;
  870. if (plugin == nullptr || ! plugin->isEnabled())
  871. continue;
  872. plugin->setActive(true, true, false);
  873. }
  874. #endif
  875. fIsActive = true;
  876. }
  877. void deactivate()
  878. {
  879. fIsActive = false;
  880. #if 0
  881. for (uint i=0; i < pData->curPluginCount; ++i)
  882. {
  883. CarlaPluginPtr plugin = pData->plugins[i].plugin;
  884. if (plugin == nullptr || ! plugin->isEnabled())
  885. continue;
  886. plugin->setActive(false, true, false);
  887. }
  888. #endif
  889. // just in case
  890. //runPendingRtEvents();
  891. }
  892. void process(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames,
  893. const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount)
  894. {
  895. if (frames > pData->bufferSize)
  896. {
  897. carla_stderr2("Host is calling process with too high number of frames! %u vs %u",
  898. frames, pData->bufferSize);
  899. deactivate();
  900. bufferSizeChanged(frames);
  901. activate();
  902. }
  903. const PendingRtEventsRunner prt(this, frames, true);
  904. // ---------------------------------------------------------------
  905. // Time Info
  906. const NativeTimeInfo* const timeInfo(pHost->get_time_info(pHost->handle));
  907. pData->timeInfo.playing = timeInfo->playing;
  908. pData->timeInfo.frame = timeInfo->frame;
  909. pData->timeInfo.usecs = timeInfo->usecs;
  910. pData->timeInfo.bbt.valid = timeInfo->bbt.valid;
  911. if (timeInfo->bbt.valid)
  912. {
  913. pData->timeInfo.bbt.bar = timeInfo->bbt.bar;
  914. pData->timeInfo.bbt.beat = timeInfo->bbt.beat;
  915. pData->timeInfo.bbt.tick = timeInfo->bbt.tick;
  916. pData->timeInfo.bbt.barStartTick = timeInfo->bbt.barStartTick;
  917. pData->timeInfo.bbt.beatsPerBar = timeInfo->bbt.beatsPerBar;
  918. pData->timeInfo.bbt.beatType = timeInfo->bbt.beatType;
  919. pData->timeInfo.bbt.ticksPerBeat = timeInfo->bbt.ticksPerBeat;
  920. pData->timeInfo.bbt.beatsPerMinute = timeInfo->bbt.beatsPerMinute;
  921. }
  922. // ---------------------------------------------------------------
  923. // Do nothing if no plugins and rack mode
  924. if (pData->curPluginCount == 0 && ! kIsPatchbay)
  925. {
  926. if (outBuffer[0] != inBuffer[0])
  927. carla_copyFloats(outBuffer[0], inBuffer[0], frames);
  928. if (outBuffer[1] != inBuffer[1])
  929. carla_copyFloats(outBuffer[1], inBuffer[1], frames);
  930. for (uint32_t i=0; i < midiEventCount; ++i)
  931. {
  932. if (! pHost->write_midi_event(pHost->handle, &midiEvents[i]))
  933. break;
  934. }
  935. return;
  936. }
  937. // ---------------------------------------------------------------
  938. // initialize events
  939. carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
  940. carla_zeroStructs(pData->events.out, kMaxEngineEventInternalCount);
  941. // ---------------------------------------------------------------
  942. // events input (before processing)
  943. if (kHasMidiIn)
  944. {
  945. uint32_t engineEventIndex = 0;
  946. for (uint32_t i=0; i < midiEventCount && engineEventIndex < kMaxEngineEventInternalCount; ++i)
  947. {
  948. const NativeMidiEvent& midiEvent(midiEvents[i]);
  949. EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);
  950. engineEvent.time = midiEvent.time;
  951. engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data, 0);
  952. if (engineEventIndex >= kMaxEngineEventInternalCount)
  953. break;
  954. }
  955. }
  956. if (kIsPatchbay)
  957. {
  958. // -----------------------------------------------------------
  959. // process
  960. pData->graph.process(pData, inBuffer, outBuffer, frames);
  961. }
  962. else
  963. {
  964. // -----------------------------------------------------------
  965. // create audio buffers
  966. const float* inBuf[2] = { inBuffer[0], inBuffer[1] };
  967. /* */ float* outBuf[2] = { outBuffer[0], outBuffer[1] };
  968. // -----------------------------------------------------------
  969. // process
  970. pData->graph.processRack(pData, inBuf, outBuf, frames);
  971. }
  972. // ---------------------------------------------------------------
  973. // events output (after processing)
  974. carla_zeroStructs(pData->events.in, kMaxEngineEventInternalCount);
  975. if (kHasMidiOut)
  976. {
  977. NativeMidiEvent midiEvent;
  978. for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
  979. {
  980. const EngineEvent& engineEvent(pData->events.out[i]);
  981. if (engineEvent.type == kEngineEventTypeNull)
  982. break;
  983. carla_zeroStruct(midiEvent);
  984. midiEvent.time = engineEvent.time;
  985. /**/ if (engineEvent.type == kEngineEventTypeControl)
  986. {
  987. midiEvent.port = 0;
  988. midiEvent.size = engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.data);
  989. }
  990. else if (engineEvent.type == kEngineEventTypeMidi)
  991. {
  992. if (engineEvent.midi.size > 4)
  993. continue;
  994. midiEvent.port = engineEvent.midi.port;
  995. midiEvent.size = engineEvent.midi.size;
  996. midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] | (engineEvent.channel & MIDI_CHANNEL_BIT));
  997. for (uint8_t j=1; j < midiEvent.size; ++j)
  998. midiEvent.data[j] = engineEvent.midi.data[j];
  999. }
  1000. else
  1001. {
  1002. continue;
  1003. }
  1004. if (midiEvent.size > 0)
  1005. pHost->write_midi_event(pHost->handle, &midiEvent);
  1006. }
  1007. }
  1008. }
  1009. // -------------------------------------------------------------------
  1010. // Plugin UI calls
  1011. #ifndef CARLA_ENGINE_WITHOUT_UI
  1012. void uiShow(const bool show)
  1013. {
  1014. if (show)
  1015. {
  1016. if (fUiServer.isPipeRunning())
  1017. {
  1018. fUiServer.writeFocusMessage();
  1019. return;
  1020. }
  1021. CarlaString path(pHost->resourceDir);
  1022. if (kIsPatchbay)
  1023. path += CARLA_OS_SEP_STR "carla-plugin-patchbay";
  1024. else
  1025. path += CARLA_OS_SEP_STR "carla-plugin";
  1026. #ifdef CARLA_OS_WIN
  1027. path += ".exe";
  1028. #endif
  1029. carla_stdout("Trying to start carla-plugin using \"%s\"", path.buffer());
  1030. fUiServer.setData(path, pData->sampleRate, pHost->uiName);
  1031. #ifdef CARLA_OS_WIN
  1032. // Fix conflict with other tools using Carla
  1033. char* const oldcwd = _getcwd(nullptr, 0);
  1034. chdir(pHost->resourceDir);
  1035. #endif
  1036. if (! fUiServer.startPipeServer(false))
  1037. {
  1038. pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
  1039. return;
  1040. }
  1041. uiServerInfo();
  1042. uiServerOptions();
  1043. uiServerCallback(ENGINE_CALLBACK_ENGINE_STARTED,
  1044. pData->curPluginCount,
  1045. pData->options.processMode,
  1046. pData->options.transportMode,
  1047. static_cast<int>(pData->bufferSize),
  1048. static_cast<float>(pData->sampleRate),
  1049. "Plugin");
  1050. fUiServer.writeShowMessage();
  1051. for (uint i=0; i < pData->curPluginCount; ++i)
  1052. {
  1053. if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
  1054. if (plugin->isEnabled())
  1055. uiServerCallback(ENGINE_CALLBACK_PLUGIN_ADDED, i, plugin->getType(),
  1056. 0, 0, 0.0f,
  1057. plugin->getName());
  1058. }
  1059. if (kIsPatchbay)
  1060. patchbayRefresh(true, false, false);
  1061. #ifdef CARLA_OS_WIN
  1062. chdir(oldcwd);
  1063. std::free(oldcwd);
  1064. #endif
  1065. }
  1066. else
  1067. {
  1068. fUiServer.stopPipeServer(2000);
  1069. // hide all custom uis
  1070. for (uint i=0; i < pData->curPluginCount; ++i)
  1071. {
  1072. if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
  1073. {
  1074. if (plugin->isEnabled())
  1075. {
  1076. if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
  1077. {
  1078. try {
  1079. plugin->showCustomUI(false);
  1080. } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin showCustomUI (hide)");
  1081. }
  1082. }
  1083. }
  1084. }
  1085. }
  1086. }
  1087. #endif
  1088. void uiIdle()
  1089. {
  1090. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  1091. const ScopedJuceMessageThreadRunner sjmtr(*this, false);
  1092. if (kNeedsJuceEvents && ! sjmtr.wasLocked)
  1093. return;
  1094. #endif
  1095. for (uint i=0; i < pData->curPluginCount; ++i)
  1096. {
  1097. if (const CarlaPluginPtr plugin = pData->plugins[i].plugin)
  1098. {
  1099. if (plugin->isEnabled())
  1100. {
  1101. const uint hints = plugin->getHints();
  1102. if ((hints & PLUGIN_HAS_CUSTOM_UI) != 0 && (hints & PLUGIN_NEEDS_UI_MAIN_THREAD) != 0)
  1103. {
  1104. try {
  1105. plugin->uiIdle();
  1106. } CARLA_SAFE_EXCEPTION_CONTINUE("Plugin uiIdle");
  1107. }
  1108. }
  1109. }
  1110. }
  1111. #ifndef CARLA_ENGINE_WITHOUT_UI
  1112. idlePipe();
  1113. switch (fUiServer.getAndResetUiState())
  1114. {
  1115. case CarlaExternalUI::UiNone:
  1116. case CarlaExternalUI::UiShow:
  1117. break;
  1118. case CarlaExternalUI::UiCrashed:
  1119. pHost->dispatcher(pHost->handle, NATIVE_HOST_OPCODE_UI_UNAVAILABLE, 0, 0, nullptr, 0.0f);
  1120. break;
  1121. case CarlaExternalUI::UiHide:
  1122. pHost->ui_closed(pHost->handle);
  1123. fUiServer.stopPipeServer(1000);
  1124. break;
  1125. }
  1126. #endif
  1127. if (carla_isNotEqual(fLastScaleFactor, pData->options.uiScale))
  1128. {
  1129. fLastScaleFactor = pData->options.uiScale;
  1130. pHost->dispatcher(pHost->handle,
  1131. NATIVE_HOST_OPCODE_UI_RESIZE,
  1132. static_cast<int>(kUiWidth * fLastScaleFactor + 0.5f),
  1133. static_cast<int>(kUiHeight * fLastScaleFactor + 0.5f),
  1134. nullptr, 0.0f);
  1135. }
  1136. {
  1137. const CarlaMutexLocker cml(fPluginDeleterMutex);
  1138. pData->deletePluginsAsNeeded();
  1139. }
  1140. }
  1141. void uiSetParameterValue(const uint32_t index, const float value)
  1142. {
  1143. uint32_t rindex = index;
  1144. if (const CarlaPluginPtr plugin = _getPluginForParameterIndex(rindex))
  1145. {
  1146. if (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI)
  1147. plugin->uiParameterChange(rindex, value);
  1148. #ifndef CARLA_ENGINE_WITHOUT_UI
  1149. if (index >= kNumInParams || ! fUiServer.isPipeRunning())
  1150. return;
  1151. uiServerCallback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1152. plugin->getId(),
  1153. static_cast<int>(rindex),
  1154. 0, 0,
  1155. value,
  1156. nullptr);
  1157. #endif
  1158. }
  1159. }
  1160. #ifndef CARLA_ENGINE_WITHOUT_UI
  1161. void idlePipe()
  1162. {
  1163. if (! fUiServer.isPipeRunning())
  1164. return;
  1165. fUiServer.idlePipe();
  1166. if (! fUiServer.isPipeRunning())
  1167. return;
  1168. char tmpBuf[STR_MAX+1];
  1169. carla_zeroChars(tmpBuf, STR_MAX+1);
  1170. const CarlaMutexLocker cml(fUiServer.getPipeLock());
  1171. const CarlaScopedLocale csl;
  1172. const EngineTimeInfo& timeInfo(pData->timeInfo);
  1173. // ------------------------------------------------------------------------------------------------------------
  1174. // send engine info
  1175. std::snprintf(tmpBuf, STR_MAX, "%.12g:0\n", static_cast<double>(getDSPLoad()));
  1176. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("runtime-info\n"),);
  1177. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1178. fUiServer.flushMessages();
  1179. if (const char* const projFolder = getCurrentProjectFolder())
  1180. {
  1181. if (fLastProjectFolder != projFolder)
  1182. {
  1183. carla_stdout("Project folder changed to %s", projFolder);
  1184. fLastProjectFolder = projFolder;
  1185. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("project-folder\n"),);
  1186. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeAndFixMessage(projFolder),);
  1187. fUiServer.flushMessages();
  1188. }
  1189. }
  1190. // ------------------------------------------------------------------------------------------------------------
  1191. // send transport
  1192. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("transport\n"),);
  1193. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(timeInfo.playing ? "true\n" : "false\n"),);
  1194. if (timeInfo.bbt.valid)
  1195. {
  1196. std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":%i:%i:%i\n", timeInfo.frame,
  1197. timeInfo.bbt.bar,
  1198. timeInfo.bbt.beat,
  1199. static_cast<int>(timeInfo.bbt.tick + 0.5));
  1200. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1201. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", timeInfo.bbt.beatsPerMinute);
  1202. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1203. }
  1204. else
  1205. {
  1206. std::snprintf(tmpBuf, STR_MAX, P_UINT64 ":0:0:0\n", timeInfo.frame);
  1207. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1208. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage("0.0\n"),);
  1209. }
  1210. fUiServer.flushMessages();
  1211. // ------------------------------------------------------------------------------------------------------------
  1212. // send peaks and param outputs for all plugins
  1213. for (uint i=0; i < pData->curPluginCount; ++i)
  1214. {
  1215. const EnginePluginData& plugData(pData->plugins[i]);
  1216. const CarlaPluginPtr plugin = pData->plugins[i].plugin;
  1217. std::snprintf(tmpBuf, STR_MAX, "PEAKS_%i\n", i);
  1218. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1219. std::snprintf(tmpBuf, STR_MAX, "%.12g:%.12g:%.12g:%.12g\n",
  1220. static_cast<double>(plugData.peaks[0]),
  1221. static_cast<double>(plugData.peaks[1]),
  1222. static_cast<double>(plugData.peaks[2]),
  1223. static_cast<double>(plugData.peaks[3]));
  1224. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1225. fUiServer.flushMessages();
  1226. for (uint32_t j=0, count=plugin->getParameterCount(); j < count; ++j)
  1227. {
  1228. if (! plugin->isParameterOutput(j))
  1229. continue;
  1230. std::snprintf(tmpBuf, STR_MAX, "PARAMVAL_%u:%u\n", i, j);
  1231. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1232. std::snprintf(tmpBuf, STR_MAX, "%.12g\n", static_cast<double>(plugin->getParameterValue(j)));
  1233. CARLA_SAFE_ASSERT_RETURN(fUiServer.writeMessage(tmpBuf),);
  1234. fUiServer.flushMessages();
  1235. }
  1236. }
  1237. }
  1238. #endif
  1239. // -------------------------------------------------------------------
  1240. // Plugin state calls
  1241. char* getState() const
  1242. {
  1243. MemoryOutputStream out;
  1244. saveProjectInternal(out);
  1245. return strdup(out.toString().toRawUTF8());
  1246. }
  1247. void setState(const char* const data)
  1248. {
  1249. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  1250. const ScopedJuceMessageThreadRunner sjmtr(*this, true);
  1251. #endif
  1252. // remove all plugins from UI side
  1253. for (uint i=0, count=pData->curPluginCount; i < count; ++i)
  1254. CarlaEngine::callback(true, true, ENGINE_CALLBACK_PLUGIN_REMOVED, count-i-1, 0, 0, 0, 0.0f, nullptr);
  1255. // remove all plugins from backend, no lock
  1256. fIsRunning = false;
  1257. removeAllPlugins();
  1258. fIsRunning = true;
  1259. {
  1260. const CarlaMutexLocker cml(fPluginDeleterMutex);
  1261. pData->deletePluginsAsNeeded();
  1262. }
  1263. // stopped during removeAllPlugins()
  1264. if (! pData->runner.isRunnerActive())
  1265. pData->runner.start();
  1266. fOptionsForced = true;
  1267. const String state(data);
  1268. XmlDocument xml(state);
  1269. loadProjectInternal(xml, true);
  1270. reloadFromUI();
  1271. }
  1272. // -------------------------------------------------------------------
  1273. public:
  1274. #define handlePtr ((CarlaEngineNative*)handle)
  1275. static NativePluginHandle _instantiateRack(const NativeHostDescriptor* host)
  1276. {
  1277. return new CarlaEngineNative(host, false, true, true);
  1278. }
  1279. static NativePluginHandle _instantiateRackNoMidiOut(const NativeHostDescriptor* host)
  1280. {
  1281. return new CarlaEngineNative(host, false, true, false);
  1282. }
  1283. static NativePluginHandle _instantiatePatchbay(const NativeHostDescriptor* host)
  1284. {
  1285. return new CarlaEngineNative(host, true, true, true);
  1286. }
  1287. static NativePluginHandle _instantiatePatchbay3s(const NativeHostDescriptor* host)
  1288. {
  1289. return new CarlaEngineNative(host, true, true, true, 3, 2);
  1290. }
  1291. static NativePluginHandle _instantiatePatchbay16(const NativeHostDescriptor* host)
  1292. {
  1293. return new CarlaEngineNative(host, true, true, true, 16, 16);
  1294. }
  1295. static NativePluginHandle _instantiatePatchbay32(const NativeHostDescriptor* host)
  1296. {
  1297. return new CarlaEngineNative(host, true, true, true, 32, 32);
  1298. }
  1299. static NativePluginHandle _instantiatePatchbay64(const NativeHostDescriptor* host)
  1300. {
  1301. return new CarlaEngineNative(host, true, true, true, 64, 64);
  1302. }
  1303. static NativePluginHandle _instantiatePatchbayCV(const NativeHostDescriptor* host)
  1304. {
  1305. return new CarlaEngineNative(host, true, true, true, 2, 2, 5, 5);
  1306. }
  1307. static NativePluginHandle _instantiatePatchbayCV8(const NativeHostDescriptor* host)
  1308. {
  1309. return new CarlaEngineNative(host, true, true, true, 2, 2, 8, 8);
  1310. }
  1311. static NativePluginHandle _instantiatePatchbayCV32(const NativeHostDescriptor* host)
  1312. {
  1313. return new CarlaEngineNative(host, true, true, true, 64, 64, 32, 32);
  1314. }
  1315. static NativePluginHandle _instantiatePatchbayOBS(const NativeHostDescriptor* host)
  1316. {
  1317. return new CarlaEngineNative(host, true, false, false, 8, 8);
  1318. }
  1319. static void _cleanup(NativePluginHandle handle)
  1320. {
  1321. delete handlePtr;
  1322. }
  1323. static uint32_t _get_parameter_count(NativePluginHandle handle)
  1324. {
  1325. return handlePtr->getParameterCount();
  1326. }
  1327. static const NativeParameter* _get_parameter_info(NativePluginHandle handle, uint32_t index)
  1328. {
  1329. return handlePtr->getParameterInfo(index);
  1330. }
  1331. static float _get_parameter_value(NativePluginHandle handle, uint32_t index)
  1332. {
  1333. return handlePtr->getParameterValue(index);
  1334. }
  1335. static void _set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
  1336. {
  1337. handlePtr->setParameterValue(index, value);
  1338. }
  1339. #ifndef CARLA_ENGINE_WITHOUT_UI
  1340. static void _ui_show(NativePluginHandle handle, bool show)
  1341. {
  1342. handlePtr->uiShow(show);
  1343. }
  1344. #endif
  1345. static void _ui_idle(NativePluginHandle handle)
  1346. {
  1347. handlePtr->uiIdle();
  1348. }
  1349. static void _ui_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
  1350. {
  1351. handlePtr->uiSetParameterValue(index, value);
  1352. }
  1353. static void _activate(NativePluginHandle handle)
  1354. {
  1355. handlePtr->activate();
  1356. }
  1357. static void _deactivate(NativePluginHandle handle)
  1358. {
  1359. handlePtr->deactivate();
  1360. }
  1361. // FIXME for v3.0, use const for the input buffer
  1362. static void _process(NativePluginHandle handle,
  1363. float** inBuffer, float** outBuffer, const uint32_t frames,
  1364. const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
  1365. {
  1366. handlePtr->process(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
  1367. }
  1368. static char* _get_state(NativePluginHandle handle)
  1369. {
  1370. return handlePtr->getState();
  1371. }
  1372. static void _set_state(NativePluginHandle handle, const char* data)
  1373. {
  1374. handlePtr->setState(data);
  1375. }
  1376. static intptr_t _dispatcher(NativePluginHandle handle,
  1377. NativePluginDispatcherOpcode opcode,
  1378. int32_t index, intptr_t value, void* ptr, float opt)
  1379. {
  1380. switch(opcode)
  1381. {
  1382. case NATIVE_PLUGIN_OPCODE_NULL:
  1383. return 0;
  1384. case NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
  1385. CARLA_SAFE_ASSERT_RETURN(value > 0, 0);
  1386. handlePtr->bufferSizeChanged(static_cast<uint32_t>(value));
  1387. return 0;
  1388. case NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
  1389. CARLA_SAFE_ASSERT_RETURN(opt > 0.0f, 0);
  1390. handlePtr->sampleRateChanged(static_cast<double>(opt));
  1391. return 0;
  1392. case NATIVE_PLUGIN_OPCODE_OFFLINE_CHANGED:
  1393. handlePtr->offlineModeChanged(value != 0);
  1394. return 0;
  1395. case NATIVE_PLUGIN_OPCODE_UI_NAME_CHANGED:
  1396. //handlePtr->uiNameChanged(static_cast<const char*>(ptr));
  1397. return 0;
  1398. case NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE: {
  1399. CarlaEngineNative* const engine = handlePtr;
  1400. return (intptr_t)(CarlaEngine*)engine;
  1401. }
  1402. case NATIVE_PLUGIN_OPCODE_IDLE:
  1403. //handlePtr->idle();
  1404. return 0;
  1405. case NATIVE_PLUGIN_OPCODE_UI_MIDI_EVENT:
  1406. return 0;
  1407. case NATIVE_PLUGIN_OPCODE_HOST_USES_EMBED:
  1408. handlePtr->fUsesEmbed = true;
  1409. return 0;
  1410. case NATIVE_PLUGIN_OPCODE_HOST_OPTION:
  1411. handlePtr->setOption(static_cast<EngineOption>(index), value, static_cast<const char*>(ptr));
  1412. return 0;
  1413. }
  1414. return 0;
  1415. // unused
  1416. (void)index;
  1417. (void)ptr;
  1418. }
  1419. // -------------------------------------------------------------------
  1420. #undef handlePtr
  1421. private:
  1422. const NativeHostDescriptor* const pHost;
  1423. #ifdef USE_REFCOUNTER_JUCE_MESSAGE_MANAGER
  1424. const bool kNeedsJuceEvents;
  1425. const CarlaJUCE::ReferenceCountedJuceMessageMessager fJuceMsgMgr;
  1426. CarlaMutex fJuceMsgMutex;
  1427. struct ScopedJuceMessageThreadRunner {
  1428. const CarlaMutexTryLocker cmtl;
  1429. const bool wasLocked;
  1430. ScopedJuceMessageThreadRunner(CarlaEngineNative& self, const bool forceLock) noexcept
  1431. : cmtl(self.fJuceMsgMutex, forceLock),
  1432. wasLocked(cmtl.wasLocked())
  1433. {
  1434. if (! self.kNeedsJuceEvents)
  1435. return;
  1436. if (! wasLocked)
  1437. return;
  1438. CarlaJUCE::setMessageManagerForThisThread();
  1439. }
  1440. ~ScopedJuceMessageThreadRunner()
  1441. {
  1442. CarlaJUCE::dispatchMessageManagerMessages();
  1443. }
  1444. CARLA_DECLARE_NON_COPYABLE(ScopedJuceMessageThreadRunner)
  1445. };
  1446. #endif
  1447. const bool kIsPatchbay; // rack if false
  1448. const bool kHasMidiIn;
  1449. const bool kHasMidiOut;
  1450. bool fIsActive, fIsRunning, fUsesEmbed;
  1451. #ifndef CARLA_ENGINE_WITHOUT_UI
  1452. CarlaEngineNativeUI fUiServer;
  1453. #endif
  1454. float fLastScaleFactor;
  1455. float fParameters[kNumInParams+kNumOutParams];
  1456. CarlaString fLastProjectFolder;
  1457. CarlaMutex fPluginDeleterMutex;
  1458. bool fOptionsForced;
  1459. CarlaPluginPtr _getPluginForParameterIndex(uint32_t& index) const noexcept
  1460. {
  1461. if (pData->curPluginCount == 0 || pData->plugins == nullptr)
  1462. return nullptr;
  1463. for (uint32_t i=0; i<pData->curPluginCount; ++i)
  1464. {
  1465. const CarlaPluginPtr plugin = pData->plugins[i].plugin;
  1466. if (plugin.get() == nullptr || ! plugin->isEnabled())
  1467. break;
  1468. if (const uint32_t paramCount = plugin->getParameterCount())
  1469. {
  1470. if (index >= paramCount)
  1471. {
  1472. index -= paramCount;
  1473. continue;
  1474. }
  1475. return plugin;
  1476. }
  1477. }
  1478. return nullptr;
  1479. }
  1480. bool _getRealIndexForPluginParameter(const uint32_t pluginId, uint32_t& rindex) const noexcept
  1481. {
  1482. if (pData->curPluginCount == 0 || pluginId >= pData->curPluginCount || pData->plugins == nullptr)
  1483. return false;
  1484. for (uint32_t i=0; i<pluginId; ++i)
  1485. {
  1486. const CarlaPluginPtr plugin = pData->plugins[i].plugin;
  1487. if (plugin.get() == nullptr || ! plugin->isEnabled())
  1488. return false;
  1489. rindex += plugin->getParameterCount();
  1490. }
  1491. if (rindex >= kNumInParams)
  1492. return false;
  1493. return true;
  1494. }
  1495. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNative)
  1496. };
  1497. // -----------------------------------------------------------------------
  1498. #ifndef CARLA_ENGINE_WITHOUT_UI
  1499. bool CarlaEngineNativeUI::msgReceived(const char* const msg) noexcept
  1500. {
  1501. if (CarlaExternalUI::msgReceived(msg))
  1502. return true;
  1503. bool ok = true;
  1504. if (std::strcmp(msg, "set_engine_option") == 0)
  1505. {
  1506. uint32_t option;
  1507. int32_t value;
  1508. const char* valueStr = nullptr;
  1509. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
  1510. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(value), true);
  1511. readNextLineAsString(valueStr, false); // can be null
  1512. try {
  1513. fEngine->setOption(static_cast<EngineOption>(option), value, valueStr);
  1514. } CARLA_SAFE_EXCEPTION("setOption");
  1515. }
  1516. else if (std::strcmp(msg, "clear_engine_xruns") == 0)
  1517. {
  1518. fEngine->clearXruns();
  1519. }
  1520. else if (std::strcmp(msg, "cancel_engine_action") == 0)
  1521. {
  1522. fEngine->setActionCanceled(true);
  1523. }
  1524. else if (std::strcmp(msg, "load_file") == 0)
  1525. {
  1526. const char* filename;
  1527. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
  1528. try {
  1529. ok = fEngine->loadFile(filename);
  1530. } CARLA_SAFE_EXCEPTION("loadFile");
  1531. fEngine->reloadFromUI();
  1532. }
  1533. else if (std::strcmp(msg, "load_project") == 0)
  1534. {
  1535. const char* filename;
  1536. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
  1537. try {
  1538. ok = fEngine->loadProject(filename, true);
  1539. } CARLA_SAFE_EXCEPTION("loadProject");
  1540. fEngine->reloadFromUI();
  1541. }
  1542. else if (std::strcmp(msg, "save_project") == 0)
  1543. {
  1544. const char* filename;
  1545. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
  1546. try {
  1547. ok = fEngine->saveProject(filename, true);
  1548. } CARLA_SAFE_EXCEPTION("saveProject");
  1549. }
  1550. else if (std::strcmp(msg, "clear_project_filename") == 0)
  1551. {
  1552. fEngine->clearCurrentProjectFilename();
  1553. }
  1554. else if (std::strcmp(msg, "patchbay_connect") == 0)
  1555. {
  1556. bool external;
  1557. uint32_t groupA, portA, groupB, portB;
  1558. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
  1559. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupA), true);
  1560. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portA), true);
  1561. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupB), true);
  1562. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(portB), true);
  1563. try {
  1564. ok = fEngine->patchbayConnect(external, groupA, portA, groupB, portB);
  1565. } CARLA_SAFE_EXCEPTION("patchbayConnect");
  1566. }
  1567. else if (std::strcmp(msg, "patchbay_disconnect") == 0)
  1568. {
  1569. bool external;
  1570. uint32_t connectionId;
  1571. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
  1572. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(connectionId), true);
  1573. try {
  1574. ok = fEngine->patchbayDisconnect(external, connectionId);
  1575. } CARLA_SAFE_EXCEPTION("patchbayDisconnect");
  1576. }
  1577. else if (std::strcmp(msg, "patchbay_set_group_pos") == 0)
  1578. {
  1579. bool external;
  1580. uint32_t groupId;
  1581. int x1, y1, x2, y2;
  1582. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
  1583. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(groupId), true);
  1584. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x1), true);
  1585. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y1), true);
  1586. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(x2), true);
  1587. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(y2), true);
  1588. try {
  1589. ok = fEngine->patchbaySetGroupPos(false, true, external, groupId, x1, y1, x2, y2);
  1590. } CARLA_SAFE_EXCEPTION("patchbaySetGroupPos");
  1591. }
  1592. else if (std::strcmp(msg, "patchbay_refresh") == 0)
  1593. {
  1594. bool external;
  1595. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(external), true);
  1596. try {
  1597. ok = fEngine->patchbayRefresh(true, false, external);
  1598. } CARLA_SAFE_EXCEPTION("patchbayRefresh");
  1599. }
  1600. else if (std::strcmp(msg, "transport_play") == 0)
  1601. {
  1602. fEngine->transportPlay();
  1603. }
  1604. else if (std::strcmp(msg, "transport_pause") == 0)
  1605. {
  1606. fEngine->transportPause();
  1607. }
  1608. else if (std::strcmp(msg, "transport_bpm") == 0)
  1609. {
  1610. double bpm;
  1611. CARLA_SAFE_ASSERT_RETURN(readNextLineAsDouble(bpm), true);
  1612. fEngine->transportBPM(bpm);
  1613. }
  1614. else if (std::strcmp(msg, "transport_relocate") == 0)
  1615. {
  1616. uint64_t frame;
  1617. CARLA_SAFE_ASSERT_RETURN(readNextLineAsULong(frame), true);
  1618. fEngine->transportRelocate(frame);
  1619. }
  1620. else if (std::strcmp(msg, "add_plugin") == 0)
  1621. {
  1622. uint32_t btype, ptype;
  1623. const char* filename = nullptr;
  1624. const char* name;
  1625. const char* label;
  1626. int64_t uniqueId;
  1627. uint options;
  1628. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(btype), true);
  1629. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(ptype), true);
  1630. readNextLineAsString(filename, true); // can be null
  1631. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(name, true), true);
  1632. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(label, true), true);
  1633. CARLA_SAFE_ASSERT_RETURN(readNextLineAsLong(uniqueId), true);
  1634. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(options), true);
  1635. if (filename != nullptr && std::strcmp(filename, "(null)") == 0)
  1636. {
  1637. std::free(const_cast<char*>(filename));
  1638. filename = nullptr;
  1639. }
  1640. if (std::strcmp(name, "(null)") == 0)
  1641. {
  1642. std::free(const_cast<char*>(name));
  1643. name = nullptr;
  1644. }
  1645. ok = fEngine->addPlugin(static_cast<BinaryType>(btype), static_cast<PluginType>(ptype),
  1646. filename, name, label, uniqueId, nullptr, options);
  1647. if (filename != nullptr)
  1648. std::free(const_cast<char*>(filename));
  1649. if (name != nullptr)
  1650. std::free(const_cast<char*>(name));
  1651. std::free(const_cast<char*>(label));
  1652. fEngine->reloadFromUI();
  1653. }
  1654. else if (std::strcmp(msg, "remove_plugin") == 0)
  1655. {
  1656. uint32_t pluginId;
  1657. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1658. ok = fEngine->removePlugin(pluginId);
  1659. fEngine->reloadFromUI();
  1660. }
  1661. else if (std::strcmp(msg, "remove_all_plugins") == 0)
  1662. {
  1663. ok = fEngine->removeAllPlugins();
  1664. fEngine->reloadFromUI();
  1665. }
  1666. else if (std::strcmp(msg, "rename_plugin") == 0)
  1667. {
  1668. uint32_t pluginId;
  1669. const char* newName;
  1670. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1671. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName, false), true);
  1672. ok = fEngine->renamePlugin(pluginId, newName);
  1673. }
  1674. else if (std::strcmp(msg, "clone_plugin") == 0)
  1675. {
  1676. uint32_t pluginId;
  1677. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1678. ok = fEngine->clonePlugin(pluginId);
  1679. fEngine->reloadFromUI();
  1680. }
  1681. else if (std::strcmp(msg, "replace_plugin") == 0)
  1682. {
  1683. uint32_t pluginId;
  1684. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1685. ok = fEngine->replacePlugin(pluginId);
  1686. }
  1687. else if (std::strcmp(msg, "switch_plugins") == 0)
  1688. {
  1689. uint32_t pluginIdA, pluginIdB;
  1690. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdA), true);
  1691. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginIdB), true);
  1692. ok = fEngine->switchPlugins(pluginIdA, pluginIdB);
  1693. fEngine->reloadFromUI();
  1694. }
  1695. else if (std::strcmp(msg, "load_plugin_state") == 0)
  1696. {
  1697. uint32_t pluginId;
  1698. const char* filename;
  1699. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1700. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
  1701. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1702. {
  1703. plugin->loadStateFromFile(filename);
  1704. _updateParamValues(plugin, pluginId, false, true);
  1705. }
  1706. }
  1707. else if (std::strcmp(msg, "save_plugin_state") == 0)
  1708. {
  1709. uint32_t pluginId;
  1710. const char* filename;
  1711. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1712. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(filename, false), true);
  1713. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1714. plugin->saveStateToFile(filename);
  1715. }
  1716. else if (std::strcmp(msg, "set_option") == 0)
  1717. {
  1718. uint32_t pluginId, option;
  1719. bool yesNo;
  1720. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1721. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(option), true);
  1722. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
  1723. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1724. plugin->setOption(option, yesNo, false);
  1725. }
  1726. else if (std::strcmp(msg, "set_active") == 0)
  1727. {
  1728. uint32_t pluginId;
  1729. bool onOff;
  1730. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1731. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(onOff), true);
  1732. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1733. plugin->setActive(onOff, true, false);
  1734. }
  1735. else if (std::strcmp(msg, "set_drywet") == 0)
  1736. {
  1737. uint32_t pluginId;
  1738. float value;
  1739. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1740. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1741. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1742. plugin->setDryWet(value, true, false);
  1743. }
  1744. else if (std::strcmp(msg, "set_volume") == 0)
  1745. {
  1746. uint32_t pluginId;
  1747. float value;
  1748. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1749. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1750. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1751. plugin->setVolume(value, true, false);
  1752. }
  1753. else if (std::strcmp(msg, "set_balance_left") == 0)
  1754. {
  1755. uint32_t pluginId;
  1756. float value;
  1757. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1758. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1759. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1760. plugin->setBalanceLeft(value, true, false);
  1761. }
  1762. else if (std::strcmp(msg, "set_balance_right") == 0)
  1763. {
  1764. uint32_t pluginId;
  1765. float value;
  1766. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1767. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1768. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1769. plugin->setBalanceRight(value, true, false);
  1770. }
  1771. else if (std::strcmp(msg, "set_panning") == 0)
  1772. {
  1773. uint32_t pluginId;
  1774. float value;
  1775. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1776. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1777. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1778. plugin->setPanning(value, true, false);
  1779. }
  1780. else if (std::strcmp(msg, "set_ctrl_channel") == 0)
  1781. {
  1782. uint32_t pluginId;
  1783. int32_t channel;
  1784. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1785. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(channel), true);
  1786. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS, true);
  1787. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1788. plugin->setCtrlChannel(int8_t(channel), true, false);
  1789. }
  1790. else if (std::strcmp(msg, "set_parameter_value") == 0)
  1791. {
  1792. uint32_t pluginId, parameterId;
  1793. float value;
  1794. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1795. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
  1796. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(value), true);
  1797. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1798. {
  1799. plugin->setParameterValue(parameterId, value, true, true, false);
  1800. fEngine->setParameterValueFromUI(pluginId, parameterId, value);
  1801. }
  1802. }
  1803. else if (std::strcmp(msg, "set_parameter_midi_channel") == 0)
  1804. {
  1805. uint32_t pluginId, parameterId, channel;
  1806. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1807. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
  1808. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
  1809. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
  1810. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1811. plugin->setParameterMidiChannel(parameterId, static_cast<uint8_t>(channel), true, false);
  1812. }
  1813. else if (std::strcmp(msg, "set_parameter_mapped_control_index") == 0)
  1814. {
  1815. uint32_t pluginId, parameterId;
  1816. int32_t ctrl;
  1817. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1818. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
  1819. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(ctrl), true);
  1820. CARLA_SAFE_ASSERT_RETURN(ctrl >= CONTROL_INDEX_NONE && ctrl <= CONTROL_INDEX_MAX_ALLOWED, true);
  1821. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1822. plugin->setParameterMappedControlIndex(parameterId, static_cast<int16_t>(ctrl), true, false, true);
  1823. }
  1824. else if (std::strcmp(msg, "set_parameter_mapped_range") == 0)
  1825. {
  1826. uint32_t pluginId, parameterId;
  1827. float minimum, maximum;
  1828. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1829. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
  1830. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(minimum), true);
  1831. CARLA_SAFE_ASSERT_RETURN(readNextLineAsFloat(maximum), true);
  1832. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1833. plugin->setParameterMappedRange(parameterId, minimum, maximum, true, false);
  1834. }
  1835. else if (std::strcmp(msg, "set_parameter_touch") == 0)
  1836. {
  1837. uint32_t pluginId, parameterId;
  1838. bool touching;
  1839. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1840. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true);
  1841. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(touching), true);
  1842. if (fEngine->getPlugin(pluginId))
  1843. fEngine->setParameterTouchFromUI(pluginId, parameterId, touching);
  1844. }
  1845. else if (std::strcmp(msg, "set_program") == 0)
  1846. {
  1847. uint32_t pluginId;
  1848. int32_t index;
  1849. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1850. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
  1851. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1852. {
  1853. plugin->setProgram(index, true, true, false);
  1854. _updateParamValues(plugin, pluginId, true, true);
  1855. }
  1856. }
  1857. else if (std::strcmp(msg, "set_midi_program") == 0)
  1858. {
  1859. uint32_t pluginId;
  1860. int32_t index;
  1861. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1862. CARLA_SAFE_ASSERT_RETURN(readNextLineAsInt(index), true);
  1863. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1864. {
  1865. plugin->setMidiProgram(index, true, true, false);
  1866. _updateParamValues(plugin, pluginId, true, true);
  1867. }
  1868. }
  1869. else if (std::strcmp(msg, "set_custom_data") == 0)
  1870. {
  1871. uint32_t pluginId;
  1872. const char* type;
  1873. const char* key;
  1874. const char* value;
  1875. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1876. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(type, true), true);
  1877. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(key, true), true);
  1878. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(value, false), true);
  1879. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1880. plugin->setCustomData(type, key, value, true);
  1881. std::free(const_cast<char*>(type));
  1882. std::free(const_cast<char*>(key));
  1883. }
  1884. else if (std::strcmp(msg, "set_chunk_data") == 0)
  1885. {
  1886. uint32_t pluginId;
  1887. const char* cdata;
  1888. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1889. CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(cdata, false), true);
  1890. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1891. {
  1892. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(cdata));
  1893. #ifdef CARLA_PROPER_CPP11_SUPPORT
  1894. plugin->setChunkData(chunk.data(), chunk.size());
  1895. #else
  1896. plugin->setChunkData(&chunk.front(), chunk.size());
  1897. #endif
  1898. _updateParamValues(plugin, pluginId, false, true);
  1899. }
  1900. }
  1901. else if (std::strcmp(msg, "prepare_for_save") == 0)
  1902. {
  1903. uint32_t pluginId;
  1904. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1905. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1906. plugin->prepareForSave(false);
  1907. }
  1908. else if (std::strcmp(msg, "reset_parameters") == 0)
  1909. {
  1910. uint32_t pluginId;
  1911. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1912. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1913. {
  1914. plugin->resetParameters();
  1915. _updateParamValues(plugin, pluginId, false, true);
  1916. }
  1917. }
  1918. else if (std::strcmp(msg, "randomize_parameters") == 0)
  1919. {
  1920. uint32_t pluginId;
  1921. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1922. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1923. {
  1924. plugin->randomizeParameters();
  1925. _updateParamValues(plugin, pluginId, false, true);
  1926. }
  1927. }
  1928. else if (std::strcmp(msg, "send_midi_note") == 0)
  1929. {
  1930. uint32_t pluginId, channel, note, velocity;
  1931. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1932. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(channel), true);
  1933. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(note), true);
  1934. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(velocity), true);
  1935. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, true);
  1936. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_VALUE, true);
  1937. CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE, true);
  1938. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1939. plugin->sendMidiSingleNote(static_cast<uint8_t>(channel), static_cast<uint8_t>(note), static_cast<uint8_t>(velocity), true, true, false);
  1940. }
  1941. else if (std::strcmp(msg, "show_custom_ui") == 0)
  1942. {
  1943. uint32_t pluginId;
  1944. bool yesNo;
  1945. CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true);
  1946. CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(yesNo), true);
  1947. if (const CarlaPluginPtr plugin = fEngine->getPlugin(pluginId))
  1948. plugin->showCustomUI(yesNo);
  1949. }
  1950. else
  1951. {
  1952. carla_stderr("CarlaEngineNativeUI::msgReceived : %s", msg);
  1953. return false;
  1954. }
  1955. if (! ok)
  1956. {
  1957. const CarlaMutexLocker cml(getPipeLock());
  1958. if (writeMessage("error\n", 6) && writeAndFixMessage(fEngine->getLastError()))
  1959. flushMessages();
  1960. }
  1961. return true;
  1962. }
  1963. void CarlaEngineNativeUI::_updateParamValues(const CarlaPluginPtr& plugin,
  1964. const uint32_t pluginId,
  1965. const bool sendCallback, const bool sendPluginHost) const noexcept
  1966. {
  1967. float value;
  1968. for (uint32_t i=0, count=plugin->getParameterCount(); i<count; ++i) {
  1969. value = plugin->getParameterValue(i);
  1970. if (sendCallback) {
  1971. fEngine->callback(true, true,
  1972. ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1973. pluginId,
  1974. static_cast<int>(i),
  1975. 0, 0,
  1976. value,
  1977. nullptr);
  1978. }
  1979. if (sendPluginHost) {
  1980. carla_stdout("_updateParamValues");
  1981. fEngine->setParameterValueFromUI(pluginId, i, value);
  1982. }
  1983. }
  1984. }
  1985. #endif
  1986. // -----------------------------------------------------------------------
  1987. static const NativePluginDescriptor carlaRackDesc = {
  1988. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  1989. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  1990. |NATIVE_PLUGIN_HAS_UI
  1991. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  1992. |NATIVE_PLUGIN_USES_STATE
  1993. |NATIVE_PLUGIN_USES_TIME
  1994. |NATIVE_PLUGIN_USES_UI_SIZE),
  1995. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  1996. /* audioIns */ 2,
  1997. /* audioOuts */ 2,
  1998. /* midiIns */ 1,
  1999. /* midiOuts */ 1,
  2000. /* paramIns */ kNumInParams,
  2001. /* paramOuts */ kNumOutParams,
  2002. /* name */ "Carla-Rack",
  2003. /* label */ "carlarack",
  2004. /* maker */ "falkTX",
  2005. /* copyright */ "GNU GPL v2+",
  2006. CarlaEngineNative::_instantiateRack,
  2007. CarlaEngineNative::_cleanup,
  2008. CarlaEngineNative::_get_parameter_count,
  2009. CarlaEngineNative::_get_parameter_info,
  2010. CarlaEngineNative::_get_parameter_value,
  2011. /* _get_midi_program_count */ nullptr,
  2012. /* _get_midi_program_info */ nullptr,
  2013. CarlaEngineNative::_set_parameter_value,
  2014. /* _set_midi_program */ nullptr,
  2015. /* _set_custom_data */ nullptr,
  2016. #ifndef CARLA_ENGINE_WITHOUT_UI
  2017. CarlaEngineNative::_ui_show,
  2018. #else
  2019. nullptr,
  2020. #endif
  2021. CarlaEngineNative::_ui_idle,
  2022. CarlaEngineNative::_ui_set_parameter_value,
  2023. /* _ui_set_midi_program */ nullptr,
  2024. /* _ui_set_custom_data */ nullptr,
  2025. CarlaEngineNative::_activate,
  2026. CarlaEngineNative::_deactivate,
  2027. CarlaEngineNative::_process,
  2028. CarlaEngineNative::_get_state,
  2029. CarlaEngineNative::_set_state,
  2030. CarlaEngineNative::_dispatcher,
  2031. /* _render_inline_dsplay */ nullptr,
  2032. /* cvIns */ 0,
  2033. /* cvOuts */ 0,
  2034. /* _get_buffer_port_name */ nullptr,
  2035. /* _get_buffer_port_range */ nullptr,
  2036. /* ui_width */ kUiWidth,
  2037. /* ui_height */ kUiHeight
  2038. };
  2039. static const NativePluginDescriptor carlaRackNoMidiOutDesc = {
  2040. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2041. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2042. |NATIVE_PLUGIN_HAS_UI
  2043. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2044. |NATIVE_PLUGIN_USES_STATE
  2045. |NATIVE_PLUGIN_USES_TIME
  2046. |NATIVE_PLUGIN_USES_UI_SIZE),
  2047. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2048. /* audioIns */ 2,
  2049. /* audioOuts */ 2,
  2050. /* midiIns */ 1,
  2051. /* midiOuts */ 0,
  2052. /* paramIns */ kNumInParams,
  2053. /* paramOuts */ kNumOutParams,
  2054. /* name */ "Carla-Rack (no midi out)",
  2055. /* label */ "carlarack-nomidiout",
  2056. /* maker */ "falkTX",
  2057. /* copyright */ "GNU GPL v2+",
  2058. CarlaEngineNative::_instantiateRackNoMidiOut,
  2059. CarlaEngineNative::_cleanup,
  2060. CarlaEngineNative::_get_parameter_count,
  2061. CarlaEngineNative::_get_parameter_info,
  2062. CarlaEngineNative::_get_parameter_value,
  2063. /* _get_midi_program_count */ nullptr,
  2064. /* _get_midi_program_info */ nullptr,
  2065. CarlaEngineNative::_set_parameter_value,
  2066. /* _set_midi_program */ nullptr,
  2067. /* _set_custom_data */ nullptr,
  2068. #ifndef CARLA_ENGINE_WITHOUT_UI
  2069. CarlaEngineNative::_ui_show,
  2070. #else
  2071. nullptr,
  2072. #endif
  2073. CarlaEngineNative::_ui_idle,
  2074. CarlaEngineNative::_ui_set_parameter_value,
  2075. /* _ui_set_midi_program */ nullptr,
  2076. /* _ui_set_custom_data */ nullptr,
  2077. CarlaEngineNative::_activate,
  2078. CarlaEngineNative::_deactivate,
  2079. CarlaEngineNative::_process,
  2080. CarlaEngineNative::_get_state,
  2081. CarlaEngineNative::_set_state,
  2082. CarlaEngineNative::_dispatcher,
  2083. /* _render_inline_dsplay */ nullptr,
  2084. /* cvIns */ 0,
  2085. /* cvOuts */ 0,
  2086. /* _get_buffer_port_name */ nullptr,
  2087. /* _get_buffer_port_range */ nullptr,
  2088. /* ui_width */ kUiWidth,
  2089. /* ui_height */ kUiHeight
  2090. };
  2091. static const NativePluginDescriptor carlaPatchbayDesc = {
  2092. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2093. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2094. |NATIVE_PLUGIN_HAS_UI
  2095. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2096. |NATIVE_PLUGIN_USES_STATE
  2097. |NATIVE_PLUGIN_USES_TIME
  2098. |NATIVE_PLUGIN_USES_UI_SIZE),
  2099. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2100. /* audioIns */ 2,
  2101. /* audioOuts */ 2,
  2102. /* midiIns */ 1,
  2103. /* midiOuts */ 1,
  2104. /* paramIns */ kNumInParams,
  2105. /* paramOuts */ kNumOutParams,
  2106. /* name */ "Carla-Patchbay",
  2107. /* label */ "carlapatchbay",
  2108. /* maker */ "falkTX",
  2109. /* copyright */ "GNU GPL v2+",
  2110. CarlaEngineNative::_instantiatePatchbay,
  2111. CarlaEngineNative::_cleanup,
  2112. CarlaEngineNative::_get_parameter_count,
  2113. CarlaEngineNative::_get_parameter_info,
  2114. CarlaEngineNative::_get_parameter_value,
  2115. /* _get_midi_program_count */ nullptr,
  2116. /* _get_midi_program_info */ nullptr,
  2117. CarlaEngineNative::_set_parameter_value,
  2118. /* _set_midi_program */ nullptr,
  2119. /* _set_custom_data */ nullptr,
  2120. #ifndef CARLA_ENGINE_WITHOUT_UI
  2121. CarlaEngineNative::_ui_show,
  2122. #else
  2123. nullptr,
  2124. #endif
  2125. CarlaEngineNative::_ui_idle,
  2126. CarlaEngineNative::_ui_set_parameter_value,
  2127. /* _ui_set_midi_program */ nullptr,
  2128. /* _ui_set_custom_data */ nullptr,
  2129. CarlaEngineNative::_activate,
  2130. CarlaEngineNative::_deactivate,
  2131. CarlaEngineNative::_process,
  2132. CarlaEngineNative::_get_state,
  2133. CarlaEngineNative::_set_state,
  2134. CarlaEngineNative::_dispatcher,
  2135. /* _render_inline_dsplay */ nullptr,
  2136. /* cvIns */ 0,
  2137. /* cvOuts */ 0,
  2138. /* _get_buffer_port_name */ nullptr,
  2139. /* _get_buffer_port_range */ nullptr,
  2140. /* ui_width */ kUiWidth,
  2141. /* ui_height */ kUiHeight
  2142. };
  2143. static const NativePluginDescriptor carlaPatchbay3sDesc = {
  2144. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2145. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2146. |NATIVE_PLUGIN_HAS_UI
  2147. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2148. |NATIVE_PLUGIN_USES_STATE
  2149. |NATIVE_PLUGIN_USES_TIME
  2150. |NATIVE_PLUGIN_USES_UI_SIZE),
  2151. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2152. /* audioIns */ 3,
  2153. /* audioOuts */ 2,
  2154. /* midiIns */ 1,
  2155. /* midiOuts */ 1,
  2156. /* paramIns */ kNumInParams,
  2157. /* paramOuts */ kNumOutParams,
  2158. /* name */ "Carla-Patchbay (sidechain)",
  2159. /* label */ "carlapatchbay3s",
  2160. /* maker */ "falkTX",
  2161. /* copyright */ "GNU GPL v2+",
  2162. CarlaEngineNative::_instantiatePatchbay3s,
  2163. CarlaEngineNative::_cleanup,
  2164. CarlaEngineNative::_get_parameter_count,
  2165. CarlaEngineNative::_get_parameter_info,
  2166. CarlaEngineNative::_get_parameter_value,
  2167. /* _get_midi_program_count */ nullptr,
  2168. /* _get_midi_program_info */ nullptr,
  2169. CarlaEngineNative::_set_parameter_value,
  2170. /* _set_midi_program */ nullptr,
  2171. /* _set_custom_data */ nullptr,
  2172. #ifndef CARLA_ENGINE_WITHOUT_UI
  2173. CarlaEngineNative::_ui_show,
  2174. #else
  2175. nullptr,
  2176. #endif
  2177. CarlaEngineNative::_ui_idle,
  2178. CarlaEngineNative::_ui_set_parameter_value,
  2179. /* _ui_set_midi_program */ nullptr,
  2180. /* _ui_set_custom_data */ nullptr,
  2181. CarlaEngineNative::_activate,
  2182. CarlaEngineNative::_deactivate,
  2183. CarlaEngineNative::_process,
  2184. CarlaEngineNative::_get_state,
  2185. CarlaEngineNative::_set_state,
  2186. CarlaEngineNative::_dispatcher,
  2187. /* _render_inline_dsplay */ nullptr,
  2188. /* cvIns */ 0,
  2189. /* cvOuts */ 0,
  2190. /* _get_buffer_port_name */ nullptr,
  2191. /* _get_buffer_port_range */ nullptr,
  2192. /* ui_width */ kUiWidth,
  2193. /* ui_height */ kUiHeight
  2194. };
  2195. static const NativePluginDescriptor carlaPatchbay16Desc = {
  2196. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2197. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2198. |NATIVE_PLUGIN_HAS_UI
  2199. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2200. |NATIVE_PLUGIN_USES_STATE
  2201. |NATIVE_PLUGIN_USES_TIME
  2202. |NATIVE_PLUGIN_USES_UI_SIZE),
  2203. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2204. /* audioIns */ 16,
  2205. /* audioOuts */ 16,
  2206. /* midiIns */ 1,
  2207. /* midiOuts */ 1,
  2208. /* paramIns */ kNumInParams,
  2209. /* paramOuts */ kNumOutParams,
  2210. /* name */ "Carla-Patchbay (16chan)",
  2211. /* label */ "carlapatchbay16",
  2212. /* maker */ "falkTX",
  2213. /* copyright */ "GNU GPL v2+",
  2214. CarlaEngineNative::_instantiatePatchbay16,
  2215. CarlaEngineNative::_cleanup,
  2216. CarlaEngineNative::_get_parameter_count,
  2217. CarlaEngineNative::_get_parameter_info,
  2218. CarlaEngineNative::_get_parameter_value,
  2219. /* _get_midi_program_count */ nullptr,
  2220. /* _get_midi_program_info */ nullptr,
  2221. CarlaEngineNative::_set_parameter_value,
  2222. /* _set_midi_program */ nullptr,
  2223. /* _set_custom_data */ nullptr,
  2224. #ifndef CARLA_ENGINE_WITHOUT_UI
  2225. CarlaEngineNative::_ui_show,
  2226. #else
  2227. nullptr,
  2228. #endif
  2229. CarlaEngineNative::_ui_idle,
  2230. CarlaEngineNative::_ui_set_parameter_value,
  2231. /* _ui_set_midi_program */ nullptr,
  2232. /* _ui_set_custom_data */ nullptr,
  2233. CarlaEngineNative::_activate,
  2234. CarlaEngineNative::_deactivate,
  2235. CarlaEngineNative::_process,
  2236. CarlaEngineNative::_get_state,
  2237. CarlaEngineNative::_set_state,
  2238. CarlaEngineNative::_dispatcher,
  2239. /* _render_inline_dsplay */ nullptr,
  2240. /* cvIns */ 0,
  2241. /* cvOuts */ 0,
  2242. /* _get_buffer_port_name */ nullptr,
  2243. /* _get_buffer_port_range */ nullptr,
  2244. /* ui_width */ kUiWidth,
  2245. /* ui_height */ kUiHeight
  2246. };
  2247. static const NativePluginDescriptor carlaPatchbay32Desc = {
  2248. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2249. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2250. |NATIVE_PLUGIN_HAS_UI
  2251. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2252. |NATIVE_PLUGIN_USES_STATE
  2253. |NATIVE_PLUGIN_USES_TIME
  2254. |NATIVE_PLUGIN_USES_UI_SIZE),
  2255. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2256. /* audioIns */ 32,
  2257. /* audioOuts */ 32,
  2258. /* midiIns */ 1,
  2259. /* midiOuts */ 1,
  2260. /* paramIns */ kNumInParams,
  2261. /* paramOuts */ kNumOutParams,
  2262. /* name */ "Carla-Patchbay (32chan)",
  2263. /* label */ "carlapatchbay32",
  2264. /* maker */ "falkTX",
  2265. /* copyright */ "GNU GPL v2+",
  2266. CarlaEngineNative::_instantiatePatchbay32,
  2267. CarlaEngineNative::_cleanup,
  2268. CarlaEngineNative::_get_parameter_count,
  2269. CarlaEngineNative::_get_parameter_info,
  2270. CarlaEngineNative::_get_parameter_value,
  2271. /* _get_midi_program_count */ nullptr,
  2272. /* _get_midi_program_info */ nullptr,
  2273. CarlaEngineNative::_set_parameter_value,
  2274. /* _set_midi_program */ nullptr,
  2275. /* _set_custom_data */ nullptr,
  2276. #ifndef CARLA_ENGINE_WITHOUT_UI
  2277. CarlaEngineNative::_ui_show,
  2278. #else
  2279. nullptr,
  2280. #endif
  2281. CarlaEngineNative::_ui_idle,
  2282. CarlaEngineNative::_ui_set_parameter_value,
  2283. /* _ui_set_midi_program */ nullptr,
  2284. /* _ui_set_custom_data */ nullptr,
  2285. CarlaEngineNative::_activate,
  2286. CarlaEngineNative::_deactivate,
  2287. CarlaEngineNative::_process,
  2288. CarlaEngineNative::_get_state,
  2289. CarlaEngineNative::_set_state,
  2290. CarlaEngineNative::_dispatcher,
  2291. /* _render_inline_dsplay */ nullptr,
  2292. /* cvIns */ 0,
  2293. /* cvOuts */ 0,
  2294. /* _get_buffer_port_name */ nullptr,
  2295. /* _get_buffer_port_range */ nullptr,
  2296. /* ui_width */ kUiWidth,
  2297. /* ui_height */ kUiHeight
  2298. };
  2299. static const NativePluginDescriptor carlaPatchbay64Desc = {
  2300. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2301. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2302. |NATIVE_PLUGIN_HAS_UI
  2303. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2304. |NATIVE_PLUGIN_USES_STATE
  2305. |NATIVE_PLUGIN_USES_TIME
  2306. |NATIVE_PLUGIN_USES_UI_SIZE),
  2307. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2308. /* audioIns */ 64,
  2309. /* audioOuts */ 64,
  2310. /* midiIns */ 1,
  2311. /* midiOuts */ 1,
  2312. /* paramIns */ kNumInParams,
  2313. /* paramOuts */ kNumOutParams,
  2314. /* name */ "Carla-Patchbay (64chan)",
  2315. /* label */ "carlapatchbay64",
  2316. /* maker */ "falkTX",
  2317. /* copyright */ "GNU GPL v2+",
  2318. CarlaEngineNative::_instantiatePatchbay64,
  2319. CarlaEngineNative::_cleanup,
  2320. CarlaEngineNative::_get_parameter_count,
  2321. CarlaEngineNative::_get_parameter_info,
  2322. CarlaEngineNative::_get_parameter_value,
  2323. /* _get_midi_program_count */ nullptr,
  2324. /* _get_midi_program_info */ nullptr,
  2325. CarlaEngineNative::_set_parameter_value,
  2326. /* _set_midi_program */ nullptr,
  2327. /* _set_custom_data */ nullptr,
  2328. #ifndef CARLA_ENGINE_WITHOUT_UI
  2329. CarlaEngineNative::_ui_show,
  2330. #else
  2331. nullptr,
  2332. #endif
  2333. CarlaEngineNative::_ui_idle,
  2334. CarlaEngineNative::_ui_set_parameter_value,
  2335. /* _ui_set_midi_program */ nullptr,
  2336. /* _ui_set_custom_data */ nullptr,
  2337. CarlaEngineNative::_activate,
  2338. CarlaEngineNative::_deactivate,
  2339. CarlaEngineNative::_process,
  2340. CarlaEngineNative::_get_state,
  2341. CarlaEngineNative::_set_state,
  2342. CarlaEngineNative::_dispatcher,
  2343. /* _render_inline_dsplay */ nullptr,
  2344. /* cvIns */ 0,
  2345. /* cvOuts */ 0,
  2346. /* _get_buffer_port_name */ nullptr,
  2347. /* _get_buffer_port_range */ nullptr,
  2348. /* ui_width */ kUiWidth,
  2349. /* ui_height */ kUiHeight
  2350. };
  2351. static const NativePluginDescriptor carlaPatchbayCVDesc = {
  2352. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2353. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2354. |NATIVE_PLUGIN_HAS_UI
  2355. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2356. |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
  2357. |NATIVE_PLUGIN_USES_STATE
  2358. |NATIVE_PLUGIN_USES_TIME
  2359. |NATIVE_PLUGIN_USES_UI_SIZE),
  2360. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2361. /* audioIns */ 2,
  2362. /* audioOuts */ 2,
  2363. /* midiIns */ 1,
  2364. /* midiOuts */ 1,
  2365. /* paramIns */ kNumInParams,
  2366. /* paramOuts */ kNumOutParams,
  2367. /* name */ "Carla-Patchbay (CV)",
  2368. /* label */ "carlapatchbaycv",
  2369. /* maker */ "falkTX",
  2370. /* copyright */ "GNU GPL v2+",
  2371. CarlaEngineNative::_instantiatePatchbayCV,
  2372. CarlaEngineNative::_cleanup,
  2373. CarlaEngineNative::_get_parameter_count,
  2374. CarlaEngineNative::_get_parameter_info,
  2375. CarlaEngineNative::_get_parameter_value,
  2376. /* _get_midi_program_count */ nullptr,
  2377. /* _get_midi_program_info */ nullptr,
  2378. CarlaEngineNative::_set_parameter_value,
  2379. /* _set_midi_program */ nullptr,
  2380. /* _set_custom_data */ nullptr,
  2381. #ifndef CARLA_ENGINE_WITHOUT_UI
  2382. CarlaEngineNative::_ui_show,
  2383. #else
  2384. nullptr,
  2385. #endif
  2386. CarlaEngineNative::_ui_idle,
  2387. CarlaEngineNative::_ui_set_parameter_value,
  2388. /* _ui_set_midi_program */ nullptr,
  2389. /* _ui_set_custom_data */ nullptr,
  2390. CarlaEngineNative::_activate,
  2391. CarlaEngineNative::_deactivate,
  2392. CarlaEngineNative::_process,
  2393. CarlaEngineNative::_get_state,
  2394. CarlaEngineNative::_set_state,
  2395. CarlaEngineNative::_dispatcher,
  2396. /* _render_inline_dsplay */ nullptr,
  2397. /* cvIns */ 5,
  2398. /* cvOuts */ 5,
  2399. /* _get_buffer_port_name */ nullptr,
  2400. /* _get_buffer_port_range */ nullptr,
  2401. /* ui_width */ kUiWidth,
  2402. /* ui_height */ kUiHeight
  2403. };
  2404. static const NativePluginDescriptor carlaPatchbayCV8Desc = {
  2405. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2406. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2407. |NATIVE_PLUGIN_HAS_UI
  2408. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2409. |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
  2410. |NATIVE_PLUGIN_USES_STATE
  2411. |NATIVE_PLUGIN_USES_TIME
  2412. |NATIVE_PLUGIN_USES_UI_SIZE),
  2413. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2414. /* audioIns */ 2,
  2415. /* audioOuts */ 2,
  2416. /* midiIns */ 1,
  2417. /* midiOuts */ 1,
  2418. /* paramIns */ kNumInParams,
  2419. /* paramOuts */ kNumOutParams,
  2420. /* name */ "Carla-Patchbay (CV8)",
  2421. /* label */ "carlapatchbaycv",
  2422. /* maker */ "falkTX",
  2423. /* copyright */ "GNU GPL v2+",
  2424. CarlaEngineNative::_instantiatePatchbayCV8,
  2425. CarlaEngineNative::_cleanup,
  2426. CarlaEngineNative::_get_parameter_count,
  2427. CarlaEngineNative::_get_parameter_info,
  2428. CarlaEngineNative::_get_parameter_value,
  2429. /* _get_midi_program_count */ nullptr,
  2430. /* _get_midi_program_info */ nullptr,
  2431. CarlaEngineNative::_set_parameter_value,
  2432. /* _set_midi_program */ nullptr,
  2433. /* _set_custom_data */ nullptr,
  2434. #ifndef CARLA_ENGINE_WITHOUT_UI
  2435. CarlaEngineNative::_ui_show,
  2436. #else
  2437. nullptr,
  2438. #endif
  2439. CarlaEngineNative::_ui_idle,
  2440. CarlaEngineNative::_ui_set_parameter_value,
  2441. /* _ui_set_midi_program */ nullptr,
  2442. /* _ui_set_custom_data */ nullptr,
  2443. CarlaEngineNative::_activate,
  2444. CarlaEngineNative::_deactivate,
  2445. CarlaEngineNative::_process,
  2446. CarlaEngineNative::_get_state,
  2447. CarlaEngineNative::_set_state,
  2448. CarlaEngineNative::_dispatcher,
  2449. /* _render_inline_dsplay */ nullptr,
  2450. /* cvIns */ 8,
  2451. /* cvOuts */ 8,
  2452. /* _get_buffer_port_name */ nullptr,
  2453. /* _get_buffer_port_range */ nullptr,
  2454. /* ui_width */ kUiWidth,
  2455. /* ui_height */ kUiHeight
  2456. };
  2457. static const NativePluginDescriptor carlaPatchbayCV32Desc = {
  2458. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2459. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2460. |NATIVE_PLUGIN_HAS_UI
  2461. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2462. |NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
  2463. |NATIVE_PLUGIN_USES_STATE
  2464. |NATIVE_PLUGIN_USES_TIME
  2465. |NATIVE_PLUGIN_USES_UI_SIZE),
  2466. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2467. /* audioIns */ 64,
  2468. /* audioOuts */ 64,
  2469. /* midiIns */ 1,
  2470. /* midiOuts */ 1,
  2471. /* paramIns */ kNumInParams,
  2472. /* paramOuts */ kNumOutParams,
  2473. /* name */ "Carla-Patchbay (CV32)",
  2474. /* label */ "carlapatchbaycv",
  2475. /* maker */ "falkTX",
  2476. /* copyright */ "GNU GPL v2+",
  2477. CarlaEngineNative::_instantiatePatchbayCV32,
  2478. CarlaEngineNative::_cleanup,
  2479. CarlaEngineNative::_get_parameter_count,
  2480. CarlaEngineNative::_get_parameter_info,
  2481. CarlaEngineNative::_get_parameter_value,
  2482. /* _get_midi_program_count */ nullptr,
  2483. /* _get_midi_program_info */ nullptr,
  2484. CarlaEngineNative::_set_parameter_value,
  2485. /* _set_midi_program */ nullptr,
  2486. /* _set_custom_data */ nullptr,
  2487. #ifndef CARLA_ENGINE_WITHOUT_UI
  2488. CarlaEngineNative::_ui_show,
  2489. #else
  2490. nullptr,
  2491. #endif
  2492. CarlaEngineNative::_ui_idle,
  2493. CarlaEngineNative::_ui_set_parameter_value,
  2494. /* _ui_set_midi_program */ nullptr,
  2495. /* _ui_set_custom_data */ nullptr,
  2496. CarlaEngineNative::_activate,
  2497. CarlaEngineNative::_deactivate,
  2498. CarlaEngineNative::_process,
  2499. CarlaEngineNative::_get_state,
  2500. CarlaEngineNative::_set_state,
  2501. CarlaEngineNative::_dispatcher,
  2502. /* _render_inline_dsplay */ nullptr,
  2503. /* cvIns */ 32,
  2504. /* cvOuts */ 32,
  2505. /* _get_buffer_port_name */ nullptr,
  2506. /* _get_buffer_port_range */ nullptr,
  2507. /* ui_width */ kUiWidth,
  2508. /* ui_height */ kUiHeight
  2509. };
  2510. static const NativePluginDescriptor carlaPatchbayOBS = {
  2511. /* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
  2512. /* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH
  2513. |NATIVE_PLUGIN_HAS_UI
  2514. |NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD
  2515. |NATIVE_PLUGIN_USES_STATE
  2516. |NATIVE_PLUGIN_USES_TIME
  2517. |NATIVE_PLUGIN_USES_UI_SIZE),
  2518. /* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING),
  2519. /* audioIns */ 8,
  2520. /* audioOuts */ 8,
  2521. /* midiIns */ 0,
  2522. /* midiOuts */ 0,
  2523. /* paramIns */ kNumInParams,
  2524. /* paramOuts */ kNumOutParams,
  2525. /* name */ "Carla-Patchbay (OBS)",
  2526. /* label */ "carlapatchbayOBS",
  2527. /* maker */ "falkTX",
  2528. /* copyright */ "GNU GPL v2+",
  2529. CarlaEngineNative::_instantiatePatchbayOBS,
  2530. CarlaEngineNative::_cleanup,
  2531. CarlaEngineNative::_get_parameter_count,
  2532. CarlaEngineNative::_get_parameter_info,
  2533. CarlaEngineNative::_get_parameter_value,
  2534. /* _get_midi_program_count */ nullptr,
  2535. /* _get_midi_program_info */ nullptr,
  2536. CarlaEngineNative::_set_parameter_value,
  2537. /* _set_midi_program */ nullptr,
  2538. /* _set_custom_data */ nullptr,
  2539. #ifndef CARLA_ENGINE_WITHOUT_UI
  2540. CarlaEngineNative::_ui_show,
  2541. #else
  2542. nullptr,
  2543. #endif
  2544. CarlaEngineNative::_ui_idle,
  2545. CarlaEngineNative::_ui_set_parameter_value,
  2546. /* _ui_set_midi_program */ nullptr,
  2547. /* _ui_set_custom_data */ nullptr,
  2548. CarlaEngineNative::_activate,
  2549. CarlaEngineNative::_deactivate,
  2550. CarlaEngineNative::_process,
  2551. CarlaEngineNative::_get_state,
  2552. CarlaEngineNative::_set_state,
  2553. CarlaEngineNative::_dispatcher,
  2554. /* _render_inline_dsplay */ nullptr,
  2555. /* cvIns */ 0,
  2556. /* cvOuts */ 0,
  2557. /* _get_buffer_port_name */ nullptr,
  2558. /* _get_buffer_port_range */ nullptr,
  2559. /* ui_width */ kUiWidth,
  2560. /* ui_height */ kUiHeight
  2561. };
  2562. CARLA_BACKEND_END_NAMESPACE
  2563. // -----------------------------------------------------------------------
  2564. #ifndef STATIC_PLUGIN_TARGET
  2565. CARLA_API_EXPORT
  2566. void carla_register_native_plugin_carla();
  2567. void carla_register_native_plugin_carla()
  2568. {
  2569. CARLA_BACKEND_USE_NAMESPACE;
  2570. carla_register_native_plugin(&carlaRackDesc);
  2571. carla_register_native_plugin(&carlaRackNoMidiOutDesc);
  2572. carla_register_native_plugin(&carlaPatchbayDesc);
  2573. carla_register_native_plugin(&carlaPatchbay3sDesc);
  2574. carla_register_native_plugin(&carlaPatchbay16Desc);
  2575. carla_register_native_plugin(&carlaPatchbay32Desc);
  2576. carla_register_native_plugin(&carlaPatchbay64Desc);
  2577. carla_register_native_plugin(&carlaPatchbayCVDesc);
  2578. }
  2579. #endif
  2580. // -----------------------------------------------------------------------
  2581. const NativePluginDescriptor* carla_get_native_rack_plugin()
  2582. {
  2583. CARLA_BACKEND_USE_NAMESPACE;
  2584. return &carlaRackDesc;
  2585. }
  2586. const NativePluginDescriptor* carla_get_native_patchbay_plugin()
  2587. {
  2588. CARLA_BACKEND_USE_NAMESPACE;
  2589. return &carlaPatchbayDesc;
  2590. }
  2591. const NativePluginDescriptor* carla_get_native_patchbay16_plugin()
  2592. {
  2593. CARLA_BACKEND_USE_NAMESPACE;
  2594. return &carlaPatchbay16Desc;
  2595. }
  2596. const NativePluginDescriptor* carla_get_native_patchbay32_plugin()
  2597. {
  2598. CARLA_BACKEND_USE_NAMESPACE;
  2599. return &carlaPatchbay32Desc;
  2600. }
  2601. const NativePluginDescriptor* carla_get_native_patchbay64_plugin()
  2602. {
  2603. CARLA_BACKEND_USE_NAMESPACE;
  2604. return &carlaPatchbay64Desc;
  2605. }
  2606. const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin()
  2607. {
  2608. CARLA_BACKEND_USE_NAMESPACE;
  2609. return &carlaPatchbayCVDesc;
  2610. }
  2611. const NativePluginDescriptor* carla_get_native_patchbay_cv8_plugin()
  2612. {
  2613. CARLA_BACKEND_USE_NAMESPACE;
  2614. return &carlaPatchbayCV8Desc;
  2615. }
  2616. const NativePluginDescriptor* carla_get_native_patchbay_cv32_plugin()
  2617. {
  2618. CARLA_BACKEND_USE_NAMESPACE;
  2619. return &carlaPatchbayCV32Desc;
  2620. }
  2621. const NativePluginDescriptor* carla_get_native_patchbay_obs_plugin()
  2622. {
  2623. CARLA_BACKEND_USE_NAMESPACE;
  2624. return &carlaPatchbayOBS;
  2625. }
  2626. // -----------------------------------------------------------------------
  2627. // Extra stuff for linking purposes
  2628. #ifdef CARLA_PLUGIN_BUILD
  2629. CARLA_BACKEND_START_NAMESPACE
  2630. namespace EngineInit {
  2631. #ifdef HAVE_JACK
  2632. CarlaEngine* newJack() { return nullptr; }
  2633. #endif
  2634. #ifdef USING_JUCE_AUDIO_DEVICES
  2635. CarlaEngine* newJuce(const AudioApi) { return nullptr; }
  2636. uint getJuceApiCount() { return 0; }
  2637. const char* getJuceApiName(const uint) { return nullptr; }
  2638. const char* const* getJuceApiDeviceNames(const uint) { return nullptr; }
  2639. const EngineDriverDeviceInfo* getJuceDeviceInfo(const uint, const char* const) { return nullptr; }
  2640. bool showJuceDeviceControlPanel(const uint, const char* const) { return false; }
  2641. #endif
  2642. #ifdef USING_RTAUDIO
  2643. CarlaEngine* newRtAudio(const AudioApi) { return nullptr; }
  2644. uint getRtAudioApiCount() { return 0; }
  2645. const char* getRtAudioApiName(const uint) { return nullptr; }
  2646. const char* const* getRtAudioApiDeviceNames(const uint) { return nullptr; }
  2647. const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const uint, const char* const) { return nullptr; }
  2648. #endif
  2649. #ifdef HAVE_SDL
  2650. CarlaEngine* newSDL() { return nullptr; }
  2651. const char* const* getSDLDeviceNames() { return nullptr; }
  2652. #endif
  2653. }
  2654. CARLA_BACKEND_END_NAMESPACE
  2655. #define CARLA_PLUGIN_UI_CLASS_PREFIX Plugin
  2656. #include "CarlaPluginUI.cpp"
  2657. # undef CARLA_PLUGIN_UI_CLASS_PREFIX
  2658. #include "CarlaDssiUtils.cpp"
  2659. #include "CarlaMacUtils.cpp"
  2660. #include "CarlaPatchbayUtils.cpp"
  2661. #include "CarlaPipeUtils.cpp"
  2662. #include "CarlaProcessUtils.cpp"
  2663. #include "CarlaStateUtils.cpp"
  2664. #endif /* CARLA_PLUGIN_BUILD */
  2665. // -----------------------------------------------------------------------