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.

CarlaPlugin.cpp 89KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718
  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-2019 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 "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #include "CarlaBackendUtils.hpp"
  20. #include "CarlaBase64Utils.hpp"
  21. #include "CarlaMathUtils.hpp"
  22. #include "CarlaPluginUI.hpp"
  23. #include "CarlaStringList.hpp"
  24. #include <ctime>
  25. #include "water/files/File.h"
  26. #include "water/streams/MemoryOutputStream.h"
  27. #include "water/xml/XmlDocument.h"
  28. #include "water/xml/XmlElement.h"
  29. using water::CharPointer_UTF8;
  30. using water::File;
  31. using water::MemoryOutputStream;
  32. using water::Result;
  33. using water::String;
  34. using water::XmlDocument;
  35. using water::XmlElement;
  36. CARLA_BACKEND_START_NAMESPACE
  37. // -------------------------------------------------------------------
  38. // Fallback data
  39. static const ParameterData kParameterDataNull = { PARAMETER_UNKNOWN, 0x0, PARAMETER_NULL, -1, -1, 0 };
  40. static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f };
  41. static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr };
  42. static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };
  43. static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
  44. static const PluginPostRtEvent kPluginPostRtEventFallback = { kPluginPostRtEventNull, 0, 0, 0, 0.0f };
  45. // -------------------------------------------------------------------
  46. // ParamSymbol struct, needed for CarlaPlugin::loadStateSave()
  47. struct ParamSymbol {
  48. int32_t index;
  49. const char* symbol;
  50. ParamSymbol(const uint32_t i, const char* const s)
  51. : index(static_cast<int32_t>(i)),
  52. symbol(carla_strdup(s)) {}
  53. ~ParamSymbol() noexcept
  54. {
  55. CARLA_SAFE_ASSERT_RETURN(symbol != nullptr,)
  56. delete[] symbol;
  57. symbol = nullptr;
  58. }
  59. #ifdef CARLA_PROPER_CPP11_SUPPORT
  60. ParamSymbol() = delete;
  61. CARLA_DECLARE_NON_COPY_STRUCT(ParamSymbol)
  62. #endif
  63. };
  64. // -------------------------------------------------------------------
  65. // Constructor and destructor
  66. CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const uint id)
  67. : pData(new ProtectedData(engine, id))
  68. {
  69. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
  70. CARLA_SAFE_ASSERT(id < engine->getMaxPluginNumber());
  71. carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id);
  72. switch (engine->getProccessMode())
  73. {
  74. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  75. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  76. CARLA_SAFE_ASSERT(id < MAX_DEFAULT_PLUGINS);
  77. break;
  78. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  79. CARLA_SAFE_ASSERT(id < MAX_RACK_PLUGINS);
  80. break;
  81. case ENGINE_PROCESS_MODE_PATCHBAY:
  82. CARLA_SAFE_ASSERT(id < MAX_PATCHBAY_PLUGINS);
  83. break;
  84. case ENGINE_PROCESS_MODE_BRIDGE:
  85. CARLA_SAFE_ASSERT(id == 0);
  86. break;
  87. }
  88. }
  89. CarlaPlugin::~CarlaPlugin()
  90. {
  91. carla_debug("CarlaPlugin::~CarlaPlugin()");
  92. delete pData;
  93. }
  94. // -------------------------------------------------------------------
  95. // Information (base)
  96. uint CarlaPlugin::getId() const noexcept
  97. {
  98. return pData->id;
  99. }
  100. uint CarlaPlugin::getHints() const noexcept
  101. {
  102. return pData->hints;
  103. }
  104. uint CarlaPlugin::getOptionsEnabled() const noexcept
  105. {
  106. return pData->options;
  107. }
  108. bool CarlaPlugin::isEnabled() const noexcept
  109. {
  110. return pData->enabled;
  111. }
  112. const char* CarlaPlugin::getName() const noexcept
  113. {
  114. return pData->name;
  115. }
  116. const char* CarlaPlugin::getFilename() const noexcept
  117. {
  118. return pData->filename;
  119. }
  120. const char* CarlaPlugin::getIconName() const noexcept
  121. {
  122. return pData->iconName;
  123. }
  124. PluginCategory CarlaPlugin::getCategory() const noexcept
  125. {
  126. return getPluginCategoryFromName(pData->name);
  127. }
  128. int64_t CarlaPlugin::getUniqueId() const noexcept
  129. {
  130. return 0;
  131. }
  132. uint32_t CarlaPlugin::getLatencyInFrames() const noexcept
  133. {
  134. return 0;
  135. }
  136. // -------------------------------------------------------------------
  137. // Information (count)
  138. uint32_t CarlaPlugin::getAudioInCount() const noexcept
  139. {
  140. return pData->audioIn.count;
  141. }
  142. uint32_t CarlaPlugin::getAudioOutCount() const noexcept
  143. {
  144. return pData->audioOut.count;
  145. }
  146. uint32_t CarlaPlugin::getCVInCount() const noexcept
  147. {
  148. return pData->cvIn.count;
  149. }
  150. uint32_t CarlaPlugin::getCVOutCount() const noexcept
  151. {
  152. return pData->cvOut.count;
  153. }
  154. uint32_t CarlaPlugin::getMidiInCount() const noexcept
  155. {
  156. return (pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_IN) ? 1 : 0;
  157. }
  158. uint32_t CarlaPlugin::getMidiOutCount() const noexcept
  159. {
  160. return (pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_OUT) ? 1 : 0;
  161. }
  162. uint32_t CarlaPlugin::getParameterCount() const noexcept
  163. {
  164. return pData->param.count;
  165. }
  166. uint32_t CarlaPlugin::getParameterScalePointCount(const uint32_t parameterId) const noexcept
  167. {
  168. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0);
  169. return 0;
  170. }
  171. uint32_t CarlaPlugin::getProgramCount() const noexcept
  172. {
  173. return pData->prog.count;
  174. }
  175. uint32_t CarlaPlugin::getMidiProgramCount() const noexcept
  176. {
  177. return pData->midiprog.count;
  178. }
  179. uint32_t CarlaPlugin::getCustomDataCount() const noexcept
  180. {
  181. return static_cast<uint32_t>(pData->custom.count());
  182. }
  183. // -------------------------------------------------------------------
  184. // Information (current data)
  185. int32_t CarlaPlugin::getCurrentProgram() const noexcept
  186. {
  187. return pData->prog.current;
  188. }
  189. int32_t CarlaPlugin::getCurrentMidiProgram() const noexcept
  190. {
  191. return pData->midiprog.current;
  192. }
  193. const ParameterData& CarlaPlugin::getParameterData(const uint32_t parameterId) const noexcept
  194. {
  195. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, kParameterDataNull);
  196. return pData->param.data[parameterId];
  197. }
  198. const ParameterRanges& CarlaPlugin::getParameterRanges(const uint32_t parameterId) const noexcept
  199. {
  200. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, kParameterRangesNull);
  201. return pData->param.ranges[parameterId];
  202. }
  203. bool CarlaPlugin::isParameterOutput(const uint32_t parameterId) const noexcept
  204. {
  205. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  206. return (pData->param.data[parameterId].type == PARAMETER_OUTPUT);
  207. }
  208. const MidiProgramData& CarlaPlugin::getMidiProgramData(const uint32_t index) const noexcept
  209. {
  210. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count, kMidiProgramDataNull);
  211. return pData->midiprog.data[index];
  212. }
  213. const CustomData& CarlaPlugin::getCustomData(const uint32_t index) const noexcept
  214. {
  215. return pData->custom.getAt(index, kCustomDataFallback);
  216. }
  217. std::size_t CarlaPlugin::getChunkData(void** const dataPtr) noexcept
  218. {
  219. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  220. CARLA_SAFE_ASSERT(false); // this should never happen
  221. return 0;
  222. }
  223. // -------------------------------------------------------------------
  224. // Information (per-plugin data)
  225. uint CarlaPlugin::getOptionsAvailable() const noexcept
  226. {
  227. CARLA_SAFE_ASSERT(false); // this should never happen
  228. return 0x0;
  229. }
  230. float CarlaPlugin::getParameterValue(const uint32_t parameterId) const noexcept
  231. {
  232. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(), 0.0f);
  233. CARLA_SAFE_ASSERT(false); // this should never happen
  234. return 0.0f;
  235. }
  236. float CarlaPlugin::getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept
  237. {
  238. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(), 0.0f);
  239. CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId), 0.0f);
  240. CARLA_SAFE_ASSERT(false); // this should never happen
  241. return 0.0f;
  242. }
  243. void CarlaPlugin::getLabel(char* const strBuf) const noexcept
  244. {
  245. strBuf[0] = '\0';
  246. }
  247. void CarlaPlugin::getMaker(char* const strBuf) const noexcept
  248. {
  249. strBuf[0] = '\0';
  250. }
  251. void CarlaPlugin::getCopyright(char* const strBuf) const noexcept
  252. {
  253. strBuf[0] = '\0';
  254. }
  255. void CarlaPlugin::getRealName(char* const strBuf) const noexcept
  256. {
  257. strBuf[0] = '\0';
  258. }
  259. void CarlaPlugin::getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept
  260. {
  261. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  262. CARLA_SAFE_ASSERT(false); // this should never happen
  263. strBuf[0] = '\0';
  264. }
  265. void CarlaPlugin::getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept
  266. {
  267. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  268. strBuf[0] = '\0';
  269. }
  270. void CarlaPlugin::getParameterText(const uint32_t parameterId, char* const strBuf) noexcept
  271. {
  272. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  273. CARLA_SAFE_ASSERT(false); // this should never happen
  274. strBuf[0] = '\0';
  275. }
  276. void CarlaPlugin::getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept
  277. {
  278. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  279. strBuf[0] = '\0';
  280. }
  281. void CarlaPlugin::getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept
  282. {
  283. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  284. CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId),);
  285. CARLA_SAFE_ASSERT(false); // this should never happen
  286. strBuf[0] = '\0';
  287. }
  288. float CarlaPlugin::getInternalParameterValue(const int32_t parameterId) const noexcept
  289. {
  290. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  291. CARLA_SAFE_ASSERT_RETURN(parameterId != PARAMETER_NULL && parameterId > PARAMETER_MAX, 0.0f);
  292. switch (parameterId)
  293. {
  294. case PARAMETER_ACTIVE:
  295. return pData->active;
  296. case PARAMETER_CTRL_CHANNEL:
  297. return pData->ctrlChannel;
  298. case PARAMETER_DRYWET:
  299. return pData->postProc.dryWet;
  300. case PARAMETER_VOLUME:
  301. return pData->postProc.volume;
  302. case PARAMETER_BALANCE_LEFT:
  303. return pData->postProc.balanceLeft;
  304. case PARAMETER_BALANCE_RIGHT:
  305. return pData->postProc.balanceRight;
  306. case PARAMETER_PANNING:
  307. return pData->postProc.panning;
  308. };
  309. #endif
  310. CARLA_SAFE_ASSERT_RETURN(parameterId >= 0, 0.0f);
  311. return getParameterValue(static_cast<uint32_t>(parameterId));
  312. }
  313. void CarlaPlugin::getProgramName(const uint32_t index, char* const strBuf) const noexcept
  314. {
  315. CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,);
  316. CARLA_SAFE_ASSERT_RETURN(pData->prog.names[index] != nullptr,);
  317. std::strncpy(strBuf, pData->prog.names[index], STR_MAX);
  318. }
  319. void CarlaPlugin::getMidiProgramName(const uint32_t index, char* const strBuf) const noexcept
  320. {
  321. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
  322. CARLA_SAFE_ASSERT_RETURN(pData->midiprog.data[index].name != nullptr,);
  323. std::strncpy(strBuf, pData->midiprog.data[index].name, STR_MAX);
  324. }
  325. void CarlaPlugin::getParameterCountInfo(uint32_t& ins, uint32_t& outs) const noexcept
  326. {
  327. ins = 0;
  328. outs = 0;
  329. for (uint32_t i=0; i < pData->param.count; ++i)
  330. {
  331. if (pData->param.data[i].type == PARAMETER_INPUT)
  332. ++ins;
  333. else if (pData->param.data[i].type == PARAMETER_OUTPUT)
  334. ++outs;
  335. }
  336. }
  337. // -------------------------------------------------------------------
  338. // Set data (state)
  339. void CarlaPlugin::prepareForSave()
  340. {
  341. }
  342. void CarlaPlugin::resetParameters() noexcept
  343. {
  344. for (uint i=0; i < pData->param.count; ++i)
  345. {
  346. const ParameterData& paramData(pData->param.data[i]);
  347. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  348. if (paramData.type != PARAMETER_INPUT)
  349. continue;
  350. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  351. continue;
  352. setParameterValue(i, paramRanges.def, true, true, true);
  353. }
  354. }
  355. void CarlaPlugin::randomizeParameters() noexcept
  356. {
  357. float value, random;
  358. char strBuf[STR_MAX+1];
  359. strBuf[STR_MAX] = '\0';
  360. std::srand(static_cast<uint>(std::time(nullptr)));
  361. for (uint i=0; i < pData->param.count; ++i)
  362. {
  363. const ParameterData& paramData(pData->param.data[i]);
  364. if (paramData.type != PARAMETER_INPUT)
  365. continue;
  366. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  367. continue;
  368. getParameterName(i, strBuf);
  369. if (std::strstr(strBuf, "olume") != nullptr)
  370. continue;
  371. if (std::strstr(strBuf, "Master") != nullptr)
  372. continue;
  373. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  374. if (paramData.hints & PARAMETER_IS_BOOLEAN)
  375. {
  376. random = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
  377. value = random > 0.5f ? paramRanges.max : paramRanges.min;
  378. }
  379. else
  380. {
  381. random = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
  382. value = random * (paramRanges.max - paramRanges.min) + paramRanges.min;
  383. if (paramData.hints & PARAMETER_IS_INTEGER)
  384. value = std::rint(value);
  385. }
  386. setParameterValue(i, value, true, true, true);
  387. }
  388. }
  389. const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave)
  390. {
  391. if (callPrepareForSave)
  392. prepareForSave();
  393. pData->stateSave.clear();
  394. const PluginType pluginType(getType());
  395. char strBuf[STR_MAX+1];
  396. // ---------------------------------------------------------------
  397. // Basic info
  398. getLabel(strBuf);
  399. pData->stateSave.type = carla_strdup(getPluginTypeAsString(pluginType));
  400. pData->stateSave.name = carla_strdup(pData->name);
  401. pData->stateSave.label = carla_strdup(strBuf);
  402. pData->stateSave.uniqueId = getUniqueId();
  403. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  404. pData->stateSave.options = pData->options;
  405. #endif
  406. if (pData->filename != nullptr)
  407. pData->stateSave.binary = carla_strdup(pData->filename);
  408. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  409. // ---------------------------------------------------------------
  410. // Internals
  411. pData->stateSave.active = pData->active;
  412. pData->stateSave.dryWet = pData->postProc.dryWet;
  413. pData->stateSave.volume = pData->postProc.volume;
  414. pData->stateSave.balanceLeft = pData->postProc.balanceLeft;
  415. pData->stateSave.balanceRight = pData->postProc.balanceRight;
  416. pData->stateSave.panning = pData->postProc.panning;
  417. pData->stateSave.ctrlChannel = pData->ctrlChannel;
  418. #endif
  419. bool usingChunk = false;
  420. // ---------------------------------------------------------------
  421. // Chunk
  422. if (pData->options & PLUGIN_OPTION_USE_CHUNKS)
  423. {
  424. void* data = nullptr;
  425. const std::size_t dataSize(getChunkData(&data));
  426. if (data != nullptr && dataSize > 0)
  427. {
  428. pData->stateSave.chunk = CarlaString::asBase64(data, dataSize).dup();
  429. if (pluginType != PLUGIN_INTERNAL)
  430. usingChunk = true;
  431. }
  432. }
  433. // ---------------------------------------------------------------
  434. // Current Program
  435. if (pData->prog.current >= 0 && pluginType != PLUGIN_LV2)
  436. {
  437. pData->stateSave.currentProgramIndex = pData->prog.current;
  438. pData->stateSave.currentProgramName = carla_strdup(pData->prog.names[pData->prog.current]);
  439. }
  440. // ---------------------------------------------------------------
  441. // Current MIDI Program
  442. if (pData->midiprog.current >= 0 && pluginType != PLUGIN_LV2 && pluginType != PLUGIN_SF2)
  443. {
  444. const MidiProgramData& mpData(pData->midiprog.getCurrent());
  445. pData->stateSave.currentMidiBank = static_cast<int32_t>(mpData.bank);
  446. pData->stateSave.currentMidiProgram = static_cast<int32_t>(mpData.program);
  447. }
  448. // ---------------------------------------------------------------
  449. // Parameters
  450. const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
  451. for (uint32_t i=0; i < pData->param.count; ++i)
  452. {
  453. const ParameterData& paramData(pData->param.data[i]);
  454. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  455. continue;
  456. const bool dummy = paramData.type != PARAMETER_INPUT || usingChunk;
  457. if (dummy && paramData.midiCC <= -1)
  458. continue;
  459. CarlaStateSave::Parameter* const stateParameter(new CarlaStateSave::Parameter());
  460. stateParameter->dummy = dummy;
  461. stateParameter->index = paramData.index;
  462. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  463. stateParameter->midiCC = paramData.midiCC;
  464. stateParameter->midiChannel = paramData.midiChannel;
  465. #endif
  466. getParameterName(i, strBuf);
  467. stateParameter->name = carla_strdup(strBuf);
  468. getParameterSymbol(i, strBuf);
  469. stateParameter->symbol = carla_strdup(strBuf);;
  470. if (! dummy)
  471. {
  472. stateParameter->value = getParameterValue(i);
  473. if (paramData.hints & PARAMETER_USES_SAMPLERATE)
  474. stateParameter->value /= sampleRate;
  475. }
  476. pData->stateSave.parameters.append(stateParameter);
  477. }
  478. // ---------------------------------------------------------------
  479. // Custom Data
  480. if (pData->hints & PLUGIN_IS_BRIDGE)
  481. waitForBridgeSaveSignal();
  482. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
  483. {
  484. const CustomData& cData(it.getValue(kCustomDataFallback));
  485. CARLA_SAFE_ASSERT_CONTINUE(cData.isValid());
  486. CarlaStateSave::CustomData* stateCustomData(new CarlaStateSave::CustomData());
  487. stateCustomData->type = carla_strdup(cData.type);
  488. stateCustomData->key = carla_strdup(cData.key);
  489. stateCustomData->value = carla_strdup(cData.value);
  490. pData->stateSave.customData.append(stateCustomData);
  491. }
  492. return pData->stateSave;
  493. }
  494. void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave)
  495. {
  496. char strBuf[STR_MAX+1];
  497. const bool usesMultiProgs(pData->hints & PLUGIN_USES_MULTI_PROGS);
  498. const PluginType pluginType(getType());
  499. // ---------------------------------------------------------------
  500. // Part 1 - PRE-set custom data (only those which reload programs)
  501. for (CarlaStateSave::CustomDataItenerator it = stateSave.customData.begin2(); it.valid(); it.next())
  502. {
  503. const CarlaStateSave::CustomData* const stateCustomData(it.getValue(nullptr));
  504. CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr);
  505. CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid());
  506. const char* const key(stateCustomData->key);
  507. /**/ if (pluginType == PLUGIN_DSSI && (std::strcmp (key, "reloadprograms") == 0 ||
  508. std::strcmp (key, "load" ) == 0 ||
  509. std::strncmp(key, "patches", 7) == 0 ))
  510. pass();
  511. else if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
  512. pass();
  513. else
  514. continue;
  515. setCustomData(stateCustomData->type, key, stateCustomData->value, true);
  516. }
  517. // ---------------------------------------------------------------
  518. // Part 2 - set program
  519. if (stateSave.currentProgramIndex >= 0 && stateSave.currentProgramName != nullptr)
  520. {
  521. int32_t programId = -1;
  522. // index < count
  523. if (stateSave.currentProgramIndex < static_cast<int32_t>(pData->prog.count))
  524. {
  525. programId = stateSave.currentProgramIndex;
  526. }
  527. // index not valid, try to find by name
  528. else
  529. {
  530. for (uint32_t i=0; i < pData->prog.count; ++i)
  531. {
  532. strBuf[0] = '\0';
  533. getProgramName(i, strBuf);
  534. if (strBuf[0] != '\0' && std::strcmp(stateSave.currentProgramName, strBuf) == 0)
  535. {
  536. programId = static_cast<int32_t>(i);
  537. break;
  538. }
  539. }
  540. }
  541. // set program now, if valid
  542. if (programId >= 0)
  543. setProgram(programId, true, true, true);
  544. }
  545. // ---------------------------------------------------------------
  546. // Part 3 - set midi program
  547. if (stateSave.currentMidiBank >= 0 && stateSave.currentMidiProgram >= 0 && ! usesMultiProgs)
  548. setMidiProgramById(static_cast<uint32_t>(stateSave.currentMidiBank), static_cast<uint32_t>(stateSave.currentMidiProgram), true, true, true);
  549. // ---------------------------------------------------------------
  550. // Part 4a - get plugin parameter symbols
  551. LinkedList<ParamSymbol*> paramSymbols;
  552. if (pluginType == PLUGIN_LADSPA || pluginType == PLUGIN_LV2)
  553. {
  554. for (uint32_t i=0; i < pData->param.count; ++i)
  555. {
  556. strBuf[0] = '\0';
  557. getParameterSymbol(i, strBuf);
  558. if (strBuf[0] != '\0')
  559. {
  560. ParamSymbol* const paramSymbol(new ParamSymbol(i, strBuf));
  561. paramSymbols.append(paramSymbol);
  562. }
  563. }
  564. }
  565. // ---------------------------------------------------------------
  566. // Part 4b - set parameter values (carefully)
  567. const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
  568. for (CarlaStateSave::ParameterItenerator it = stateSave.parameters.begin2(); it.valid(); it.next())
  569. {
  570. CarlaStateSave::Parameter* const stateParameter(it.getValue(nullptr));
  571. CARLA_SAFE_ASSERT_CONTINUE(stateParameter != nullptr);
  572. int32_t index = -1;
  573. if (pluginType == PLUGIN_LADSPA)
  574. {
  575. // Try to set by symbol, otherwise use index
  576. if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0')
  577. {
  578. for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin2(); it2.valid(); it2.next())
  579. {
  580. ParamSymbol* const paramSymbol(it2.getValue(nullptr));
  581. CARLA_SAFE_ASSERT_CONTINUE(paramSymbol != nullptr);
  582. CARLA_SAFE_ASSERT_CONTINUE(paramSymbol->symbol != nullptr);
  583. if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0)
  584. {
  585. index = paramSymbol->index;
  586. break;
  587. }
  588. }
  589. if (index == -1)
  590. index = stateParameter->index;
  591. }
  592. else
  593. {
  594. index = stateParameter->index;
  595. }
  596. }
  597. else if (pluginType == PLUGIN_LV2)
  598. {
  599. // Symbol only
  600. if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0')
  601. {
  602. for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin2(); it2.valid(); it2.next())
  603. {
  604. ParamSymbol* const paramSymbol(it2.getValue(nullptr));
  605. CARLA_SAFE_ASSERT_CONTINUE(paramSymbol != nullptr);
  606. CARLA_SAFE_ASSERT_CONTINUE(paramSymbol->symbol != nullptr);
  607. if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0)
  608. {
  609. index = paramSymbol->index;
  610. break;
  611. }
  612. }
  613. if (index == -1)
  614. carla_stderr("Failed to find LV2 parameter symbol '%s' for '%s'",
  615. stateParameter->symbol, pData->name);
  616. }
  617. else
  618. {
  619. carla_stderr("LV2 Plugin parameter '%s' has no symbol", stateParameter->name);
  620. }
  621. }
  622. else
  623. {
  624. // Index only
  625. index = stateParameter->index;
  626. }
  627. // Now set parameter
  628. if (index >= 0 && index < static_cast<int32_t>(pData->param.count))
  629. {
  630. //CARLA_SAFE_ASSERT(stateParameter->isInput == (pData
  631. if (! stateParameter->dummy)
  632. {
  633. if (pData->param.data[index].hints & PARAMETER_USES_SAMPLERATE)
  634. stateParameter->value *= sampleRate;
  635. setParameterValue(static_cast<uint32_t>(index), stateParameter->value, true, true, true);
  636. }
  637. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  638. setParameterMidiCC(static_cast<uint32_t>(index), stateParameter->midiCC, true, true);
  639. setParameterMidiChannel(static_cast<uint32_t>(index), stateParameter->midiChannel, true, true);
  640. #endif
  641. }
  642. else
  643. carla_stderr("Could not set parameter '%s' value for '%s'",
  644. stateParameter->name, pData->name);
  645. }
  646. // ---------------------------------------------------------------
  647. // Part 4c - clear
  648. for (LinkedList<ParamSymbol*>::Itenerator it = paramSymbols.begin2(); it.valid(); it.next())
  649. {
  650. ParamSymbol* const paramSymbol(it.getValue(nullptr));
  651. delete paramSymbol;
  652. }
  653. paramSymbols.clear();
  654. // ---------------------------------------------------------------
  655. // Part 5 - set custom data
  656. for (CarlaStateSave::CustomDataItenerator it = stateSave.customData.begin2(); it.valid(); it.next())
  657. {
  658. const CarlaStateSave::CustomData* const stateCustomData(it.getValue(nullptr));
  659. CARLA_SAFE_ASSERT_CONTINUE(stateCustomData != nullptr);
  660. CARLA_SAFE_ASSERT_CONTINUE(stateCustomData->isValid());
  661. const char* const key(stateCustomData->key);
  662. if (pluginType == PLUGIN_DSSI && (std::strcmp (key, "reloadprograms") == 0 ||
  663. std::strcmp (key, "load" ) == 0 ||
  664. std::strncmp(key, "patches", 7) == 0 ))
  665. continue;
  666. if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
  667. continue;
  668. setCustomData(stateCustomData->type, key, stateCustomData->value, true);
  669. }
  670. // ---------------------------------------------------------------
  671. // Part 5x - set lv2 state
  672. if (pluginType == PLUGIN_LV2)
  673. {
  674. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
  675. {
  676. const CustomData& customData(it.getValue(kCustomDataFallback));
  677. CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  678. if (std::strcmp(customData.type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
  679. continue;
  680. restoreLV2State();
  681. break;
  682. }
  683. }
  684. // ---------------------------------------------------------------
  685. // Part 6 - set chunk
  686. if (stateSave.chunk != nullptr && (pData->options & PLUGIN_OPTION_USE_CHUNKS) != 0)
  687. {
  688. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(stateSave.chunk));
  689. #ifdef CARLA_PROPER_CPP11_SUPPORT
  690. setChunkData(chunk.data(), chunk.size());
  691. #else
  692. setChunkData(&chunk.front(), chunk.size());
  693. #endif
  694. }
  695. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  696. // ---------------------------------------------------------------
  697. // Part 6 - set internal stuff
  698. const uint availOptions(getOptionsAvailable());
  699. for (uint i=0; i<10; ++i) // FIXME - get this value somehow...
  700. {
  701. const uint option(1u << i);
  702. if (availOptions & option)
  703. setOption(option, (stateSave.options & option) != 0, true);
  704. }
  705. setDryWet(stateSave.dryWet, true, true);
  706. setVolume(stateSave.volume, true, true);
  707. setBalanceLeft(stateSave.balanceLeft, true, true);
  708. setBalanceRight(stateSave.balanceRight, true, true);
  709. setPanning(stateSave.panning, true, true);
  710. setCtrlChannel(stateSave.ctrlChannel, true, true);
  711. setActive(stateSave.active, true, true);
  712. if (! pData->engine->isLoadingProject())
  713. pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0f, nullptr);
  714. #endif
  715. }
  716. bool CarlaPlugin::saveStateToFile(const char* const filename)
  717. {
  718. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  719. carla_debug("CarlaPlugin::saveStateToFile(\"%s\")", filename);
  720. MemoryOutputStream out, streamState;
  721. getStateSave().dumpToMemoryStream(streamState);
  722. out << "<?xml version='1.0' encoding='UTF-8'?>\n";
  723. out << "<!DOCTYPE CARLA-PRESET>\n";
  724. out << "<CARLA-PRESET VERSION='2.0'>\n";
  725. out << streamState;
  726. out << "</CARLA-PRESET>\n";
  727. const String jfilename = String(CharPointer_UTF8(filename));
  728. File file(jfilename);
  729. if (file.replaceWithData(out.getData(), out.getDataSize()))
  730. return true;
  731. pData->engine->setLastError("Failed to write file");
  732. return false;
  733. }
  734. bool CarlaPlugin::loadStateFromFile(const char* const filename)
  735. {
  736. // TODO set errors
  737. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  738. carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename);
  739. const String jfilename = String(CharPointer_UTF8(filename));
  740. File file(jfilename);
  741. CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(), false);
  742. XmlDocument xml(file);
  743. ScopedPointer<XmlElement> xmlElement(xml.getDocumentElement(true));
  744. CARLA_SAFE_ASSERT_RETURN(xmlElement != nullptr, false);
  745. CARLA_SAFE_ASSERT_RETURN(xmlElement->getTagName().equalsIgnoreCase("carla-preset"), false);
  746. // completely load file
  747. xmlElement = xml.getDocumentElement(false);
  748. CARLA_SAFE_ASSERT_RETURN(xmlElement != nullptr, false);
  749. if (pData->stateSave.fillFromXmlElement(xmlElement))
  750. {
  751. loadStateSave(pData->stateSave);
  752. return true;
  753. }
  754. return false;
  755. }
  756. bool CarlaPlugin::exportAsLV2(const char* const lv2path)
  757. {
  758. CARLA_SAFE_ASSERT_RETURN(lv2path != nullptr && lv2path[0] != '\0', false);
  759. carla_debug("CarlaPlugin::exportAsLV2(\"%s\")", lv2path);
  760. CarlaString bundlepath(lv2path);
  761. if (! bundlepath.endsWith(".lv2"))
  762. bundlepath += ".lv2";
  763. const File bundlefolder(bundlepath.buffer());
  764. if (bundlefolder.existsAsFile())
  765. {
  766. pData->engine->setLastError("Requested filename already exists as file, use a folder instead");
  767. return false;
  768. }
  769. if (! bundlefolder.exists())
  770. {
  771. const Result res(bundlefolder.createDirectory());
  772. if (res.failed())
  773. {
  774. pData->engine->setLastError(res.getErrorMessage().toRawUTF8());
  775. return false;
  776. }
  777. }
  778. CarlaString symbol(pData->name);
  779. symbol.toBasic();
  780. {
  781. const CarlaString pluginFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".xml");
  782. if (! saveStateToFile(pluginFilename))
  783. return false;
  784. }
  785. {
  786. MemoryOutputStream manifestStream;
  787. manifestStream << "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n";
  788. manifestStream << "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
  789. manifestStream << "@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .\n";
  790. manifestStream << "\n";
  791. manifestStream << "<" << symbol.buffer() << ".ttl>\n";
  792. manifestStream << " a lv2:Plugin ;\n";
  793. manifestStream << " lv2:binary <" << symbol.buffer() << CARLA_LIB_EXT "> ;\n";
  794. manifestStream << " rdfs:seeAlso <" << symbol.buffer() << ".ttl> .\n";
  795. manifestStream << "\n";
  796. manifestStream << "<ext-ui>\n";
  797. manifestStream << " a <http://kxstudio.sf.net/ns/lv2ext/external-ui#Widget> ;\n";
  798. manifestStream << " ui:binary <" << symbol.buffer() << CARLA_LIB_EXT "> ;\n";
  799. manifestStream << " lv2:extensionData <http://lv2plug.in/ns/extensions/ui#idleInterface> ,\n";
  800. manifestStream << " <http://lv2plug.in/ns/extensions/ui#showInterface> ;\n";
  801. manifestStream << " lv2:requiredFeature <http://lv2plug.in/ns/ext/instance-access> .\n";
  802. manifestStream << "\n";
  803. const CarlaString manifestFilename(bundlepath + CARLA_OS_SEP_STR "manifest.ttl");
  804. const File manifestFile(manifestFilename.buffer());
  805. if (! manifestFile.replaceWithData(manifestStream.getData(), manifestStream.getDataSize()))
  806. {
  807. pData->engine->setLastError("Failed to write manifest.ttl file");
  808. return false;
  809. }
  810. }
  811. {
  812. MemoryOutputStream mainStream;
  813. mainStream << "@prefix atom: <http://lv2plug.in/ns/ext/atom#> .\n";
  814. mainStream << "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
  815. mainStream << "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
  816. mainStream << "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n";
  817. mainStream << "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
  818. mainStream << "@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .\n";
  819. mainStream << "\n";
  820. mainStream << "<>\n";
  821. mainStream << " a lv2:Plugin ;\n";
  822. mainStream << "\n";
  823. mainStream << " lv2:requiredFeature <http://lv2plug.in/ns/ext/buf-size#boundedBlockLength> ,\n";
  824. mainStream << " <http://lv2plug.in/ns/ext/options#options> ,\n";
  825. mainStream << " <http://lv2plug.in/ns/ext/urid#map> ;\n";
  826. mainStream << "\n";
  827. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  828. {
  829. mainStream << " ui:ui <ext-ui> ;\n";
  830. mainStream << "\n";
  831. }
  832. const uint32_t midiIns = getMidiInCount();
  833. const uint32_t midiOuts = getMidiOutCount();
  834. int portIndex = 0;
  835. if (midiIns > 0)
  836. {
  837. mainStream << " lv2:port [\n";
  838. mainStream << " a lv2:InputPort, atom:AtomPort ;\n";
  839. mainStream << " lv2:index 0 ;\n";
  840. mainStream << " lv2:symbol \"clv2_events_in\" ;\n";
  841. mainStream << " lv2:name \"Events Input\" ;\n";
  842. mainStream << " atom:bufferType atom:Sequence ;\n";
  843. mainStream << " atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ,\n";
  844. mainStream << " <http://lv2plug.in/ns/ext/time#Position> ;\n";
  845. mainStream << " ] ;\n";
  846. ++portIndex;
  847. for (uint32_t i=1; i<midiIns; ++i)
  848. {
  849. const String portIndexNum(portIndex++);
  850. const String portIndexLabel(portIndex);
  851. mainStream << " lv2:port [\n";
  852. mainStream << " a lv2:InputPort, atom:AtomPort ;\n";
  853. mainStream << " lv2:index " << portIndexNum << " ;\n";
  854. mainStream << " lv2:symbol \"clv2_midi_in_" << portIndexLabel << "\" ;\n";
  855. mainStream << " lv2:name \"MIDI Input " << portIndexLabel << "\" ;\n";
  856. mainStream << " ] ;\n";
  857. }
  858. }
  859. else
  860. {
  861. mainStream << " lv2:port [\n";
  862. mainStream << " a lv2:InputPort, atom:AtomPort ;\n";
  863. mainStream << " lv2:index 0 ;\n";
  864. mainStream << " lv2:symbol \"clv2_time_info\" ;\n";
  865. mainStream << " lv2:name \"Time Info\" ;\n";
  866. mainStream << " atom:bufferType atom:Sequence ;\n";
  867. mainStream << " atom:supports <http://lv2plug.in/ns/ext/time#Position> ;\n";
  868. mainStream << " ] ;\n";
  869. ++portIndex;
  870. }
  871. for (uint32_t i=0; i<midiOuts; ++i)
  872. {
  873. const String portIndexNum(portIndex++);
  874. const String portIndexLabel(portIndex);
  875. mainStream << " lv2:port [\n";
  876. mainStream << " a lv2:InputPort, atom:AtomPort ;\n";
  877. mainStream << " lv2:index " << portIndexNum << " ;\n";
  878. mainStream << " lv2:symbol \"clv2_midi_out_" << portIndexLabel << "\" ;\n";
  879. mainStream << " lv2:name \"MIDI Output " << portIndexLabel << "\" ;\n";
  880. mainStream << " atom:bufferType atom:Sequence ;\n";
  881. mainStream << " atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n";
  882. mainStream << " ] ;\n";
  883. }
  884. mainStream << " lv2:port [\n";
  885. mainStream << " a lv2:InputPort, lv2:ControlPort ;\n";
  886. mainStream << " lv2:index " << String(portIndex++) << " ;\n";
  887. mainStream << " lv2:name \"freewheel\" ;\n";
  888. mainStream << " lv2:symbol \"clv2_freewheel\" ;\n";
  889. mainStream << " lv2:default 0 ;\n";
  890. mainStream << " lv2:minimum 0 ;\n";
  891. mainStream << " lv2:maximum 1 ;\n";
  892. mainStream << " lv2:designation lv2:freeWheeling ;\n";
  893. mainStream << " lv2:portProperty lv2:toggled , lv2:integer ;\n";
  894. mainStream << " lv2:portProperty <http://lv2plug.in/ns/ext/port-props#notOnGUI> ;\n";
  895. mainStream << " ] ;\n";
  896. for (uint32_t i=0; i<pData->audioIn.count; ++i)
  897. {
  898. const String portIndexNum(portIndex++);
  899. const String portIndexLabel(i+1);
  900. mainStream << " lv2:port [\n";
  901. mainStream << " a lv2:InputPort, lv2:AudioPort ;\n";
  902. mainStream << " lv2:index " << portIndexNum << " ;\n";
  903. mainStream << " lv2:symbol \"clv2_audio_in_" << portIndexLabel << "\" ;\n";
  904. mainStream << " lv2:name \"Audio Input " << portIndexLabel << "\" ;\n";
  905. mainStream << " ] ;\n";
  906. }
  907. for (uint32_t i=0; i<pData->audioOut.count; ++i)
  908. {
  909. const String portIndexNum(portIndex++);
  910. const String portIndexLabel(i+1);
  911. mainStream << " lv2:port [\n";
  912. mainStream << " a lv2:OutputPort, lv2:AudioPort ;\n";
  913. mainStream << " lv2:index " << portIndexNum << " ;\n";
  914. mainStream << " lv2:symbol \"clv2_audio_out_" << portIndexLabel << "\" ;\n";
  915. mainStream << " lv2:name \"Audio Output " << portIndexLabel << "\" ;\n";
  916. mainStream << " ] ;\n";
  917. }
  918. CarlaStringList uniqueSymbolNames;
  919. char strBufName[STR_MAX+1];
  920. char strBufSymbol[STR_MAX+1];
  921. strBufName[STR_MAX] = strBufSymbol[STR_MAX] = '\0';
  922. for (uint32_t i=0; i<pData->param.count; ++i)
  923. {
  924. const ParameterData& paramData(pData->param.data[i]);
  925. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  926. const String portIndexNum(portIndex++);
  927. mainStream << " lv2:port [\n";
  928. if (paramData.type == PARAMETER_INPUT)
  929. mainStream << " a lv2:InputPort, lv2:ControlPort ;\n";
  930. else
  931. mainStream << " a lv2:OutputPort, lv2:ControlPort ;\n";
  932. if (paramData.hints & PARAMETER_IS_BOOLEAN)
  933. mainStream << " lv2:portProperty lv2:toggled ;\n";
  934. if (paramData.hints & PARAMETER_IS_INTEGER)
  935. mainStream << " lv2:portProperty lv2:integer ;\n";
  936. // TODO logarithmic, enabled (not on gui), automable, samplerate, scalepoints
  937. strBufName[0] = strBufSymbol[0] = '\0';
  938. getParameterName(i, strBufName);
  939. getParameterSymbol(i, strBufSymbol);
  940. if (strBufSymbol[0] == '\0')
  941. {
  942. CarlaString s(strBufName);
  943. s.toBasic();
  944. std::memcpy(strBufSymbol, s.buffer(), s.length()+1);
  945. if (strBufSymbol[0] >= '0' && strBufSymbol[0] <= '9')
  946. {
  947. const size_t len(std::strlen(strBufSymbol));
  948. std::memmove(strBufSymbol+1, strBufSymbol, len);
  949. strBufSymbol[0] = '_';
  950. strBufSymbol[len+1] = '\0';
  951. }
  952. }
  953. if (uniqueSymbolNames.contains(strBufSymbol))
  954. {
  955. std::snprintf(strBufSymbol, STR_MAX, "clv2_param_%d", i+1);
  956. strBufSymbol[STR_MAX] = '\0';
  957. }
  958. mainStream << " lv2:index " << portIndexNum << " ;\n";
  959. mainStream << " lv2:symbol \"" << strBufSymbol << "\" ;\n";
  960. mainStream << " lv2:name \"\"\"" << strBufName << "\"\"\" ;\n";
  961. mainStream << " lv2:default " << String(paramRanges.def) << " ;\n";
  962. mainStream << " lv2:minimum " << String(paramRanges.min) << " ;\n";
  963. mainStream << " lv2:maximum " << String(paramRanges.max) << " ;\n";
  964. // TODO midiCC, midiChannel
  965. mainStream << " ] ;\n";
  966. }
  967. char strBuf[STR_MAX];
  968. getMaker(strBuf);
  969. strBuf[STR_MAX-1] = '\0';
  970. mainStream << " rdfs:comment \"Plugin generated using Carla LV2 export.\" ;\n";
  971. mainStream << " doap:name \"\"\"" << getName() << "\"\"\" ;\n";
  972. mainStream << " doap:maintainer [ foaf:name \"\"\"" << strBuf << "\"\"\" ] .\n";
  973. mainStream << "\n";
  974. const CarlaString mainFilename(bundlepath + CARLA_OS_SEP_STR + symbol + ".ttl");
  975. const File mainFile(mainFilename.buffer());
  976. if (! mainFile.replaceWithData(mainStream.getData(), mainStream.getDataSize()))
  977. {
  978. pData->engine->setLastError("Failed to write main plugin ttl file");
  979. return false;
  980. }
  981. }
  982. const CarlaString binaryFilename(bundlepath + CARLA_OS_SEP_STR + symbol + CARLA_LIB_EXT);
  983. const File binaryFileSource(File::getSpecialLocation(File::currentExecutableFile).getSiblingFile("carla-bridge-lv2" CARLA_LIB_EXT));
  984. const File binaryFileTarget(binaryFilename.buffer());
  985. const EngineOptions& opts(pData->engine->getOptions());
  986. const CarlaString binFolderTarget(bundlepath + CARLA_OS_SEP_STR + "bin");
  987. const CarlaString resFolderTarget(bundlepath + CARLA_OS_SEP_STR + "res");
  988. if (! binaryFileSource.copyFileTo(binaryFileTarget))
  989. {
  990. pData->engine->setLastError("Failed to copy plugin binary");
  991. return false;
  992. }
  993. #ifdef CARLA_OS_WIN
  994. File(opts.resourceDir).copyDirectoryTo(File(resFolderTarget.buffer()));
  995. // Copying all the binaries is pointless, just go through the expected needed bits
  996. const File binFolder1(opts.binaryDir);
  997. const File binFolder2(binFolderTarget.buffer());
  998. binFolder2.createDirectory();
  999. static const char* files[] = {
  1000. "carla-bridge-native.exe",
  1001. "carla-bridge-win32.exe",
  1002. "carla-discovery-win32.exe",
  1003. "carla-discovery-win64.exe",
  1004. "libcarla_utils.dll"
  1005. };
  1006. for (int i=0; i<5; ++i)
  1007. binFolder1.getChildFile(files[i]).copyFileTo(binFolder2.getChildFile(files[i]));;
  1008. #else
  1009. File(opts.binaryDir).createSymbolicLink(File(binFolderTarget.buffer()), true);
  1010. File(opts.resourceDir).createSymbolicLink(File(resFolderTarget.buffer()), true);
  1011. #endif
  1012. return true;
  1013. }
  1014. // -------------------------------------------------------------------
  1015. // Set data (internal stuff)
  1016. void CarlaPlugin::setId(const uint newId) noexcept
  1017. {
  1018. pData->id = newId;
  1019. }
  1020. void CarlaPlugin::setName(const char* const newName)
  1021. {
  1022. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0',);
  1023. if (pData->name != nullptr)
  1024. delete[] pData->name;
  1025. pData->name = carla_strdup(newName);
  1026. }
  1027. void CarlaPlugin::setOption(const uint option, const bool yesNo, const bool sendCallback)
  1028. {
  1029. CARLA_SAFE_ASSERT_RETURN(getOptionsAvailable() & option,);
  1030. if (yesNo)
  1031. pData->options |= option;
  1032. else
  1033. pData->options &= ~option;
  1034. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1035. if (sendCallback)
  1036. pData->engine->callback(ENGINE_CALLBACK_OPTION_CHANGED,
  1037. pData->id,
  1038. static_cast<int>(option),
  1039. yesNo ? 1 : 0,
  1040. 0, 0.0f, nullptr);
  1041. #else
  1042. // unused
  1043. return; (void)sendCallback;
  1044. #endif
  1045. }
  1046. void CarlaPlugin::setEnabled(const bool yesNo) noexcept
  1047. {
  1048. if (pData->enabled == yesNo)
  1049. return;
  1050. pData->masterMutex.lock();
  1051. pData->enabled = yesNo;
  1052. if (yesNo && ! pData->client->isActive())
  1053. pData->client->activate();
  1054. pData->masterMutex.unlock();
  1055. }
  1056. void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback) noexcept
  1057. {
  1058. if (pData->engineBridged) {
  1059. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1060. } else if (pData->enginePlugin) {
  1061. // nothing here
  1062. } else {
  1063. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1064. }
  1065. if (pData->active == active)
  1066. return;
  1067. {
  1068. const ScopedSingleProcessLocker spl(this, true);
  1069. if (active)
  1070. activate();
  1071. else
  1072. deactivate();
  1073. }
  1074. pData->active = active;
  1075. const float value = active ? 1.0f : 0.0f;
  1076. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1077. if (sendOsc && pData->engine->isOscControlRegistered())
  1078. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, value);
  1079. #endif
  1080. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1081. if (sendCallback)
  1082. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1083. pData->id,
  1084. PARAMETER_ACTIVE,
  1085. 0, 0,
  1086. value,
  1087. nullptr);
  1088. #endif
  1089. // maybe unused
  1090. return; (void)value;
  1091. }
  1092. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1093. void CarlaPlugin::setDryWet(const float value, const bool sendOsc, const bool sendCallback) noexcept
  1094. {
  1095. if (pData->engineBridged) {
  1096. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1097. } else {
  1098. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1099. }
  1100. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  1101. const float fixedValue(carla_fixedValue<float>(0.0f, 1.0f, value));
  1102. if (carla_isEqual(pData->postProc.dryWet, fixedValue))
  1103. return;
  1104. pData->postProc.dryWet = fixedValue;
  1105. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1106. if (sendOsc && pData->engine->isOscControlRegistered())
  1107. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, fixedValue);
  1108. # endif
  1109. if (sendCallback)
  1110. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1111. pData->id,
  1112. PARAMETER_DRYWET,
  1113. 0, 0,
  1114. fixedValue,
  1115. nullptr);
  1116. }
  1117. void CarlaPlugin::setVolume(const float value, const bool sendOsc, const bool sendCallback) noexcept
  1118. {
  1119. if (pData->engineBridged) {
  1120. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1121. } else {
  1122. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1123. }
  1124. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.27f);
  1125. const float fixedValue(carla_fixedValue<float>(0.0f, 1.27f, value));
  1126. if (carla_isEqual(pData->postProc.volume, fixedValue))
  1127. return;
  1128. pData->postProc.volume = fixedValue;
  1129. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1130. if (sendOsc && pData->engine->isOscControlRegistered())
  1131. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, fixedValue);
  1132. # endif
  1133. if (sendCallback)
  1134. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1135. pData->id,
  1136. PARAMETER_VOLUME,
  1137. 0, 0,
  1138. fixedValue,
  1139. nullptr);
  1140. }
  1141. void CarlaPlugin::setBalanceLeft(const float value, const bool sendOsc, const bool sendCallback) noexcept
  1142. {
  1143. if (pData->engineBridged) {
  1144. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1145. } else {
  1146. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1147. }
  1148. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1149. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1150. if (carla_isEqual(pData->postProc.balanceLeft, fixedValue))
  1151. return;
  1152. pData->postProc.balanceLeft = fixedValue;
  1153. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1154. if (sendOsc && pData->engine->isOscControlRegistered())
  1155. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, fixedValue);
  1156. # endif
  1157. if (sendCallback)
  1158. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1159. pData->id,
  1160. PARAMETER_BALANCE_LEFT,
  1161. 0, 0,
  1162. fixedValue,
  1163. nullptr);
  1164. }
  1165. void CarlaPlugin::setBalanceRight(const float value, const bool sendOsc, const bool sendCallback) noexcept
  1166. {
  1167. if (pData->engineBridged) {
  1168. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1169. } else {
  1170. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1171. }
  1172. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1173. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1174. if (carla_isEqual(pData->postProc.balanceRight, fixedValue))
  1175. return;
  1176. pData->postProc.balanceRight = fixedValue;
  1177. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1178. if (sendOsc && pData->engine->isOscControlRegistered())
  1179. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, fixedValue);
  1180. # endif
  1181. if (sendCallback)
  1182. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1183. pData->id,
  1184. PARAMETER_BALANCE_RIGHT,
  1185. 0, 0,
  1186. fixedValue,
  1187. nullptr);
  1188. }
  1189. void CarlaPlugin::setPanning(const float value, const bool sendOsc, const bool sendCallback) noexcept
  1190. {
  1191. if (pData->engineBridged) {
  1192. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1193. } else {
  1194. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1195. }
  1196. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1197. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1198. if (carla_isEqual(pData->postProc.panning, fixedValue))
  1199. return;
  1200. pData->postProc.panning = fixedValue;
  1201. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1202. if (sendOsc && pData->engine->isOscControlRegistered())
  1203. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, fixedValue);
  1204. # endif
  1205. if (sendCallback)
  1206. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1207. pData->id,
  1208. PARAMETER_PANNING,
  1209. 0, 0,
  1210. fixedValue,
  1211. nullptr);
  1212. }
  1213. void CarlaPlugin::setDryWetRT(const float value) noexcept
  1214. {
  1215. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  1216. const float fixedValue(carla_fixedValue<float>(0.0f, 1.0f, value));
  1217. if (carla_isEqual(pData->postProc.dryWet, fixedValue))
  1218. return;
  1219. pData->postProc.dryWet = fixedValue;
  1220. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, 0, fixedValue);
  1221. }
  1222. void CarlaPlugin::setVolumeRT(const float value) noexcept
  1223. {
  1224. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.27f);
  1225. const float fixedValue(carla_fixedValue<float>(0.0f, 1.27f, value));
  1226. if (carla_isEqual(pData->postProc.volume, fixedValue))
  1227. return;
  1228. pData->postProc.volume = fixedValue;
  1229. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, 0, fixedValue);
  1230. }
  1231. void CarlaPlugin::setBalanceLeftRT(const float value) noexcept
  1232. {
  1233. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1234. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1235. if (carla_isEqual(pData->postProc.balanceLeft, fixedValue))
  1236. return;
  1237. pData->postProc.balanceLeft = fixedValue;
  1238. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, 0, fixedValue);
  1239. }
  1240. void CarlaPlugin::setBalanceRightRT(const float value) noexcept
  1241. {
  1242. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1243. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1244. if (carla_isEqual(pData->postProc.balanceRight, fixedValue))
  1245. return;
  1246. pData->postProc.balanceRight = fixedValue;
  1247. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, 0, fixedValue);
  1248. }
  1249. void CarlaPlugin::setPanningRT(const float value) noexcept
  1250. {
  1251. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  1252. const float fixedValue(carla_fixedValue<float>(-1.0f, 1.0f, value));
  1253. if (carla_isEqual(pData->postProc.panning, fixedValue))
  1254. return;
  1255. pData->postProc.panning = fixedValue;
  1256. }
  1257. #endif // ! BUILD_BRIDGE_ALTERNATIVE_ARCH
  1258. void CarlaPlugin::setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept
  1259. {
  1260. if (pData->engineBridged) {
  1261. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1262. } else {
  1263. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1264. }
  1265. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);
  1266. if (pData->ctrlChannel == channel)
  1267. return;
  1268. pData->ctrlChannel = channel;
  1269. const float channelf = static_cast<float>(channel);
  1270. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1271. if (sendOsc && pData->engine->isOscControlRegistered())
  1272. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, channelf);
  1273. #endif
  1274. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1275. if (sendCallback)
  1276. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1277. pData->id,
  1278. PARAMETER_CTRL_CHANNEL,
  1279. 0, 0,
  1280. channelf, nullptr);
  1281. #endif
  1282. // maybe unused
  1283. return; (void)channelf;
  1284. }
  1285. // -------------------------------------------------------------------
  1286. // Set data (plugin-specific stuff)
  1287. void CarlaPlugin::setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  1288. {
  1289. if (pData->engineBridged) {
  1290. // NOTE: some LV2 plugins feedback messages to UI on purpose
  1291. CARLA_SAFE_ASSERT_RETURN(getType() == PLUGIN_LV2 || !sendGui,);
  1292. } else if (pData->enginePlugin) {
  1293. // nothing here
  1294. } else {
  1295. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,); // never call this from RT
  1296. }
  1297. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  1298. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1299. uiParameterChange(parameterId, value);
  1300. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1301. if (sendOsc && pData->engine->isOscControlRegistered())
  1302. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(parameterId), value);
  1303. #endif
  1304. if (sendCallback)
  1305. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1306. pData->id,
  1307. static_cast<int>(parameterId),
  1308. 0, 0,
  1309. value,
  1310. nullptr);
  1311. }
  1312. void CarlaPlugin::setParameterValueRT(const uint32_t parameterId, const float value) noexcept
  1313. {
  1314. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(parameterId), 0, 0, value);
  1315. }
  1316. void CarlaPlugin::setParameterValueByRealIndex(const int32_t rindex, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  1317. {
  1318. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1319. CARLA_SAFE_ASSERT_RETURN(rindex > PARAMETER_MAX && rindex != PARAMETER_NULL,);
  1320. switch (rindex)
  1321. {
  1322. case PARAMETER_ACTIVE:
  1323. return setActive((value > 0.0f), sendOsc, sendCallback);
  1324. case PARAMETER_CTRL_CHANNEL:
  1325. return setCtrlChannel(int8_t(value), sendOsc, sendCallback);
  1326. case PARAMETER_DRYWET:
  1327. return setDryWet(value, sendOsc, sendCallback);
  1328. case PARAMETER_VOLUME:
  1329. return setVolume(value, sendOsc, sendCallback);
  1330. case PARAMETER_BALANCE_LEFT:
  1331. return setBalanceLeft(value, sendOsc, sendCallback);
  1332. case PARAMETER_BALANCE_RIGHT:
  1333. return setBalanceRight(value, sendOsc, sendCallback);
  1334. case PARAMETER_PANNING:
  1335. return setPanning(value, sendOsc, sendCallback);
  1336. }
  1337. #endif
  1338. CARLA_SAFE_ASSERT_RETURN(rindex >= 0,);
  1339. for (uint32_t i=0; i < pData->param.count; ++i)
  1340. {
  1341. if (pData->param.data[i].rindex == rindex)
  1342. {
  1343. //if (carla_isNotEqual(getParameterValue(i), value))
  1344. setParameterValue(i, value, sendGui, sendOsc, sendCallback);
  1345. break;
  1346. }
  1347. }
  1348. }
  1349. void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept
  1350. {
  1351. if (pData->engineBridged) {
  1352. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1353. } else {
  1354. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1355. }
  1356. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  1357. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1358. pData->param.data[parameterId].midiChannel = channel;
  1359. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1360. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1361. if (sendOsc && pData->engine->isOscControlRegistered())
  1362. pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, parameterId, channel);
  1363. # endif
  1364. if (sendCallback)
  1365. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED,
  1366. pData->id,
  1367. static_cast<int>(parameterId),
  1368. channel,
  1369. 0, 0.0f, nullptr);
  1370. #endif
  1371. }
  1372. void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, const int16_t cc, const bool sendOsc, const bool sendCallback) noexcept
  1373. {
  1374. if (pData->engineBridged) {
  1375. CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,);
  1376. } else {
  1377. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  1378. }
  1379. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  1380. CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc < MAX_MIDI_CONTROL,);
  1381. pData->param.data[parameterId].midiCC = cc;
  1382. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1383. # if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1384. if (sendOsc && pData->engine->isOscControlRegistered())
  1385. pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, parameterId, cc);
  1386. # endif
  1387. if (sendCallback)
  1388. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED,
  1389. pData->id,
  1390. static_cast<int>(parameterId),
  1391. cc,
  1392. 0, 0.0f, nullptr);
  1393. #endif
  1394. }
  1395. void CarlaPlugin::setCustomData(const char* const type, const char* const key, const char* const value, const bool)
  1396. {
  1397. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  1398. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  1399. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  1400. // Ignore some keys
  1401. if (std::strcmp(type, CUSTOM_DATA_TYPE_STRING) == 0)
  1402. {
  1403. const PluginType ptype = getType();
  1404. if ((ptype == PLUGIN_INTERNAL && std::strncmp(key, "CarlaAlternateFile", 18) == 0) ||
  1405. (ptype == PLUGIN_DSSI && std::strcmp (key, "guiVisible") == 0) ||
  1406. (ptype == PLUGIN_LV2 && std::strncmp(key, "OSC:", 4) == 0))
  1407. return;
  1408. }
  1409. // Check if we already have this key
  1410. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin2(); it.valid(); it.next())
  1411. {
  1412. CustomData& customData(it.getValue(kCustomDataFallbackNC));
  1413. CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  1414. if (std::strcmp(customData.key, key) == 0)
  1415. {
  1416. if (customData.value != nullptr)
  1417. delete[] customData.value;
  1418. customData.value = carla_strdup(value);
  1419. return;
  1420. }
  1421. }
  1422. // Otherwise store it
  1423. CustomData customData;
  1424. customData.type = carla_strdup(type);
  1425. customData.key = carla_strdup(key);
  1426. customData.value = carla_strdup(value);
  1427. pData->custom.append(customData);
  1428. }
  1429. void CarlaPlugin::setChunkData(const void* const data, const std::size_t dataSize)
  1430. {
  1431. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  1432. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  1433. CARLA_SAFE_ASSERT(false); // this should never happen
  1434. }
  1435. void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool) noexcept
  1436. {
  1437. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  1438. pData->prog.current = index;
  1439. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1440. const bool reallySendOsc(sendOsc && pData->engine->isOscControlRegistered());
  1441. if (reallySendOsc && index < 50)
  1442. pData->engine->oscSend_control_set_current_program(pData->id, index);
  1443. #else
  1444. const bool reallySendOsc(false);
  1445. #endif
  1446. if (sendCallback)
  1447. pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED,
  1448. pData->id,
  1449. index,
  1450. 0, 0, 0.0f, nullptr);
  1451. // Change default parameter values
  1452. if (index >= 0)
  1453. {
  1454. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1455. uiProgramChange(static_cast<uint32_t>(index));
  1456. switch (getType())
  1457. {
  1458. case PLUGIN_SF2:
  1459. case PLUGIN_SFZ:
  1460. break;
  1461. default:
  1462. pData->updateParameterValues(this, reallySendOsc, sendCallback, true);
  1463. break;
  1464. }
  1465. }
  1466. // may be unused
  1467. return; (void)sendOsc;
  1468. }
  1469. void CarlaPlugin::setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool) noexcept
  1470. {
  1471. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  1472. pData->midiprog.current = index;
  1473. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1474. const bool reallySendOsc(sendOsc && pData->engine->isOscControlRegistered());
  1475. if (reallySendOsc && index < 50)
  1476. pData->engine->oscSend_control_set_current_midi_program(pData->id, index);
  1477. #else
  1478. const bool reallySendOsc(false);
  1479. #endif
  1480. if (sendCallback)
  1481. pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED,
  1482. pData->id,
  1483. index,
  1484. 0, 0, 0.0f, nullptr);
  1485. // Change default parameter values
  1486. if (index >= 0)
  1487. {
  1488. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1489. uiMidiProgramChange(static_cast<uint32_t>(index));
  1490. switch (getType())
  1491. {
  1492. case PLUGIN_SF2:
  1493. case PLUGIN_SFZ:
  1494. break;
  1495. default:
  1496. pData->updateParameterValues(this, reallySendOsc, sendCallback, true);
  1497. break;
  1498. }
  1499. }
  1500. // may be unused
  1501. return; (void)sendOsc;
  1502. }
  1503. void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  1504. {
  1505. for (uint32_t i=0; i < pData->midiprog.count; ++i)
  1506. {
  1507. if (pData->midiprog.data[i].bank == bank && pData->midiprog.data[i].program == program)
  1508. return setMidiProgram(static_cast<int32_t>(i), sendGui, sendOsc, sendCallback);
  1509. }
  1510. }
  1511. void CarlaPlugin::setProgramRT(const uint32_t uindex) noexcept
  1512. {
  1513. CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,);
  1514. const int32_t index = static_cast<int32_t>(uindex);
  1515. pData->prog.current = index;
  1516. // Change default parameter values
  1517. switch (getType())
  1518. {
  1519. case PLUGIN_SF2:
  1520. case PLUGIN_SFZ:
  1521. break;
  1522. default:
  1523. pData->updateDefaultParameterValues(this);
  1524. break;
  1525. }
  1526. pData->postponeRtEvent(kPluginPostRtEventProgramChange, index, 0, 0, 0.0f);
  1527. }
  1528. void CarlaPlugin::setMidiProgramRT(const uint32_t uindex) noexcept
  1529. {
  1530. CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
  1531. const int32_t index = static_cast<int32_t>(uindex);
  1532. pData->midiprog.current = index;
  1533. // Change default parameter values
  1534. switch (getType())
  1535. {
  1536. case PLUGIN_SF2:
  1537. case PLUGIN_SFZ:
  1538. break;
  1539. default:
  1540. pData->updateDefaultParameterValues(this);
  1541. break;
  1542. }
  1543. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0, 0.0f);
  1544. }
  1545. // -------------------------------------------------------------------
  1546. // Plugin state
  1547. void CarlaPlugin::reloadPrograms(const bool)
  1548. {
  1549. }
  1550. // -------------------------------------------------------------------
  1551. // Plugin processing
  1552. void CarlaPlugin::activate() noexcept
  1553. {
  1554. CARLA_SAFE_ASSERT(! pData->active);
  1555. }
  1556. void CarlaPlugin::deactivate() noexcept
  1557. {
  1558. CARLA_SAFE_ASSERT(pData->active);
  1559. }
  1560. void CarlaPlugin::bufferSizeChanged(const uint32_t)
  1561. {
  1562. }
  1563. void CarlaPlugin::sampleRateChanged(const double)
  1564. {
  1565. }
  1566. void CarlaPlugin::offlineModeChanged(const bool)
  1567. {
  1568. }
  1569. // -------------------------------------------------------------------
  1570. // Misc
  1571. void CarlaPlugin::idle()
  1572. {
  1573. if (! pData->enabled)
  1574. return;
  1575. const bool hasUI(pData->hints & PLUGIN_HAS_CUSTOM_UI);
  1576. const bool needsUiMainThread(pData->hints & PLUGIN_NEEDS_UI_MAIN_THREAD);
  1577. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1578. const bool sendOsc(pData->engine->isOscControlRegistered());
  1579. #endif
  1580. const uint32_t latency(getLatencyInFrames());
  1581. if (pData->latency.frames != latency)
  1582. {
  1583. carla_stdout("latency changed to %i samples", latency);
  1584. const ScopedSingleProcessLocker sspl(this, true);
  1585. pData->client->setLatency(latency);
  1586. #ifndef BUILD_BRIDGE
  1587. pData->latency.recreateBuffers(pData->latency.channels, latency);
  1588. #else
  1589. pData->latency.frames = latency;
  1590. #endif
  1591. }
  1592. const CarlaMutexLocker sl(pData->postRtEvents.getDataMutex());
  1593. for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.getDataIterator(); it.valid(); it.next())
  1594. {
  1595. const PluginPostRtEvent& event(it.getValue(kPluginPostRtEventFallback));
  1596. CARLA_SAFE_ASSERT_CONTINUE(event.type != kPluginPostRtEventNull);
  1597. switch (event.type)
  1598. {
  1599. case kPluginPostRtEventNull: {
  1600. } break;
  1601. case kPluginPostRtEventDebug: {
  1602. pData->engine->callback(ENGINE_CALLBACK_DEBUG, pData->id,
  1603. event.value1, event.value2,
  1604. 0,
  1605. event.valueF,
  1606. nullptr);
  1607. } break;
  1608. case kPluginPostRtEventParameterChange: {
  1609. // Update UI
  1610. if (event.value1 >= 0 && hasUI)
  1611. {
  1612. if (needsUiMainThread)
  1613. pData->postUiEvents.append(event);
  1614. else
  1615. uiParameterChange(static_cast<uint32_t>(event.value1), event.valueF);
  1616. }
  1617. if (event.value2 != 1)
  1618. {
  1619. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1620. // Update OSC control client
  1621. if (sendOsc)
  1622. pData->engine->oscSend_control_set_parameter_value(pData->id, event.value1, event.valueF);
  1623. #endif
  1624. // Update Host
  1625. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1626. pData->id,
  1627. event.value1,
  1628. 0, 0,
  1629. event.valueF,
  1630. nullptr);
  1631. }
  1632. } break;
  1633. case kPluginPostRtEventProgramChange: {
  1634. // Update UI
  1635. if (event.value1 >= 0 && hasUI)
  1636. {
  1637. if (needsUiMainThread)
  1638. pData->postUiEvents.append(event);
  1639. else
  1640. uiProgramChange(static_cast<uint32_t>(event.value1));
  1641. }
  1642. // Update param values
  1643. for (uint32_t j=0; j < pData->param.count; ++j)
  1644. {
  1645. const float paramDefault(pData->param.ranges[j].def);
  1646. const float paramValue(getParameterValue(j));
  1647. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1648. if (sendOsc && j < 50)
  1649. {
  1650. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(j), paramValue);
  1651. pData->engine->oscSend_control_set_default_value(pData->id, j, paramDefault);
  1652. }
  1653. #endif
  1654. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1655. pData->id,
  1656. static_cast<int>(j),
  1657. 0, 0,
  1658. paramValue,
  1659. nullptr);
  1660. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED,
  1661. pData->id,
  1662. static_cast<int>(j),
  1663. 0, 0,
  1664. paramDefault,
  1665. nullptr);
  1666. }
  1667. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1668. // Update OSC control client
  1669. if (sendOsc)
  1670. pData->engine->oscSend_control_set_current_program(pData->id, event.value1);
  1671. #endif
  1672. // Update Host
  1673. pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED,
  1674. pData->id,
  1675. event.value1,
  1676. 0, 0, 0.0f, nullptr);
  1677. } break;
  1678. case kPluginPostRtEventMidiProgramChange: {
  1679. // Update UI
  1680. if (event.value1 >= 0 && hasUI)
  1681. {
  1682. if (needsUiMainThread)
  1683. pData->postUiEvents.append(event);
  1684. else
  1685. uiMidiProgramChange(static_cast<uint32_t>(event.value1));
  1686. }
  1687. // Update param values
  1688. for (uint32_t j=0; j < pData->param.count; ++j)
  1689. {
  1690. const float paramDefault(pData->param.ranges[j].def);
  1691. const float paramValue(getParameterValue(j));
  1692. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1693. if (sendOsc && j < 50)
  1694. {
  1695. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(j), paramValue);
  1696. pData->engine->oscSend_control_set_default_value(pData->id, j, paramDefault);
  1697. }
  1698. #endif
  1699. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  1700. pData->id,
  1701. static_cast<int>(j),
  1702. 0, 0,
  1703. paramValue,
  1704. nullptr);
  1705. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED,
  1706. pData->id,
  1707. static_cast<int>(j),
  1708. 0, 0,
  1709. paramDefault,
  1710. nullptr);
  1711. }
  1712. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1713. // Update OSC control client
  1714. if (sendOsc)
  1715. pData->engine->oscSend_control_set_current_midi_program(pData->id, event.value1);
  1716. #endif
  1717. // Update Host
  1718. pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED,
  1719. pData->id,
  1720. event.value1,
  1721. 0, 0, 0.0f, nullptr);
  1722. } break;
  1723. case kPluginPostRtEventNoteOn: {
  1724. CARLA_SAFE_ASSERT_BREAK(event.value1 >= 0 && event.value1 < MAX_MIDI_CHANNELS);
  1725. CARLA_SAFE_ASSERT_BREAK(event.value2 >= 0 && event.value2 < MAX_MIDI_NOTE);
  1726. CARLA_SAFE_ASSERT_BREAK(event.value4 >= 0 && event.value4 < MAX_MIDI_VALUE);
  1727. const uint8_t channel = static_cast<uint8_t>(event.value1);
  1728. const uint8_t note = static_cast<uint8_t>(event.value2);
  1729. const uint8_t velocity = static_cast<uint8_t>(event.value4);
  1730. // Update UI
  1731. if (hasUI)
  1732. {
  1733. if (needsUiMainThread)
  1734. pData->postUiEvents.append(event);
  1735. else
  1736. uiNoteOn(channel, note, velocity);
  1737. }
  1738. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1739. // Update OSC control client
  1740. if (sendOsc)
  1741. pData->engine->oscSend_control_note_on(pData->id, channel, note, velocity);
  1742. #endif
  1743. // Update Host
  1744. pData->engine->callback(ENGINE_CALLBACK_NOTE_ON,
  1745. pData->id,
  1746. event.value1,
  1747. event.value2,
  1748. event.value4,
  1749. 0.0f, nullptr);
  1750. } break;
  1751. case kPluginPostRtEventNoteOff: {
  1752. CARLA_SAFE_ASSERT_BREAK(event.value1 >= 0 && event.value1 < MAX_MIDI_CHANNELS);
  1753. CARLA_SAFE_ASSERT_BREAK(event.value2 >= 0 && event.value2 < MAX_MIDI_NOTE);
  1754. const uint8_t channel = static_cast<uint8_t>(event.value1);
  1755. const uint8_t note = static_cast<uint8_t>(event.value2);
  1756. // Update UI
  1757. if (hasUI)
  1758. {
  1759. if (needsUiMainThread)
  1760. pData->postUiEvents.append(event);
  1761. else
  1762. uiNoteOff(channel, note);
  1763. }
  1764. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1765. // Update OSC control client
  1766. if (sendOsc)
  1767. pData->engine->oscSend_control_note_off(pData->id, channel, note);
  1768. #endif
  1769. // Update Host
  1770. pData->engine->callback(ENGINE_CALLBACK_NOTE_OFF,
  1771. pData->id,
  1772. event.value1,
  1773. event.value2,
  1774. 0, 0.0f, nullptr);
  1775. } break;
  1776. }
  1777. }
  1778. pData->postRtEvents.clearData();
  1779. }
  1780. bool CarlaPlugin::tryLock(const bool forcedOffline) noexcept
  1781. {
  1782. if (forcedOffline)
  1783. {
  1784. #ifndef STOAT_TEST_BUILD
  1785. pData->masterMutex.lock();
  1786. return true;
  1787. #endif
  1788. }
  1789. return pData->masterMutex.tryLock();
  1790. }
  1791. void CarlaPlugin::unlock() noexcept
  1792. {
  1793. pData->masterMutex.unlock();
  1794. }
  1795. // -------------------------------------------------------------------
  1796. // Plugin buffers
  1797. void CarlaPlugin::initBuffers() const noexcept
  1798. {
  1799. pData->audioIn.initBuffers();
  1800. pData->audioOut.initBuffers();
  1801. pData->cvIn.initBuffers();
  1802. pData->cvOut.initBuffers();
  1803. pData->event.initBuffers();
  1804. }
  1805. void CarlaPlugin::clearBuffers() noexcept
  1806. {
  1807. pData->clearBuffers();
  1808. }
  1809. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1810. // -------------------------------------------------------------------
  1811. // OSC stuff
  1812. void CarlaPlugin::registerToOscClient() noexcept
  1813. {
  1814. if (! pData->engine->isOscControlRegistered())
  1815. return;
  1816. pData->engine->oscSend_control_add_plugin_start(pData->id, pData->name);
  1817. // Base data
  1818. {
  1819. char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1];
  1820. carla_zeroChars(bufName, STR_MAX);
  1821. carla_zeroChars(bufLabel, STR_MAX);
  1822. carla_zeroChars(bufMaker, STR_MAX);
  1823. carla_zeroChars(bufCopyright, STR_MAX);
  1824. getRealName(bufName);
  1825. getLabel(bufLabel);
  1826. getMaker(bufMaker);
  1827. getCopyright(bufCopyright);
  1828. pData->engine->oscSend_control_set_plugin_info1(pData->id, getType(), getCategory(), pData->hints, getUniqueId());
  1829. pData->engine->oscSend_control_set_plugin_info2(pData->id, bufName, bufLabel, bufMaker, bufCopyright);
  1830. }
  1831. // Base count
  1832. uint32_t paramIns, paramOuts;
  1833. {
  1834. getParameterCountInfo(paramIns, paramOuts);
  1835. if (paramIns > 49)
  1836. paramIns = 49;
  1837. if (paramOuts > 49)
  1838. paramOuts = 49;
  1839. pData->engine->oscSend_control_set_audio_count(pData->id, getAudioInCount(), getAudioOutCount());
  1840. pData->engine->oscSend_control_set_midi_count(pData->id, getMidiInCount(), getMidiOutCount());
  1841. pData->engine->oscSend_control_set_parameter_count(pData->id, paramIns, paramOuts);
  1842. }
  1843. // Plugin Parameters
  1844. if (const uint32_t count = std::min<uint32_t>(pData->param.count, 98U))
  1845. {
  1846. char bufName[STR_MAX+1], bufUnit[STR_MAX+1];
  1847. for (uint32_t i=0; i<count; ++i)
  1848. {
  1849. const ParameterData& paramData(pData->param.data[i]);
  1850. if (paramData.type == PARAMETER_INPUT)
  1851. {
  1852. if (--paramIns == 0)
  1853. break;
  1854. }
  1855. else if (paramData.type == PARAMETER_OUTPUT)
  1856. {
  1857. if (--paramOuts == 0)
  1858. break;
  1859. }
  1860. else
  1861. {
  1862. continue;
  1863. }
  1864. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  1865. carla_zeroChars(bufName, STR_MAX);
  1866. carla_zeroChars(bufUnit, STR_MAX);
  1867. getParameterName(i, bufName);
  1868. getParameterUnit(i, bufUnit);
  1869. pData->engine->oscSend_control_set_parameter_data(pData->id, i, paramData.type, paramData.hints, bufName, bufUnit);
  1870. pData->engine->oscSend_control_set_parameter_ranges1(pData->id, i, paramRanges.def, paramRanges.min, paramRanges.max);
  1871. pData->engine->oscSend_control_set_parameter_ranges2(pData->id, i, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
  1872. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(i), getParameterValue(i));
  1873. if (paramData.midiCC >= 0)
  1874. pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, i, paramData.midiCC);
  1875. if (paramData.midiChannel != 0)
  1876. pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, i, paramData.midiChannel);
  1877. }
  1878. }
  1879. // Programs
  1880. if (const uint32_t count = std::min<uint32_t>(pData->prog.count, 50U))
  1881. {
  1882. pData->engine->oscSend_control_set_program_count(pData->id, count);
  1883. for (uint32_t i=0; i < count; ++i)
  1884. pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
  1885. pData->engine->oscSend_control_set_current_program(pData->id, pData->prog.current);
  1886. }
  1887. // MIDI Programs
  1888. if (const uint32_t count = std::min<uint32_t>(pData->midiprog.count, 50U))
  1889. {
  1890. pData->engine->oscSend_control_set_midi_program_count(pData->id, count);
  1891. for (uint32_t i=0; i < count; ++i)
  1892. {
  1893. const MidiProgramData& mpData(pData->midiprog.data[i]);
  1894. pData->engine->oscSend_control_set_midi_program_data(pData->id, i, mpData.bank, mpData.program, mpData.name);
  1895. }
  1896. pData->engine->oscSend_control_set_current_midi_program(pData->id, pData->midiprog.current);
  1897. }
  1898. pData->engine->oscSend_control_add_plugin_end(pData->id);
  1899. // Internal Parameters
  1900. {
  1901. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, pData->postProc.dryWet);
  1902. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, pData->postProc.volume);
  1903. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, pData->postProc.balanceLeft);
  1904. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, pData->postProc.balanceRight);
  1905. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, pData->postProc.panning);
  1906. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, pData->ctrlChannel);
  1907. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, pData->active ? 1.0f : 0.0f);
  1908. }
  1909. }
  1910. #endif
  1911. // FIXME
  1912. void CarlaPlugin::handleOscMessage(const char* const, const int, const void* const, const char* const, const lo_message)
  1913. {
  1914. // do nothing
  1915. }
  1916. //#endif // HAVE_LIBLO && ! BUILD_BRIDGE
  1917. // -------------------------------------------------------------------
  1918. // MIDI events
  1919. void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback)
  1920. {
  1921. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1922. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1923. CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,);
  1924. if (! pData->active)
  1925. return;
  1926. ExternalMidiNote extNote;
  1927. extNote.channel = static_cast<int8_t>(channel);
  1928. extNote.note = note;
  1929. extNote.velo = velo;
  1930. pData->extNotes.appendNonRT(extNote);
  1931. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1932. {
  1933. if (velo > 0)
  1934. uiNoteOn(channel, note, velo);
  1935. else
  1936. uiNoteOff(channel, note);
  1937. }
  1938. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  1939. if (sendOsc && pData->engine->isOscControlRegistered())
  1940. {
  1941. if (velo > 0)
  1942. pData->engine->oscSend_control_note_on(pData->id, channel, note, velo);
  1943. else
  1944. pData->engine->oscSend_control_note_off(pData->id, channel, note);
  1945. }
  1946. #endif
  1947. if (sendCallback)
  1948. pData->engine->callback((velo > 0) ? ENGINE_CALLBACK_NOTE_ON : ENGINE_CALLBACK_NOTE_OFF,
  1949. pData->id,
  1950. channel,
  1951. note,
  1952. velo,
  1953. 0.0f, nullptr);
  1954. // may be unused
  1955. return; (void)sendOsc;
  1956. }
  1957. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1958. void CarlaPlugin::sendMidiAllNotesOffToCallback()
  1959. {
  1960. if (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)
  1961. return;
  1962. PluginPostRtEvent postEvent;
  1963. postEvent.type = kPluginPostRtEventNoteOff;
  1964. postEvent.value1 = pData->ctrlChannel;
  1965. postEvent.value2 = 0;
  1966. postEvent.value4 = 0;
  1967. postEvent.valueF = 0.0f;
  1968. for (int32_t i=0; i < MAX_MIDI_NOTE; ++i)
  1969. {
  1970. postEvent.value2 = i;
  1971. pData->postRtEvents.appendRT(postEvent);
  1972. }
  1973. }
  1974. #endif
  1975. // -------------------------------------------------------------------
  1976. // UI Stuff
  1977. void CarlaPlugin::showCustomUI(const bool yesNo)
  1978. {
  1979. if (yesNo) {
  1980. CARLA_SAFE_ASSERT(false);
  1981. }
  1982. }
  1983. void CarlaPlugin::uiIdle()
  1984. {
  1985. if (pData->hints & PLUGIN_NEEDS_UI_MAIN_THREAD)
  1986. {
  1987. // Update parameter outputs
  1988. for (uint32_t i=0; i < pData->param.count; ++i)
  1989. {
  1990. if (pData->param.data[i].type == PARAMETER_OUTPUT)
  1991. uiParameterChange(i, getParameterValue(i));
  1992. }
  1993. const CarlaMutexLocker sl(pData->postUiEvents.mutex);
  1994. for (LinkedList<PluginPostRtEvent>::Itenerator it = pData->postUiEvents.data.begin2(); it.valid(); it.next())
  1995. {
  1996. const PluginPostRtEvent& event(it.getValue(kPluginPostRtEventFallback));
  1997. CARLA_SAFE_ASSERT_CONTINUE(event.type != kPluginPostRtEventNull);
  1998. switch (event.type)
  1999. {
  2000. case kPluginPostRtEventNull:
  2001. case kPluginPostRtEventDebug:
  2002. break;
  2003. case kPluginPostRtEventParameterChange:
  2004. uiParameterChange(static_cast<uint32_t>(event.value1), event.valueF);
  2005. break;
  2006. case kPluginPostRtEventProgramChange:
  2007. uiProgramChange(static_cast<uint32_t>(event.value1));
  2008. break;
  2009. case kPluginPostRtEventMidiProgramChange:
  2010. uiMidiProgramChange(static_cast<uint32_t>(event.value1));
  2011. break;
  2012. case kPluginPostRtEventNoteOn:
  2013. uiNoteOn(static_cast<uint8_t>(event.value1),
  2014. static_cast<uint8_t>(event.value2),
  2015. static_cast<uint8_t>(event.value4));
  2016. break;
  2017. case kPluginPostRtEventNoteOff:
  2018. uiNoteOff(static_cast<uint8_t>(event.value1),
  2019. static_cast<uint8_t>(event.value2));
  2020. break;
  2021. }
  2022. }
  2023. pData->postUiEvents.data.clear();
  2024. }
  2025. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  2026. if (pData->transientTryCounter == 0)
  2027. return;
  2028. if (++pData->transientTryCounter % 10 != 0)
  2029. return;
  2030. if (pData->transientTryCounter >= 200)
  2031. return;
  2032. carla_stdout("Trying to get window...");
  2033. CarlaString uiTitle(pData->name);
  2034. uiTitle += " (GUI)";
  2035. if (CarlaPluginUI::tryTransientWinIdMatch(getUiBridgeProcessId(), uiTitle,
  2036. pData->engine->getOptions().frontendWinId, pData->transientFirstTry))
  2037. {
  2038. pData->transientTryCounter = 0;
  2039. pData->transientFirstTry = false;
  2040. }
  2041. #endif
  2042. }
  2043. void CarlaPlugin::uiParameterChange(const uint32_t index, const float value) noexcept
  2044. {
  2045. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  2046. return;
  2047. // unused
  2048. (void)value;
  2049. }
  2050. void CarlaPlugin::uiProgramChange(const uint32_t index) noexcept
  2051. {
  2052. CARLA_SAFE_ASSERT_RETURN(index < getProgramCount(),);
  2053. }
  2054. void CarlaPlugin::uiMidiProgramChange(const uint32_t index) noexcept
  2055. {
  2056. CARLA_SAFE_ASSERT_RETURN(index < getMidiProgramCount(),);
  2057. }
  2058. void CarlaPlugin::uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept
  2059. {
  2060. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  2061. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  2062. CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
  2063. }
  2064. void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note) noexcept
  2065. {
  2066. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  2067. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  2068. }
  2069. CarlaEngine* CarlaPlugin::getEngine() const noexcept
  2070. {
  2071. return pData->engine;
  2072. }
  2073. CarlaEngineClient* CarlaPlugin::getEngineClient() const noexcept
  2074. {
  2075. return pData->client;
  2076. }
  2077. CarlaEngineAudioPort* CarlaPlugin::getAudioInPort(const uint32_t index) const noexcept
  2078. {
  2079. return pData->audioIn.ports[index].port;
  2080. }
  2081. CarlaEngineAudioPort* CarlaPlugin::getAudioOutPort(const uint32_t index) const noexcept
  2082. {
  2083. return pData->audioOut.ports[index].port;
  2084. }
  2085. CarlaEngineCVPort* CarlaPlugin::getCVInPort(const uint32_t index) const noexcept
  2086. {
  2087. return pData->cvIn.ports[index].port;
  2088. }
  2089. CarlaEngineCVPort* CarlaPlugin::getCVOutPort(const uint32_t index) const noexcept
  2090. {
  2091. return pData->cvOut.ports[index].port;
  2092. }
  2093. CarlaEngineEventPort* CarlaPlugin::getDefaultEventInPort() const noexcept
  2094. {
  2095. return pData->event.portIn;
  2096. }
  2097. CarlaEngineEventPort* CarlaPlugin::getDefaultEventOutPort() const noexcept
  2098. {
  2099. return pData->event.portOut;
  2100. }
  2101. void* CarlaPlugin::getNativeHandle() const noexcept
  2102. {
  2103. return nullptr;
  2104. }
  2105. const void* CarlaPlugin::getNativeDescriptor() const noexcept
  2106. {
  2107. return nullptr;
  2108. }
  2109. uintptr_t CarlaPlugin::getUiBridgeProcessId() const noexcept
  2110. {
  2111. return 0;
  2112. }
  2113. // -------------------------------------------------------------------
  2114. uint32_t CarlaPlugin::getPatchbayNodeId() const noexcept
  2115. {
  2116. return pData->nodeId;
  2117. }
  2118. void CarlaPlugin::setPatchbayNodeId(const uint32_t nodeId) noexcept
  2119. {
  2120. pData->nodeId = nodeId;
  2121. }
  2122. // -------------------------------------------------------------------
  2123. void CarlaPlugin::restoreLV2State() noexcept
  2124. {
  2125. carla_stderr2("Warning: restoreLV2State() called for non-implemented type");
  2126. }
  2127. void CarlaPlugin::waitForBridgeSaveSignal() noexcept
  2128. {
  2129. }
  2130. // -------------------------------------------------------------------
  2131. // Scoped Disabler
  2132. CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin) noexcept
  2133. : fPlugin(plugin),
  2134. fWasEnabled(false)
  2135. {
  2136. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  2137. CARLA_SAFE_ASSERT_RETURN(plugin->pData != nullptr,);
  2138. CARLA_SAFE_ASSERT_RETURN(plugin->pData->client != nullptr,);
  2139. carla_debug("CarlaPlugin::ScopedDisabler(%p)", plugin);
  2140. plugin->pData->masterMutex.lock();
  2141. if (plugin->pData->enabled)
  2142. {
  2143. fWasEnabled = true;
  2144. plugin->pData->enabled = false;
  2145. if (plugin->pData->client->isActive())
  2146. plugin->pData->client->deactivate();
  2147. }
  2148. }
  2149. CarlaPlugin::ScopedDisabler::~ScopedDisabler() noexcept
  2150. {
  2151. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  2152. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  2153. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData->client != nullptr,);
  2154. carla_debug("CarlaPlugin::~ScopedDisabler()");
  2155. if (fWasEnabled)
  2156. {
  2157. fPlugin->pData->enabled = true;
  2158. fPlugin->pData->client->activate();
  2159. }
  2160. fPlugin->pData->masterMutex.unlock();
  2161. }
  2162. // -------------------------------------------------------------------
  2163. // Scoped Process Locker
  2164. CarlaPlugin::ScopedSingleProcessLocker::ScopedSingleProcessLocker(CarlaPlugin* const plugin, const bool block) noexcept
  2165. : fPlugin(plugin),
  2166. fBlock(block)
  2167. {
  2168. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  2169. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  2170. carla_debug("CarlaPlugin::ScopedSingleProcessLocker(%p, %s)", plugin, bool2str(block));
  2171. if (! fBlock)
  2172. return;
  2173. plugin->pData->singleMutex.lock();
  2174. }
  2175. CarlaPlugin::ScopedSingleProcessLocker::~ScopedSingleProcessLocker() noexcept
  2176. {
  2177. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  2178. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  2179. carla_debug("CarlaPlugin::~ScopedSingleProcessLocker()");
  2180. if (! fBlock)
  2181. return;
  2182. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  2183. if (fPlugin->pData->singleMutex.wasTryLockCalled())
  2184. fPlugin->pData->needsReset = true;
  2185. #endif
  2186. fPlugin->pData->singleMutex.unlock();
  2187. }
  2188. // -------------------------------------------------------------------
  2189. CARLA_BACKEND_END_NAMESPACE