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

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
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
11 years ago
11 years ago
11 years ago
10 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
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
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 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
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
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 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
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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
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
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
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031
  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-2014 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 <ctime>
  24. #include "juce_core.h"
  25. using juce::File;
  26. using juce::MemoryOutputStream;
  27. using juce::ScopedPointer;
  28. using juce::String;
  29. using juce::XmlDocument;
  30. using juce::XmlElement;
  31. CARLA_BACKEND_START_NAMESPACE
  32. // -------------------------------------------------------------------
  33. // Fallback data
  34. static const ParameterData kParameterDataNull = { PARAMETER_UNKNOWN, 0x0, PARAMETER_NULL, -1, -1, 0 };
  35. static const ParameterRanges kParameterRangesNull = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f };
  36. static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr };
  37. static const CustomData kCustomDataNull = { nullptr, nullptr, nullptr };
  38. // -------------------------------------------------------------------
  39. // ParamSymbol struct, needed for CarlaPlugin::loadStateSave()
  40. struct ParamSymbol {
  41. int32_t index;
  42. const char* symbol;
  43. ParamSymbol(const uint32_t i, const char* const s)
  44. : index(static_cast<int32_t>(i)),
  45. symbol(carla_strdup(s)) {}
  46. ~ParamSymbol() noexcept
  47. {
  48. CARLA_SAFE_ASSERT_RETURN(symbol != nullptr,)
  49. delete[] symbol;
  50. symbol = nullptr;
  51. }
  52. #ifdef CARLA_PROPER_CPP11_SUPPORT
  53. ParamSymbol() = delete;
  54. CARLA_DECLARE_NON_COPY_STRUCT(ParamSymbol)
  55. #endif
  56. };
  57. // -------------------------------------------------------------------
  58. // Constructor and destructor
  59. CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const uint id)
  60. : pData(new ProtectedData(engine, id, this))
  61. {
  62. CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
  63. CARLA_SAFE_ASSERT(id < engine->getMaxPluginNumber());
  64. carla_debug("CarlaPlugin::CarlaPlugin(%p, %i)", engine, id);
  65. switch (engine->getProccessMode())
  66. {
  67. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  68. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  69. CARLA_SAFE_ASSERT(id < MAX_DEFAULT_PLUGINS);
  70. break;
  71. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  72. CARLA_SAFE_ASSERT(id < MAX_RACK_PLUGINS);
  73. break;
  74. case ENGINE_PROCESS_MODE_PATCHBAY:
  75. CARLA_SAFE_ASSERT(id < MAX_PATCHBAY_PLUGINS);
  76. break;
  77. case ENGINE_PROCESS_MODE_BRIDGE:
  78. CARLA_SAFE_ASSERT(id == 0);
  79. break;
  80. }
  81. }
  82. CarlaPlugin::~CarlaPlugin()
  83. {
  84. carla_debug("CarlaPlugin::~CarlaPlugin()");
  85. delete pData;
  86. }
  87. // -------------------------------------------------------------------
  88. // Information (base)
  89. uint CarlaPlugin::getId() const noexcept
  90. {
  91. return pData->id;
  92. }
  93. uint CarlaPlugin::getHints() const noexcept
  94. {
  95. return pData->hints;
  96. }
  97. uint CarlaPlugin::getOptionsEnabled() const noexcept
  98. {
  99. return pData->options;
  100. }
  101. bool CarlaPlugin::isEnabled() const noexcept
  102. {
  103. return pData->enabled;
  104. }
  105. const char* CarlaPlugin::getName() const noexcept
  106. {
  107. return pData->name;
  108. }
  109. const char* CarlaPlugin::getFilename() const noexcept
  110. {
  111. return pData->filename;
  112. }
  113. const char* CarlaPlugin::getIconName() const noexcept
  114. {
  115. return pData->iconName;
  116. }
  117. PluginCategory CarlaPlugin::getCategory() const noexcept
  118. {
  119. return getPluginCategoryFromName(pData->name);
  120. }
  121. int64_t CarlaPlugin::getUniqueId() const noexcept
  122. {
  123. return 0;
  124. }
  125. uint32_t CarlaPlugin::getLatencyInFrames() const noexcept
  126. {
  127. return pData->latency;
  128. }
  129. // -------------------------------------------------------------------
  130. // Information (count)
  131. uint32_t CarlaPlugin::getAudioInCount() const noexcept
  132. {
  133. return pData->audioIn.count;
  134. }
  135. uint32_t CarlaPlugin::getAudioOutCount() const noexcept
  136. {
  137. return pData->audioOut.count;
  138. }
  139. uint32_t CarlaPlugin::getMidiInCount() const noexcept
  140. {
  141. return (pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_IN) ? 1 : 0;
  142. }
  143. uint32_t CarlaPlugin::getMidiOutCount() const noexcept
  144. {
  145. return (pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_OUT) ? 1 : 0;
  146. }
  147. uint32_t CarlaPlugin::getParameterCount() const noexcept
  148. {
  149. return pData->param.count;
  150. }
  151. uint32_t CarlaPlugin::getParameterScalePointCount(const uint32_t parameterId) const noexcept
  152. {
  153. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0);
  154. return 0;
  155. }
  156. uint32_t CarlaPlugin::getProgramCount() const noexcept
  157. {
  158. return pData->prog.count;
  159. }
  160. uint32_t CarlaPlugin::getMidiProgramCount() const noexcept
  161. {
  162. return pData->midiprog.count;
  163. }
  164. uint32_t CarlaPlugin::getCustomDataCount() const noexcept
  165. {
  166. return static_cast<uint32_t>(pData->custom.count());
  167. }
  168. // -------------------------------------------------------------------
  169. // Information (current data)
  170. int32_t CarlaPlugin::getCurrentProgram() const noexcept
  171. {
  172. return pData->prog.current;
  173. }
  174. int32_t CarlaPlugin::getCurrentMidiProgram() const noexcept
  175. {
  176. return pData->midiprog.current;
  177. }
  178. const ParameterData& CarlaPlugin::getParameterData(const uint32_t parameterId) const noexcept
  179. {
  180. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, kParameterDataNull);
  181. return pData->param.data[parameterId];
  182. }
  183. const ParameterRanges& CarlaPlugin::getParameterRanges(const uint32_t parameterId) const noexcept
  184. {
  185. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, kParameterRangesNull);
  186. return pData->param.ranges[parameterId];
  187. }
  188. bool CarlaPlugin::isParameterOutput(const uint32_t parameterId) const noexcept
  189. {
  190. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  191. return (pData->param.data[parameterId].type == PARAMETER_OUTPUT);
  192. }
  193. const MidiProgramData& CarlaPlugin::getMidiProgramData(const uint32_t index) const noexcept
  194. {
  195. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count, kMidiProgramDataNull);
  196. return pData->midiprog.data[index];
  197. }
  198. const CustomData& CarlaPlugin::getCustomData(const uint32_t index) const noexcept
  199. {
  200. CARLA_SAFE_ASSERT_RETURN(index < pData->custom.count(), kCustomDataNull);
  201. return pData->custom.getAt(index, kCustomDataNull);
  202. }
  203. std::size_t CarlaPlugin::getChunkData(void** const dataPtr) noexcept
  204. {
  205. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  206. CARLA_SAFE_ASSERT(false); // this should never happen
  207. return 0;
  208. }
  209. // -------------------------------------------------------------------
  210. // Information (per-plugin data)
  211. uint CarlaPlugin::getOptionsAvailable() const noexcept
  212. {
  213. CARLA_SAFE_ASSERT(false); // this should never happen
  214. return 0x0;
  215. }
  216. float CarlaPlugin::getParameterValue(const uint32_t parameterId) const noexcept
  217. {
  218. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(), 0.0f);
  219. CARLA_SAFE_ASSERT(false); // this should never happen
  220. return 0.0f;
  221. }
  222. float CarlaPlugin::getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept
  223. {
  224. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(), 0.0f);
  225. CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId), 0.0f);
  226. CARLA_SAFE_ASSERT(false); // this should never happen
  227. return 0.0f;
  228. }
  229. void CarlaPlugin::getLabel(char* const strBuf) const noexcept
  230. {
  231. strBuf[0] = '\0';
  232. }
  233. void CarlaPlugin::getMaker(char* const strBuf) const noexcept
  234. {
  235. strBuf[0] = '\0';
  236. }
  237. void CarlaPlugin::getCopyright(char* const strBuf) const noexcept
  238. {
  239. strBuf[0] = '\0';
  240. }
  241. void CarlaPlugin::getRealName(char* const strBuf) const noexcept
  242. {
  243. strBuf[0] = '\0';
  244. }
  245. void CarlaPlugin::getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  248. CARLA_SAFE_ASSERT(false); // this should never happen
  249. strBuf[0] = '\0';
  250. }
  251. void CarlaPlugin::getParameterSymbol(const uint32_t parameterId, char* const strBuf) const noexcept
  252. {
  253. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  254. strBuf[0] = '\0';
  255. }
  256. void CarlaPlugin::getParameterText(const uint32_t parameterId, char* const strBuf) const noexcept
  257. {
  258. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  259. CARLA_SAFE_ASSERT(false); // this should never happen
  260. strBuf[0] = '\0';
  261. }
  262. void CarlaPlugin::getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept
  263. {
  264. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  265. strBuf[0] = '\0';
  266. }
  267. void CarlaPlugin::getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept
  268. {
  269. CARLA_SAFE_ASSERT_RETURN(parameterId < getParameterCount(),);
  270. CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId),);
  271. CARLA_SAFE_ASSERT(false); // this should never happen
  272. strBuf[0] = '\0';
  273. }
  274. float CarlaPlugin::getInternalParameterValue(const int32_t parameterId) const noexcept
  275. {
  276. #ifndef BUILD_BRIDGE
  277. CARLA_SAFE_ASSERT_RETURN(parameterId != PARAMETER_NULL && parameterId > PARAMETER_MAX, 0.0f);
  278. switch (parameterId)
  279. {
  280. case PARAMETER_ACTIVE:
  281. return pData->active;
  282. case PARAMETER_CTRL_CHANNEL:
  283. return pData->ctrlChannel;
  284. case PARAMETER_DRYWET:
  285. return pData->postProc.dryWet;
  286. case PARAMETER_VOLUME:
  287. return pData->postProc.volume;
  288. case PARAMETER_BALANCE_LEFT:
  289. return pData->postProc.balanceLeft;
  290. case PARAMETER_BALANCE_RIGHT:
  291. return pData->postProc.balanceRight;
  292. case PARAMETER_PANNING:
  293. return pData->postProc.panning;
  294. };
  295. #endif
  296. CARLA_SAFE_ASSERT_RETURN(parameterId >= 0, 0.0f);
  297. return getParameterValue(static_cast<uint32_t>(parameterId));
  298. }
  299. void CarlaPlugin::getProgramName(const uint32_t index, char* const strBuf) const noexcept
  300. {
  301. CARLA_SAFE_ASSERT_RETURN(index < pData->prog.count,);
  302. CARLA_SAFE_ASSERT_RETURN(pData->prog.names[index] != nullptr,);
  303. std::strncpy(strBuf, pData->prog.names[index], STR_MAX);
  304. }
  305. void CarlaPlugin::getMidiProgramName(const uint32_t index, char* const strBuf) const noexcept
  306. {
  307. CARLA_SAFE_ASSERT_RETURN(index < pData->midiprog.count,);
  308. CARLA_SAFE_ASSERT_RETURN(pData->midiprog.data[index].name != nullptr,);
  309. std::strncpy(strBuf, pData->midiprog.data[index].name, STR_MAX);
  310. }
  311. void CarlaPlugin::getParameterCountInfo(uint32_t& ins, uint32_t& outs) const noexcept
  312. {
  313. ins = 0;
  314. outs = 0;
  315. for (uint32_t i=0; i < pData->param.count; ++i)
  316. {
  317. if (pData->param.data[i].type == PARAMETER_INPUT)
  318. ++ins;
  319. else if (pData->param.data[i].type == PARAMETER_OUTPUT)
  320. ++outs;
  321. }
  322. }
  323. // -------------------------------------------------------------------
  324. // Set data (state)
  325. void CarlaPlugin::prepareForSave()
  326. {
  327. }
  328. void CarlaPlugin::resetParameters() noexcept
  329. {
  330. for (uint i=0; i < pData->param.count; ++i)
  331. {
  332. const ParameterData& paramData(pData->param.data[i]);
  333. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  334. if (paramData.type != PARAMETER_INPUT)
  335. continue;
  336. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  337. continue;
  338. setParameterValue(i, paramRanges.def, true, true, true);
  339. }
  340. }
  341. void CarlaPlugin::randomizeParameters() noexcept
  342. {
  343. float value, random;
  344. char strBuf[STR_MAX+1];
  345. strBuf[STR_MAX] = '\0';
  346. std::srand(static_cast<uint>(std::time(nullptr)));
  347. for (uint i=0; i < pData->param.count; ++i)
  348. {
  349. const ParameterData& paramData(pData->param.data[i]);
  350. if (paramData.type != PARAMETER_INPUT)
  351. continue;
  352. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  353. continue;
  354. getParameterName(i, strBuf);
  355. if (std::strstr(strBuf, "olume") != nullptr)
  356. continue;
  357. if (std::strstr(strBuf, "Master") != nullptr)
  358. continue;
  359. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  360. if (paramData.hints & PARAMETER_IS_BOOLEAN)
  361. {
  362. random = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
  363. value = random > 0.5 ? paramRanges.max : paramRanges.min;
  364. }
  365. else
  366. {
  367. random = static_cast<float>(std::rand()) / static_cast<float>(RAND_MAX);
  368. value = random * (paramRanges.max - paramRanges.min) + paramRanges.min;
  369. if (paramData.hints & PARAMETER_IS_INTEGER)
  370. value = std::rint(value);
  371. }
  372. setParameterValue(i, value, true, true, true);
  373. }
  374. }
  375. const StateSave& CarlaPlugin::getStateSave()
  376. {
  377. pData->stateSave.clear();
  378. prepareForSave();
  379. const PluginType pluginType(getType());
  380. char strBuf[STR_MAX+1];
  381. // ---------------------------------------------------------------
  382. // Basic info
  383. getLabel(strBuf);
  384. pData->stateSave.type = carla_strdup(getPluginTypeAsString(getType()));
  385. pData->stateSave.name = carla_strdup(pData->name);
  386. pData->stateSave.label = carla_strdup(strBuf);
  387. pData->stateSave.uniqueId = getUniqueId();
  388. #ifndef BUILD_BRIDGE
  389. pData->stateSave.options = pData->options;
  390. #endif
  391. if (pData->filename != nullptr)
  392. pData->stateSave.binary = carla_strdup(pData->filename);
  393. #ifndef BUILD_BRIDGE
  394. // ---------------------------------------------------------------
  395. // Internals
  396. pData->stateSave.active = pData->active;
  397. pData->stateSave.dryWet = pData->postProc.dryWet;
  398. pData->stateSave.volume = pData->postProc.volume;
  399. pData->stateSave.balanceLeft = pData->postProc.balanceLeft;
  400. pData->stateSave.balanceRight = pData->postProc.balanceRight;
  401. pData->stateSave.panning = pData->postProc.panning;
  402. pData->stateSave.ctrlChannel = pData->ctrlChannel;
  403. #endif
  404. // ---------------------------------------------------------------
  405. // Chunk
  406. if (pData->options & PLUGIN_OPTION_USE_CHUNKS)
  407. {
  408. void* data = nullptr;
  409. const std::size_t dataSize(getChunkData(&data));
  410. if (data != nullptr && dataSize > 0)
  411. {
  412. pData->stateSave.chunk = CarlaString::asBase64(data, dataSize).dup();
  413. // Don't save anything else if using chunks
  414. return pData->stateSave;
  415. }
  416. }
  417. // ---------------------------------------------------------------
  418. // Current Program
  419. if (pData->prog.current >= 0 && pluginType != PLUGIN_LV2 && pluginType != PLUGIN_GIG)
  420. {
  421. pData->stateSave.currentProgramIndex = pData->prog.current;
  422. pData->stateSave.currentProgramName = carla_strdup(pData->prog.names[pData->prog.current]);
  423. }
  424. // ---------------------------------------------------------------
  425. // Current MIDI Program
  426. if (pData->midiprog.current >= 0 && pluginType != PLUGIN_LV2 && pluginType != PLUGIN_SF2)
  427. {
  428. const MidiProgramData& mpData(pData->midiprog.getCurrent());
  429. pData->stateSave.currentMidiBank = static_cast<int32_t>(mpData.bank);
  430. pData->stateSave.currentMidiProgram = static_cast<int32_t>(mpData.program);
  431. }
  432. // ---------------------------------------------------------------
  433. // Parameters
  434. const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
  435. for (uint32_t i=0; i < pData->param.count; ++i)
  436. {
  437. const ParameterData& paramData(pData->param.data[i]);
  438. if ((paramData.hints & PARAMETER_IS_ENABLED) == 0)
  439. continue;
  440. StateParameter* const stateParameter(new StateParameter());
  441. stateParameter->isInput = (paramData.type == PARAMETER_INPUT);
  442. stateParameter->index = paramData.index;
  443. #ifndef BUILD_BRIDGE
  444. stateParameter->midiCC = paramData.midiCC;
  445. stateParameter->midiChannel = paramData.midiChannel;
  446. #endif
  447. getParameterName(i, strBuf);
  448. stateParameter->name = carla_strdup(strBuf);
  449. getParameterSymbol(i, strBuf);
  450. stateParameter->symbol = carla_strdup(strBuf);;
  451. stateParameter->value = getParameterValue(i);
  452. if (paramData.hints & PARAMETER_USES_SAMPLERATE)
  453. stateParameter->value /= sampleRate;
  454. pData->stateSave.parameters.append(stateParameter);
  455. }
  456. // ---------------------------------------------------------------
  457. // Custom Data
  458. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next())
  459. {
  460. const CustomData& cData(it.getValue());
  461. StateCustomData* stateCustomData(new StateCustomData());
  462. stateCustomData->type = carla_strdup(cData.type);
  463. stateCustomData->key = carla_strdup(cData.key);
  464. stateCustomData->value = carla_strdup(cData.value);
  465. pData->stateSave.customData.append(stateCustomData);
  466. }
  467. return pData->stateSave;
  468. }
  469. void CarlaPlugin::loadStateSave(const StateSave& stateSave)
  470. {
  471. char strBuf[STR_MAX+1];
  472. const bool usesMultiProgs(pData->extraHints & PLUGIN_EXTRA_HINT_USES_MULTI_PROGS);
  473. // ---------------------------------------------------------------
  474. // Part 1 - PRE-set custom data (only that which reload programs)
  475. for (LinkedList<StateCustomData*>::Itenerator it = stateSave.customData.begin(); it.valid(); it.next())
  476. {
  477. const StateCustomData* const stateCustomData(it.getValue());
  478. const char* const key(stateCustomData->key);
  479. bool wantData = false;
  480. if (getType() == PLUGIN_DSSI && (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0))
  481. wantData = true;
  482. else if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
  483. wantData = true;
  484. if (wantData)
  485. setCustomData(stateCustomData->type, stateCustomData->key, stateCustomData->value, true);
  486. }
  487. // ---------------------------------------------------------------
  488. // Part 2 - set program
  489. if (stateSave.currentProgramIndex >= 0 && stateSave.currentProgramName != nullptr)
  490. {
  491. int32_t programId = -1;
  492. // index < count
  493. if (stateSave.currentProgramIndex < static_cast<int32_t>(pData->prog.count))
  494. {
  495. programId = stateSave.currentProgramIndex;
  496. }
  497. // index not valid, try to find by name
  498. else
  499. {
  500. for (uint32_t i=0; i < pData->prog.count; ++i)
  501. {
  502. strBuf[0] = '\0';
  503. getProgramName(i, strBuf);
  504. if (strBuf[0] != '\0' && std::strcmp(stateSave.currentProgramName, strBuf) == 0)
  505. {
  506. programId = static_cast<int32_t>(i);
  507. break;
  508. }
  509. }
  510. }
  511. // set program now, if valid
  512. if (programId >= 0)
  513. setProgram(programId, true, true, true);
  514. }
  515. // ---------------------------------------------------------------
  516. // Part 3 - set midi program
  517. if (stateSave.currentMidiBank >= 0 && stateSave.currentMidiProgram >= 0 && ! usesMultiProgs)
  518. setMidiProgramById(static_cast<uint32_t>(stateSave.currentMidiBank), static_cast<uint32_t>(stateSave.currentMidiProgram), true, true, true);
  519. // ---------------------------------------------------------------
  520. // Part 4a - get plugin parameter symbols
  521. LinkedList<ParamSymbol*> paramSymbols;
  522. if (getType() == PLUGIN_LADSPA || getType() == PLUGIN_LV2)
  523. {
  524. for (uint32_t i=0; i < pData->param.count; ++i)
  525. {
  526. strBuf[0] = '\0';
  527. getParameterSymbol(i, strBuf);
  528. if (strBuf[0] != '\0')
  529. {
  530. ParamSymbol* const paramSymbol(new ParamSymbol(i, strBuf));
  531. paramSymbols.append(paramSymbol);
  532. }
  533. }
  534. }
  535. // ---------------------------------------------------------------
  536. // Part 4b - set parameter values (carefully)
  537. const float sampleRate(static_cast<float>(pData->engine->getSampleRate()));
  538. for (LinkedList<StateParameter*>::Itenerator it = stateSave.parameters.begin(); it.valid(); it.next())
  539. {
  540. StateParameter* const stateParameter(it.getValue());
  541. int32_t index = -1;
  542. if (getType() == PLUGIN_LADSPA)
  543. {
  544. // Try to set by symbol, otherwise use index
  545. if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0')
  546. {
  547. for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin(); it2.valid(); it2.next())
  548. {
  549. ParamSymbol* const paramSymbol(it2.getValue());
  550. if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0)
  551. {
  552. index = paramSymbol->index;
  553. break;
  554. }
  555. }
  556. if (index == -1)
  557. index = stateParameter->index;
  558. }
  559. else
  560. index = stateParameter->index;
  561. }
  562. else if (getType() == PLUGIN_LV2)
  563. {
  564. // Symbol only
  565. if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0')
  566. {
  567. for (LinkedList<ParamSymbol*>::Itenerator it2 = paramSymbols.begin(); it2.valid(); it2.next())
  568. {
  569. ParamSymbol* const paramSymbol(it2.getValue());
  570. if (std::strcmp(stateParameter->symbol, paramSymbol->symbol) == 0)
  571. {
  572. index = paramSymbol->index;
  573. break;
  574. }
  575. }
  576. if (index == -1)
  577. carla_stderr("Failed to find LV2 parameter symbol '%s')", stateParameter->symbol);
  578. }
  579. else
  580. carla_stderr("LV2 Plugin parameter '%s' has no symbol", stateParameter->name);
  581. }
  582. else
  583. {
  584. // Index only
  585. index = stateParameter->index;
  586. }
  587. // Now set parameter
  588. if (index >= 0 && index < static_cast<int32_t>(pData->param.count))
  589. {
  590. //CARLA_SAFE_ASSERT(stateParameter->isInput == (pData
  591. if (stateParameter->isInput)
  592. {
  593. if (pData->param.data[index].hints & PARAMETER_USES_SAMPLERATE)
  594. stateParameter->value *= sampleRate;
  595. setParameterValue(static_cast<uint32_t>(index), stateParameter->value, true, true, true);
  596. }
  597. #ifndef BUILD_BRIDGE
  598. setParameterMidiCC(static_cast<uint32_t>(index), stateParameter->midiCC, true, true);
  599. setParameterMidiChannel(static_cast<uint32_t>(index), stateParameter->midiChannel, true, true);
  600. #endif
  601. }
  602. else
  603. carla_stderr("Could not set parameter data for '%s'", stateParameter->name);
  604. }
  605. // ---------------------------------------------------------------
  606. // Part 4c - clear
  607. for (LinkedList<ParamSymbol*>::Itenerator it = paramSymbols.begin(); it.valid(); it.next())
  608. {
  609. ParamSymbol* const paramSymbol(it.getValue());
  610. delete paramSymbol;
  611. }
  612. paramSymbols.clear();
  613. // ---------------------------------------------------------------
  614. // Part 5 - set custom data
  615. for (LinkedList<StateCustomData*>::Itenerator it = stateSave.customData.begin(); it.valid(); it.next())
  616. {
  617. const StateCustomData* const stateCustomData(it.getValue());
  618. const char* const key(stateCustomData->key);
  619. if (getType() == PLUGIN_DSSI && (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0))
  620. continue;
  621. if (usesMultiProgs && std::strcmp(key, "midiPrograms") == 0)
  622. continue;
  623. setCustomData(stateCustomData->type, stateCustomData->key, stateCustomData->value, true);
  624. }
  625. // ---------------------------------------------------------------
  626. // Part 5x - set lv2 state
  627. if (getType() == PLUGIN_LV2 && pData->custom.count() > 0)
  628. setCustomData(CUSTOM_DATA_TYPE_STRING, "CarlaLoadLv2StateNow", "true", true);
  629. // ---------------------------------------------------------------
  630. // Part 6 - set chunk
  631. if (stateSave.chunk != nullptr && (pData->options & PLUGIN_OPTION_USE_CHUNKS) != 0)
  632. {
  633. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(stateSave.chunk));
  634. setChunkData(chunk.data(), chunk.size());
  635. }
  636. #ifndef BUILD_BRIDGE
  637. // ---------------------------------------------------------------
  638. // Part 6 - set internal stuff
  639. const uint availOptions(getOptionsAvailable());
  640. for (uint i=0; i<10; ++i) // FIXME - get this value somehow...
  641. {
  642. const uint option(1u << i);
  643. if (availOptions & option)
  644. setOption(option, (stateSave.options & option) != 0, true);
  645. }
  646. setDryWet(stateSave.dryWet, true, true);
  647. setVolume(stateSave.volume, true, true);
  648. setBalanceLeft(stateSave.balanceLeft, true, true);
  649. setBalanceRight(stateSave.balanceRight, true, true);
  650. setPanning(stateSave.panning, true, true);
  651. setCtrlChannel(stateSave.ctrlChannel, true, true);
  652. setActive(stateSave.active, true, true);
  653. #endif
  654. }
  655. bool CarlaPlugin::saveStateToFile(const char* const filename)
  656. {
  657. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  658. carla_debug("CarlaPlugin::saveStateToFile(\"%s\")", filename);
  659. MemoryOutputStream out;
  660. out << "<?xml version='1.0' encoding='UTF-8'?>\n";
  661. out << "<!DOCTYPE CARLA-PRESET>\n";
  662. out << "<CARLA-PRESET VERSION='2.0'>\n";
  663. out << getStateSave().toString();
  664. out << "</CARLA-PRESET>\n";
  665. File file(filename);
  666. if (file.replaceWithData(out.getData(), out.getDataSize()))
  667. return true;
  668. pData->engine->setLastError("Failed to write file");
  669. return false;
  670. }
  671. bool CarlaPlugin::loadStateFromFile(const char* const filename)
  672. {
  673. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  674. carla_debug("CarlaPlugin::loadStateFromFile(\"%s\")", filename);
  675. File file(filename);
  676. CARLA_SAFE_ASSERT_RETURN(file.existsAsFile(), false);
  677. XmlDocument xml(file);
  678. ScopedPointer<XmlElement> xmlElement(xml.getDocumentElement(true));
  679. CARLA_SAFE_ASSERT_RETURN(xmlElement != nullptr, false);
  680. CARLA_SAFE_ASSERT_RETURN(xmlElement->getTagName().equalsIgnoreCase("carla-preset"), false);
  681. // completely load file
  682. xmlElement = xml.getDocumentElement(false);
  683. CARLA_SAFE_ASSERT_RETURN(xmlElement != nullptr, false);
  684. if (pData->stateSave.fillFromXmlElement(xmlElement->getFirstChildElement()))
  685. loadStateSave(pData->stateSave);
  686. return true;
  687. }
  688. // -------------------------------------------------------------------
  689. // Set data (internal stuff)
  690. void CarlaPlugin::setId(const uint newId) noexcept
  691. {
  692. pData->id = newId;
  693. }
  694. void CarlaPlugin::setName(const char* const newName)
  695. {
  696. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0',);
  697. if (pData->name != nullptr)
  698. delete[] pData->name;
  699. pData->name = carla_strdup(newName);
  700. }
  701. void CarlaPlugin::setOption(const uint option, const bool yesNo, const bool sendCallback)
  702. {
  703. CARLA_SAFE_ASSERT_RETURN(getOptionsAvailable() & option,);
  704. if (yesNo)
  705. pData->options |= option;
  706. else
  707. pData->options &= ~option;
  708. #ifndef BUILD_BRIDGE
  709. if (sendCallback)
  710. pData->engine->callback(ENGINE_CALLBACK_OPTION_CHANGED, pData->id, static_cast<int>(option), yesNo ? 1 : 0, 0.0f, nullptr);
  711. #else
  712. // unused
  713. return; (void)sendCallback;
  714. #endif
  715. }
  716. void CarlaPlugin::setEnabled(const bool yesNo) noexcept
  717. {
  718. if (pData->enabled == yesNo)
  719. return;
  720. pData->enabled = yesNo;
  721. pData->masterMutex.lock();
  722. pData->masterMutex.unlock();
  723. }
  724. void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback) noexcept
  725. {
  726. #ifndef BUILD_BRIDGE
  727. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  728. #endif
  729. if (pData->active == active)
  730. return;
  731. {
  732. const ScopedSingleProcessLocker spl(this, true);
  733. if (active)
  734. activate();
  735. else
  736. deactivate();
  737. }
  738. pData->active = active;
  739. #ifndef BUILD_BRIDGE
  740. const float value(active ? 1.0f : 0.0f);
  741. if (sendOsc && pData->engine->isOscControlRegistered())
  742. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, value);
  743. if (sendCallback)
  744. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_ACTIVE, 0, value, nullptr);
  745. #else
  746. // unused
  747. return; (void)sendOsc; (void)sendCallback;
  748. #endif
  749. }
  750. #ifndef BUILD_BRIDGE
  751. void CarlaPlugin::setDryWet(const float value, const bool sendOsc, const bool sendCallback) noexcept
  752. {
  753. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  754. const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value));
  755. if (carla_compareFloats(pData->postProc.dryWet, fixedValue))
  756. return;
  757. pData->postProc.dryWet = fixedValue;
  758. if (sendOsc && pData->engine->isOscControlRegistered())
  759. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, fixedValue);
  760. if (sendCallback)
  761. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_DRYWET, 0, fixedValue, nullptr);
  762. }
  763. void CarlaPlugin::setVolume(const float value, const bool sendOsc, const bool sendCallback) noexcept
  764. {
  765. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.27f);
  766. const float fixedValue(carla_fixValue<float>(0.0f, 1.27f, value));
  767. if (carla_compareFloats(pData->postProc.volume, fixedValue))
  768. return;
  769. pData->postProc.volume = fixedValue;
  770. if (sendOsc && pData->engine->isOscControlRegistered())
  771. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, fixedValue);
  772. if (sendCallback)
  773. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_VOLUME, 0, fixedValue, nullptr);
  774. }
  775. void CarlaPlugin::setBalanceLeft(const float value, const bool sendOsc, const bool sendCallback) noexcept
  776. {
  777. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  778. const float fixedValue(carla_fixValue<float>(-1.0f, 1.0f, value));
  779. if (carla_compareFloats(pData->postProc.balanceLeft, fixedValue))
  780. return;
  781. pData->postProc.balanceLeft = fixedValue;
  782. if (sendOsc && pData->engine->isOscControlRegistered())
  783. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, fixedValue);
  784. if (sendCallback)
  785. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_BALANCE_LEFT, 0, fixedValue, nullptr);
  786. }
  787. void CarlaPlugin::setBalanceRight(const float value, const bool sendOsc, const bool sendCallback) noexcept
  788. {
  789. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  790. const float fixedValue(carla_fixValue<float>(-1.0f, 1.0f, value));
  791. if (carla_compareFloats(pData->postProc.balanceRight, fixedValue))
  792. return;
  793. pData->postProc.balanceRight = fixedValue;
  794. if (sendOsc && pData->engine->isOscControlRegistered())
  795. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, fixedValue);
  796. if (sendCallback)
  797. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_BALANCE_RIGHT, 0, fixedValue, nullptr);
  798. }
  799. void CarlaPlugin::setPanning(const float value, const bool sendOsc, const bool sendCallback) noexcept
  800. {
  801. CARLA_SAFE_ASSERT(value >= -1.0f && value <= 1.0f);
  802. const float fixedValue(carla_fixValue<float>(-1.0f, 1.0f, value));
  803. if (carla_compareFloats(pData->postProc.panning, fixedValue))
  804. return;
  805. pData->postProc.panning = fixedValue;
  806. if (sendOsc && pData->engine->isOscControlRegistered())
  807. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, fixedValue);
  808. if (sendCallback)
  809. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_PANNING, 0, fixedValue, nullptr);
  810. }
  811. #endif
  812. void CarlaPlugin::setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept
  813. {
  814. #ifndef BUILD_BRIDGE
  815. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  816. #endif
  817. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);
  818. if (pData->ctrlChannel == channel)
  819. return;
  820. pData->ctrlChannel = channel;
  821. #ifndef BUILD_BRIDGE
  822. const float channelf(channel);
  823. if (sendOsc && pData->engine->isOscControlRegistered())
  824. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, channelf);
  825. if (sendCallback)
  826. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_CTRL_CHANNEL, 0, channelf, nullptr);
  827. #else
  828. // unused
  829. return; (void)sendOsc; (void)sendCallback;
  830. #endif
  831. }
  832. // -------------------------------------------------------------------
  833. // Set data (plugin-specific stuff)
  834. void CarlaPlugin::setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  835. {
  836. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  837. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  838. uiParameterChange(parameterId, value);
  839. #ifndef BUILD_BRIDGE
  840. if (sendOsc && pData->engine->isOscControlRegistered())
  841. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(parameterId), value);
  842. #endif
  843. if (sendCallback)
  844. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, static_cast<int>(parameterId), 0, value, nullptr);
  845. #ifdef BUILD_BRIDGE
  846. // unused
  847. return; (void)sendOsc;
  848. #endif
  849. }
  850. void CarlaPlugin::setParameterValueByRealIndex(const int32_t rindex, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  851. {
  852. #ifndef BUILD_BRIDGE
  853. CARLA_SAFE_ASSERT_RETURN(rindex > PARAMETER_MAX && rindex != PARAMETER_NULL,);
  854. switch (rindex)
  855. {
  856. case PARAMETER_ACTIVE:
  857. return setActive((value > 0.0f), sendOsc, sendCallback);
  858. case PARAMETER_CTRL_CHANNEL:
  859. return setCtrlChannel(int8_t(value), sendOsc, sendCallback);
  860. case PARAMETER_DRYWET:
  861. return setDryWet(value, sendOsc, sendCallback);
  862. case PARAMETER_VOLUME:
  863. return setVolume(value, sendOsc, sendCallback);
  864. case PARAMETER_BALANCE_LEFT:
  865. return setBalanceLeft(value, sendOsc, sendCallback);
  866. case PARAMETER_BALANCE_RIGHT:
  867. return setBalanceRight(value, sendOsc, sendCallback);
  868. case PARAMETER_PANNING:
  869. return setPanning(value, sendOsc, sendCallback);
  870. }
  871. #endif
  872. CARLA_SAFE_ASSERT_RETURN(rindex >= 0,);
  873. for (uint32_t i=0; i < pData->param.count; ++i)
  874. {
  875. if (pData->param.data[i].rindex == rindex)
  876. {
  877. //if (! carla_compareFloats(getParameterValue(i), value))
  878. setParameterValue(i, value, sendGui, sendOsc, sendCallback);
  879. break;
  880. }
  881. }
  882. }
  883. void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept
  884. {
  885. #ifndef BUILD_BRIDGE
  886. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  887. #endif
  888. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  889. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  890. pData->param.data[parameterId].midiChannel = channel;
  891. #ifndef BUILD_BRIDGE
  892. if (sendOsc && pData->engine->isOscControlRegistered())
  893. pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, parameterId, channel);
  894. if (sendCallback)
  895. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED, pData->id, static_cast<int>(parameterId), channel, 0.0f, nullptr);
  896. #else
  897. // unused
  898. return; (void)sendOsc; (void)sendCallback;
  899. #endif
  900. }
  901. void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, const int16_t cc, const bool sendOsc, const bool sendCallback) noexcept
  902. {
  903. #ifndef BUILD_BRIDGE
  904. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT
  905. #endif
  906. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  907. CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc <= 0x5F,);
  908. pData->param.data[parameterId].midiCC = cc;
  909. #ifndef BUILD_BRIDGE
  910. if (sendOsc && pData->engine->isOscControlRegistered())
  911. pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, parameterId, cc);
  912. if (sendCallback)
  913. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_MIDI_CC_CHANGED, pData->id, static_cast<int>(parameterId), cc, 0.0f, nullptr);
  914. #else
  915. // unused
  916. return; (void)sendOsc; (void)sendCallback;
  917. #endif
  918. }
  919. void CarlaPlugin::setCustomData(const char* const type, const char* const key, const char* const value, const bool)
  920. {
  921. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  922. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  923. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  924. // Ignore some keys
  925. if (std::strcmp(type, CUSTOM_DATA_TYPE_STRING) == 0)
  926. {
  927. if (std::strncmp(key, "OSC:", 4) == 0 || std::strncmp(key, "CarlaAlternateFile", 18) == 0 || std::strcmp(key, "guiVisible") == 0)
  928. return;
  929. }
  930. // Check if we already have this key
  931. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next())
  932. {
  933. CustomData& cData(it.getValue());
  934. CARLA_SAFE_ASSERT_CONTINUE(cData.type != nullptr && cData.type[0] != '\0');
  935. CARLA_SAFE_ASSERT_CONTINUE(cData.key != nullptr && cData.key[0] != '\0');
  936. CARLA_SAFE_ASSERT_CONTINUE(cData.value != nullptr);
  937. if (std::strcmp(cData.key, key) == 0)
  938. {
  939. if (cData.value != nullptr)
  940. delete[] cData.value;
  941. cData.value = carla_strdup(value);
  942. return;
  943. }
  944. }
  945. // Otherwise store it
  946. CustomData newData;
  947. newData.type = carla_strdup(type);
  948. newData.key = carla_strdup(key);
  949. newData.value = carla_strdup(value);
  950. pData->custom.append(newData);
  951. }
  952. void CarlaPlugin::setChunkData(const void* const data, const std::size_t dataSize)
  953. {
  954. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  955. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  956. CARLA_SAFE_ASSERT(false); // this should never happen
  957. }
  958. void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  959. {
  960. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  961. pData->prog.current = index;
  962. #ifdef BUILD_BRIDGE
  963. const bool reallySendOsc(false);
  964. #else
  965. const bool reallySendOsc(sendOsc && pData->engine->isOscControlRegistered());
  966. if (reallySendOsc)
  967. pData->engine->oscSend_control_set_current_program(pData->id, index);
  968. #endif
  969. if (sendCallback)
  970. pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr);
  971. // Change default parameter values
  972. if (index >= 0)
  973. {
  974. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  975. uiProgramChange(static_cast<uint32_t>(index));
  976. if (getType() == PLUGIN_GIG || getType() == PLUGIN_SF2 || getType() == PLUGIN_SFZ)
  977. return;
  978. pData->updateParameterValues(this, reallySendOsc, sendCallback, true);
  979. }
  980. #ifdef BUILD_BRIDGE
  981. // unused
  982. return; (void)sendGui; (void)sendOsc;
  983. #endif
  984. }
  985. void CarlaPlugin::setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  986. {
  987. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  988. pData->midiprog.current = index;
  989. #ifdef BUILD_BRIDGE
  990. const bool reallySendOsc(false);
  991. #else
  992. const bool reallySendOsc(sendOsc && pData->engine->isOscControlRegistered());
  993. if (reallySendOsc)
  994. pData->engine->oscSend_control_set_current_midi_program(pData->id, index);
  995. #endif
  996. if (sendCallback)
  997. pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr);
  998. if (index >= 0)
  999. {
  1000. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1001. uiMidiProgramChange(static_cast<uint32_t>(index));
  1002. if (getType() == PLUGIN_GIG || getType() == PLUGIN_SF2 || getType() == PLUGIN_SFZ)
  1003. return;
  1004. pData->updateParameterValues(this, reallySendOsc, sendCallback, true);
  1005. }
  1006. #ifdef BUILD_BRIDGE
  1007. // unused
  1008. return; (void)sendGui; (void)sendOsc;
  1009. #endif
  1010. }
  1011. void CarlaPlugin::setMidiProgramById(const uint32_t bank, const uint32_t program, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept
  1012. {
  1013. for (uint32_t i=0; i < pData->midiprog.count; ++i)
  1014. {
  1015. if (pData->midiprog.data[i].bank == bank && pData->midiprog.data[i].program == program)
  1016. return setMidiProgram(static_cast<int32_t>(i), sendGui, sendOsc, sendCallback);
  1017. }
  1018. }
  1019. // -------------------------------------------------------------------
  1020. // Set ui stuff
  1021. void CarlaPlugin::idle()
  1022. {
  1023. if (! pData->enabled)
  1024. return;
  1025. if (pData->hints & PLUGIN_NEEDS_SINGLE_THREAD)
  1026. {
  1027. // Process postponed events
  1028. postRtEventsRun();
  1029. // Update parameter outputs
  1030. for (uint32_t i=0; i < pData->param.count; ++i)
  1031. {
  1032. if (pData->param.data[i].type == PARAMETER_OUTPUT)
  1033. uiParameterChange(i, getParameterValue(i));
  1034. }
  1035. }
  1036. if (pData->transientTryCounter == 0)
  1037. return;
  1038. if (++pData->transientTryCounter % 10 != 0)
  1039. return;
  1040. if (pData->transientTryCounter >= 200)
  1041. return;
  1042. carla_stdout("Trying to get window...");
  1043. CarlaString uiTitle(pData->name);
  1044. uiTitle += " (GUI)";
  1045. if (CarlaPluginUI::tryTransientWinIdMatch(pData->osc.data.target != nullptr ? pData->osc.thread.getPid() : 0, uiTitle, pData->engine->getOptions().frontendWinId, true))
  1046. pData->transientTryCounter = 0;
  1047. }
  1048. void CarlaPlugin::showCustomUI(const bool yesNo)
  1049. {
  1050. CARLA_SAFE_ASSERT(false);
  1051. return;
  1052. // unused
  1053. (void)yesNo;
  1054. }
  1055. // -------------------------------------------------------------------
  1056. // Plugin state
  1057. void CarlaPlugin::reloadPrograms(const bool)
  1058. {
  1059. }
  1060. // -------------------------------------------------------------------
  1061. // Plugin processing
  1062. void CarlaPlugin::activate() noexcept
  1063. {
  1064. CARLA_SAFE_ASSERT(! pData->active);
  1065. }
  1066. void CarlaPlugin::deactivate() noexcept
  1067. {
  1068. CARLA_SAFE_ASSERT(pData->active);
  1069. }
  1070. void CarlaPlugin::bufferSizeChanged(const uint32_t)
  1071. {
  1072. }
  1073. void CarlaPlugin::sampleRateChanged(const double)
  1074. {
  1075. }
  1076. void CarlaPlugin::offlineModeChanged(const bool)
  1077. {
  1078. }
  1079. bool CarlaPlugin::tryLock(const bool forcedOffline) noexcept
  1080. {
  1081. if (forcedOffline)
  1082. {
  1083. pData->masterMutex.lock();
  1084. return true;
  1085. }
  1086. return pData->masterMutex.tryLock();
  1087. }
  1088. void CarlaPlugin::unlock() noexcept
  1089. {
  1090. pData->masterMutex.unlock();
  1091. }
  1092. // -------------------------------------------------------------------
  1093. // Plugin buffers
  1094. void CarlaPlugin::initBuffers() const noexcept
  1095. {
  1096. pData->audioIn.initBuffers();
  1097. pData->audioOut.initBuffers();
  1098. pData->event.initBuffers();
  1099. }
  1100. void CarlaPlugin::clearBuffers() noexcept
  1101. {
  1102. pData->clearBuffers();
  1103. }
  1104. // -------------------------------------------------------------------
  1105. // OSC stuff
  1106. void CarlaPlugin::registerToOscClient() noexcept
  1107. {
  1108. #ifdef BUILD_BRIDGE
  1109. if (! pData->engine->isOscBridgeRegistered())
  1110. #else
  1111. if (! pData->engine->isOscControlRegistered())
  1112. #endif
  1113. return;
  1114. #ifndef BUILD_BRIDGE
  1115. pData->engine->oscSend_control_add_plugin_start(pData->id, pData->name);
  1116. #endif
  1117. // Base data
  1118. {
  1119. // TODO - clear buf
  1120. char bufName[STR_MAX+1] = { '\0' };
  1121. char bufLabel[STR_MAX+1] = { '\0' };
  1122. char bufMaker[STR_MAX+1] = { '\0' };
  1123. char bufCopyright[STR_MAX+1] = { '\0' };
  1124. getRealName(bufName);
  1125. getLabel(bufLabel);
  1126. getMaker(bufMaker);
  1127. getCopyright(bufCopyright);
  1128. #ifdef BUILD_BRIDGE
  1129. pData->engine->oscSend_bridge_plugin_info1(getCategory(), pData->hints, getOptionsAvailable(), pData->options, getUniqueId());
  1130. pData->engine->oscSend_bridge_plugin_info2(bufName, bufLabel, bufMaker, bufCopyright);
  1131. #else
  1132. pData->engine->oscSend_control_set_plugin_info1(pData->id, getType(), getCategory(), pData->hints, getUniqueId());
  1133. pData->engine->oscSend_control_set_plugin_info2(pData->id, bufName, bufLabel, bufMaker, bufCopyright);
  1134. #endif
  1135. }
  1136. // Base count
  1137. {
  1138. uint32_t paramIns, paramOuts;
  1139. getParameterCountInfo(paramIns, paramOuts);
  1140. #ifdef BUILD_BRIDGE
  1141. pData->engine->oscSend_bridge_audio_count(getAudioInCount(), getAudioOutCount());
  1142. pData->engine->oscSend_bridge_midi_count(getMidiInCount(), getMidiOutCount());
  1143. pData->engine->oscSend_bridge_parameter_count(paramIns, paramOuts);
  1144. #else
  1145. pData->engine->oscSend_control_set_audio_count(pData->id, getAudioInCount(), getAudioOutCount());
  1146. pData->engine->oscSend_control_set_midi_count(pData->id, getMidiInCount(), getMidiOutCount());
  1147. pData->engine->oscSend_control_set_parameter_count(pData->id, paramIns, paramOuts);
  1148. #endif
  1149. }
  1150. // Plugin Parameters
  1151. if (pData->param.count > 0 && pData->param.count < pData->engine->getOptions().maxParameters)
  1152. {
  1153. char bufName[STR_MAX+1], bufUnit[STR_MAX+1];
  1154. for (uint32_t i=0; i < pData->param.count; ++i)
  1155. {
  1156. carla_zeroChar(bufName, STR_MAX);
  1157. carla_zeroChar(bufUnit, STR_MAX);
  1158. getParameterName(i, bufName);
  1159. getParameterUnit(i, bufUnit);
  1160. const ParameterData& paramData(pData->param.data[i]);
  1161. const ParameterRanges& paramRanges(pData->param.ranges[i]);
  1162. #ifdef BUILD_BRIDGE
  1163. pData->engine->oscSend_bridge_parameter_data1(i, paramData.rindex, paramData.type, paramData.hints, paramData.midiCC);
  1164. pData->engine->oscSend_bridge_parameter_data2(i, bufName, bufUnit);
  1165. pData->engine->oscSend_bridge_parameter_ranges1(i, paramRanges.def, paramRanges.min, paramRanges.max);
  1166. pData->engine->oscSend_bridge_parameter_ranges2(i, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
  1167. pData->engine->oscSend_bridge_parameter_value(i, getParameterValue(i));
  1168. #else
  1169. pData->engine->oscSend_control_set_parameter_data(pData->id, i, paramData.type, paramData.hints, bufName, bufUnit);
  1170. pData->engine->oscSend_control_set_parameter_ranges1(pData->id, i, paramRanges.def, paramRanges.min, paramRanges.max);
  1171. pData->engine->oscSend_control_set_parameter_ranges2(pData->id, i, paramRanges.step, paramRanges.stepSmall, paramRanges.stepLarge);
  1172. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(i), getParameterValue(i));
  1173. pData->engine->oscSend_control_set_parameter_midi_cc(pData->id, i, paramData.midiCC);
  1174. pData->engine->oscSend_control_set_parameter_midi_channel(pData->id, i, paramData.midiChannel);
  1175. #endif
  1176. }
  1177. }
  1178. // Programs
  1179. if (pData->prog.count > 0)
  1180. {
  1181. #ifdef BUILD_BRIDGE
  1182. pData->engine->oscSend_bridge_program_count(pData->prog.count);
  1183. for (uint32_t i=0; i < pData->prog.count; ++i)
  1184. pData->engine->oscSend_bridge_program_name(i, pData->prog.names[i]);
  1185. pData->engine->oscSend_bridge_current_program(pData->prog.current);
  1186. #else
  1187. pData->engine->oscSend_control_set_program_count(pData->id, pData->prog.count);
  1188. for (uint32_t i=0; i < pData->prog.count; ++i)
  1189. pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
  1190. pData->engine->oscSend_control_set_current_program(pData->id, pData->prog.current);
  1191. #endif
  1192. }
  1193. // MIDI Programs
  1194. if (pData->midiprog.count > 0)
  1195. {
  1196. #ifdef BUILD_BRIDGE
  1197. pData->engine->oscSend_bridge_midi_program_count(pData->midiprog.count);
  1198. for (uint32_t i=0; i < pData->midiprog.count; ++i)
  1199. {
  1200. const MidiProgramData& mpData(pData->midiprog.data[i]);
  1201. pData->engine->oscSend_bridge_midi_program_data(i, mpData.bank, mpData.program, mpData.name);
  1202. }
  1203. pData->engine->oscSend_bridge_current_midi_program(pData->midiprog.current);
  1204. #else
  1205. pData->engine->oscSend_control_set_midi_program_count(pData->id, pData->midiprog.count);
  1206. for (uint32_t i=0; i < pData->midiprog.count; ++i)
  1207. {
  1208. const MidiProgramData& mpData(pData->midiprog.data[i]);
  1209. pData->engine->oscSend_control_set_midi_program_data(pData->id, i, mpData.bank, mpData.program, mpData.name);
  1210. }
  1211. pData->engine->oscSend_control_set_current_midi_program(pData->id, pData->midiprog.current);
  1212. #endif
  1213. }
  1214. #ifndef BUILD_BRIDGE
  1215. pData->engine->oscSend_control_add_plugin_end(pData->id);
  1216. // Internal Parameters
  1217. {
  1218. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_DRYWET, pData->postProc.dryWet);
  1219. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_VOLUME, pData->postProc.volume);
  1220. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_LEFT, pData->postProc.balanceLeft);
  1221. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_BALANCE_RIGHT, pData->postProc.balanceRight);
  1222. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_PANNING, pData->postProc.panning);
  1223. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_CTRL_CHANNEL, pData->ctrlChannel);
  1224. pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, pData->active ? 1.0f : 0.0f);
  1225. }
  1226. #endif
  1227. }
  1228. void CarlaPlugin::updateOscData(const lo_address& source, const char* const url)
  1229. {
  1230. // FIXME - remove debug prints later
  1231. carla_stdout("CarlaPlugin::updateOscData(%p, \"%s\")", source, url);
  1232. pData->osc.data.clear();
  1233. const int proto = lo_address_get_protocol(source);
  1234. {
  1235. const char* host = lo_address_get_hostname(source);
  1236. const char* port = lo_address_get_port(source);
  1237. pData->osc.data.source = lo_address_new_with_proto(proto, host, port);
  1238. carla_stdout("CarlaPlugin::updateOscData() - source: host \"%s\", port \"%s\"", host, port);
  1239. }
  1240. {
  1241. char* host = lo_url_get_hostname(url);
  1242. char* port = lo_url_get_port(url);
  1243. pData->osc.data.path = carla_strdup_free(lo_url_get_path(url));
  1244. pData->osc.data.target = lo_address_new_with_proto(proto, host, port);
  1245. carla_stdout("CarlaPlugin::updateOscData() - target: host \"%s\", port \"%s\", path \"%s\"", host, port, pData->osc.data.path);
  1246. std::free(host);
  1247. std::free(port);
  1248. }
  1249. #ifndef BUILD_BRIDGE
  1250. if (pData->hints & PLUGIN_IS_BRIDGE)
  1251. {
  1252. carla_stdout("CarlaPlugin::updateOscData() - done");
  1253. return;
  1254. }
  1255. #endif
  1256. // send possible extra data first
  1257. if (updateOscDataExtra())
  1258. pData->engine->idleOsc();
  1259. osc_send_sample_rate(pData->osc.data, static_cast<float>(pData->engine->getSampleRate()));
  1260. for (LinkedList<CustomData>::Itenerator it = pData->custom.begin(); it.valid(); it.next())
  1261. {
  1262. const CustomData& cData(it.getValue());
  1263. CARLA_SAFE_ASSERT_CONTINUE(cData.type != nullptr && cData.type[0] != '\0');
  1264. CARLA_SAFE_ASSERT_CONTINUE(cData.key != nullptr && cData.key[0] != '\0');
  1265. CARLA_SAFE_ASSERT_CONTINUE(cData.value != nullptr);
  1266. if (std::strcmp(cData.type, CUSTOM_DATA_TYPE_STRING) == 0)
  1267. osc_send_configure(pData->osc.data, cData.key, cData.value);
  1268. }
  1269. if (pData->prog.current >= 0)
  1270. osc_send_program(pData->osc.data, static_cast<uint32_t>(pData->prog.current));
  1271. if (pData->midiprog.current >= 0)
  1272. {
  1273. const MidiProgramData& curMidiProg(pData->midiprog.getCurrent());
  1274. if (getType() == PLUGIN_DSSI)
  1275. osc_send_program(pData->osc.data, curMidiProg.bank, curMidiProg.program);
  1276. else
  1277. osc_send_midi_program(pData->osc.data, curMidiProg.bank, curMidiProg.program);
  1278. }
  1279. for (uint32_t i=0; i < pData->param.count; ++i)
  1280. osc_send_control(pData->osc.data, pData->param.data[i].rindex, getParameterValue(i));
  1281. if ((pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0 && pData->engine->getOptions().frontendWinId != 0)
  1282. pData->transientTryCounter = 1;
  1283. carla_stdout("CarlaPlugin::updateOscData() - done");
  1284. }
  1285. bool CarlaPlugin::updateOscDataExtra()
  1286. {
  1287. return false;
  1288. }
  1289. void CarlaPlugin::updateOscURL()
  1290. {
  1291. const String newURL(String(pData->engine->getOscServerPathUDP()) + String("/") + String(pData->id));
  1292. osc_send_update_url(pData->osc.data, newURL.toRawUTF8());
  1293. }
  1294. bool CarlaPlugin::waitForOscGuiShow()
  1295. {
  1296. carla_stdout("CarlaPlugin::waitForOscGuiShow()");
  1297. uint i=0, oscUiTimeout = pData->engine->getOptions().uiBridgesTimeout;
  1298. // wait for UI 'update' call
  1299. for (; i < oscUiTimeout/100; ++i)
  1300. {
  1301. if (pData->osc.data.target != nullptr)
  1302. {
  1303. carla_stdout("CarlaPlugin::waitForOscGuiShow() - got response, asking UI to show itself now");
  1304. osc_send_show(pData->osc.data);
  1305. return true;
  1306. }
  1307. if (pData->osc.thread.isThreadRunning())
  1308. carla_msleep(100);
  1309. else
  1310. return false;
  1311. }
  1312. carla_stdout("CarlaPlugin::waitForOscGuiShow() - Timeout while waiting for UI to respond (waited %u msecs)", oscUiTimeout);
  1313. return false;
  1314. }
  1315. // -------------------------------------------------------------------
  1316. // MIDI events
  1317. #ifndef BUILD_BRIDGE
  1318. void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note, const uint8_t velo, const bool sendGui, const bool sendOsc, const bool sendCallback)
  1319. {
  1320. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1321. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1322. CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,);
  1323. if (! pData->active)
  1324. return;
  1325. ExternalMidiNote extNote;
  1326. extNote.channel = static_cast<int8_t>(channel);
  1327. extNote.note = note;
  1328. extNote.velo = velo;
  1329. pData->extNotes.appendNonRT(extNote);
  1330. if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1331. {
  1332. if (velo > 0)
  1333. uiNoteOn(channel, note, velo);
  1334. else
  1335. uiNoteOff(channel, note);
  1336. }
  1337. if (sendOsc && pData->engine->isOscControlRegistered())
  1338. {
  1339. if (velo > 0)
  1340. pData->engine->oscSend_control_note_on(pData->id, channel, note, velo);
  1341. else
  1342. pData->engine->oscSend_control_note_off(pData->id, channel, note);
  1343. }
  1344. if (sendCallback)
  1345. pData->engine->callback((velo > 0) ? ENGINE_CALLBACK_NOTE_ON : ENGINE_CALLBACK_NOTE_OFF, pData->id, channel, note, velo, nullptr);
  1346. }
  1347. void CarlaPlugin::sendMidiAllNotesOffToCallback()
  1348. {
  1349. if (pData->ctrlChannel < 0 || pData->ctrlChannel >= MAX_MIDI_CHANNELS)
  1350. return;
  1351. PluginPostRtEvent postEvent;
  1352. postEvent.type = kPluginPostRtEventNoteOff;
  1353. postEvent.value1 = pData->ctrlChannel;
  1354. postEvent.value2 = 0;
  1355. postEvent.value3 = 0.0f;
  1356. for (int32_t i=0; i < MAX_MIDI_NOTE; ++i)
  1357. {
  1358. postEvent.value2 = i;
  1359. pData->postRtEvents.appendRT(postEvent);
  1360. }
  1361. }
  1362. #endif
  1363. // -------------------------------------------------------------------
  1364. // Post-poned events
  1365. void CarlaPlugin::postRtEventsRun()
  1366. {
  1367. const CarlaMutexLocker sl(pData->postRtEvents.mutex);
  1368. #ifndef BUILD_BRIDGE
  1369. const bool sendOsc(pData->engine->isOscControlRegistered());
  1370. #endif
  1371. for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.data.begin(); it.valid(); it.next())
  1372. {
  1373. const PluginPostRtEvent& event(it.getValue());
  1374. switch (event.type)
  1375. {
  1376. case kPluginPostRtEventNull: {
  1377. } break;
  1378. case kPluginPostRtEventDebug: {
  1379. pData->engine->callback(ENGINE_CALLBACK_DEBUG, pData->id, event.value1, event.value2, event.value3, nullptr);
  1380. } break;
  1381. case kPluginPostRtEventParameterChange: {
  1382. // Update UI
  1383. if (event.value1 >= 0 && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1384. uiParameterChange(static_cast<uint32_t>(event.value1), event.value3);
  1385. if (event.value2 != 1)
  1386. {
  1387. #ifndef BUILD_BRIDGE
  1388. // Update OSC control client
  1389. if (sendOsc)
  1390. pData->engine->oscSend_control_set_parameter_value(pData->id, event.value1, event.value3);
  1391. #endif
  1392. // Update Host
  1393. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, event.value1, 0, event.value3, nullptr);
  1394. }
  1395. } break;
  1396. case kPluginPostRtEventProgramChange: {
  1397. // Update UI
  1398. if (event.value1 >= 0 && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1399. uiProgramChange(static_cast<uint32_t>(event.value1));
  1400. // Update param values
  1401. for (uint32_t j=0; j < pData->param.count; ++j)
  1402. {
  1403. const float paramDefault(pData->param.ranges[j].def);
  1404. const float paramValue(getParameterValue(j));
  1405. #ifndef BUILD_BRIDGE
  1406. if (sendOsc)
  1407. {
  1408. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(j), paramValue);
  1409. pData->engine->oscSend_control_set_default_value(pData->id, j, paramDefault);
  1410. }
  1411. #endif
  1412. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, static_cast<int>(j), 0, paramValue, nullptr);
  1413. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED, pData->id, static_cast<int>(j), 0, paramDefault, nullptr);
  1414. }
  1415. #ifndef BUILD_BRIDGE
  1416. // Update OSC control client
  1417. if (sendOsc)
  1418. pData->engine->oscSend_control_set_current_program(pData->id, event.value1);
  1419. #endif
  1420. // Update Host
  1421. pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED, pData->id, event.value1, 0, 0.0f, nullptr);
  1422. } break;
  1423. case kPluginPostRtEventMidiProgramChange: {
  1424. // Update UI
  1425. if (event.value1 >= 0 && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
  1426. uiMidiProgramChange(static_cast<uint32_t>(event.value1));
  1427. // Update param values
  1428. for (uint32_t j=0; j < pData->param.count; ++j)
  1429. {
  1430. const float paramDefault(pData->param.ranges[j].def);
  1431. const float paramValue(getParameterValue(j));
  1432. #ifndef BUILD_BRIDGE
  1433. if (sendOsc)
  1434. {
  1435. pData->engine->oscSend_control_set_parameter_value(pData->id, static_cast<int32_t>(j), paramValue);
  1436. pData->engine->oscSend_control_set_default_value(pData->id, j, paramDefault);
  1437. }
  1438. #endif
  1439. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, static_cast<int>(j), 0, paramValue, nullptr);
  1440. pData->engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED, pData->id, static_cast<int>(j), 0, paramDefault, nullptr);
  1441. }
  1442. #ifndef BUILD_BRIDGE
  1443. // Update OSC control client
  1444. if (sendOsc)
  1445. pData->engine->oscSend_control_set_current_midi_program(pData->id, event.value1);
  1446. #endif
  1447. // Update Host
  1448. pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, event.value1, 0, 0.0f, nullptr);
  1449. } break;
  1450. case kPluginPostRtEventNoteOn: {
  1451. CARLA_SAFE_ASSERT_BREAK(event.value1 >= 0 && event.value1 < MAX_MIDI_CHANNELS);
  1452. CARLA_SAFE_ASSERT_BREAK(event.value2 >= 0 && event.value2 < MAX_MIDI_NOTE);
  1453. CARLA_SAFE_ASSERT_BREAK(event.value3 >= 0 && event.value3 < MAX_MIDI_VALUE);
  1454. const uint8_t channel = static_cast<uint8_t>(event.value1);
  1455. const uint8_t note = static_cast<uint8_t>(event.value2);
  1456. const uint8_t velocity = uint8_t(event.value3);
  1457. // Update UI
  1458. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  1459. uiNoteOn(channel, note, velocity);
  1460. #ifndef BUILD_BRIDGE
  1461. // Update OSC control client
  1462. if (sendOsc)
  1463. pData->engine->oscSend_control_note_on(pData->id, channel, note, velocity);
  1464. #endif
  1465. // Update Host
  1466. pData->engine->callback(ENGINE_CALLBACK_NOTE_ON, pData->id, event.value1, event.value2, event.value3, nullptr);
  1467. } break;
  1468. case kPluginPostRtEventNoteOff: {
  1469. CARLA_SAFE_ASSERT_BREAK(event.value1 >= 0 && event.value1 < MAX_MIDI_CHANNELS);
  1470. CARLA_SAFE_ASSERT_BREAK(event.value2 >= 0 && event.value2 < MAX_MIDI_NOTE);
  1471. const uint8_t channel = static_cast<uint8_t>(event.value1);
  1472. const uint8_t note = static_cast<uint8_t>(event.value2);
  1473. // Update UI
  1474. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  1475. uiNoteOff(channel, note);
  1476. #ifndef BUILD_BRIDGE
  1477. // Update OSC control client
  1478. if (sendOsc)
  1479. pData->engine->oscSend_control_note_off(pData->id, channel, note);
  1480. #endif
  1481. // Update Host
  1482. pData->engine->callback(ENGINE_CALLBACK_NOTE_OFF, pData->id, event.value1, event.value2, 0.0f, nullptr);
  1483. } break;
  1484. }
  1485. }
  1486. pData->postRtEvents.data.clear();
  1487. }
  1488. // -------------------------------------------------------------------
  1489. // Post-poned UI Stuff
  1490. void CarlaPlugin::uiParameterChange(const uint32_t index, const float value) noexcept
  1491. {
  1492. CARLA_SAFE_ASSERT_RETURN(index < getParameterCount(),);
  1493. return;
  1494. // unused
  1495. (void)value;
  1496. }
  1497. void CarlaPlugin::uiProgramChange(const uint32_t index) noexcept
  1498. {
  1499. CARLA_SAFE_ASSERT_RETURN(index < getProgramCount(),);
  1500. }
  1501. void CarlaPlugin::uiMidiProgramChange(const uint32_t index) noexcept
  1502. {
  1503. CARLA_SAFE_ASSERT_RETURN(index < getMidiProgramCount(),);
  1504. }
  1505. void CarlaPlugin::uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) noexcept
  1506. {
  1507. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1508. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1509. CARLA_SAFE_ASSERT_RETURN(velo > 0 && velo < MAX_MIDI_VALUE,);
  1510. }
  1511. void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note) noexcept
  1512. {
  1513. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1514. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  1515. }
  1516. bool CarlaPlugin::canRunInRack() const noexcept
  1517. {
  1518. return (pData->extraHints & PLUGIN_EXTRA_HINT_CAN_RUN_RACK) != 0;
  1519. }
  1520. CarlaEngine* CarlaPlugin::getEngine() const noexcept
  1521. {
  1522. return pData->engine;
  1523. }
  1524. CarlaEngineClient* CarlaPlugin::getEngineClient() const noexcept
  1525. {
  1526. return pData->client;
  1527. }
  1528. CarlaEngineAudioPort* CarlaPlugin::getAudioInPort(const uint32_t index) const noexcept
  1529. {
  1530. return pData->audioIn.ports[index].port;
  1531. }
  1532. CarlaEngineAudioPort* CarlaPlugin::getAudioOutPort(const uint32_t index) const noexcept
  1533. {
  1534. return pData->audioOut.ports[index].port;
  1535. }
  1536. CarlaEngineEventPort* CarlaPlugin::getDefaultEventInPort() const noexcept
  1537. {
  1538. return pData->event.portIn;
  1539. }
  1540. CarlaEngineEventPort* CarlaPlugin::getDefaultEventOutPort() const noexcept
  1541. {
  1542. return pData->event.portOut;
  1543. }
  1544. void* CarlaPlugin::getNativeHandle() const noexcept
  1545. {
  1546. return nullptr;
  1547. }
  1548. const void* CarlaPlugin::getNativeDescriptor() const noexcept
  1549. {
  1550. return nullptr;
  1551. }
  1552. // -------------------------------------------------------------------
  1553. // Scoped Disabler
  1554. CarlaPlugin::ScopedDisabler::ScopedDisabler(CarlaPlugin* const plugin) noexcept
  1555. : fPlugin(plugin)
  1556. {
  1557. CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,);
  1558. CARLA_SAFE_ASSERT_RETURN(plugin->pData != nullptr,);
  1559. CARLA_SAFE_ASSERT_RETURN(plugin->pData->client != nullptr,);
  1560. carla_debug("CarlaPlugin::ScopedDisabler(%p)", plugin);
  1561. plugin->pData->masterMutex.lock();
  1562. if (plugin->pData->enabled)
  1563. plugin->pData->enabled = false;
  1564. if (plugin->pData->client->isActive())
  1565. plugin->pData->client->deactivate();
  1566. }
  1567. CarlaPlugin::ScopedDisabler::~ScopedDisabler() noexcept
  1568. {
  1569. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  1570. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  1571. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData->client != nullptr,);
  1572. carla_debug("CarlaPlugin::~ScopedDisabler()");
  1573. fPlugin->pData->enabled = true;
  1574. fPlugin->pData->client->activate();
  1575. fPlugin->pData->masterMutex.unlock();
  1576. }
  1577. // -------------------------------------------------------------------
  1578. // Scoped Process Locker
  1579. CarlaPlugin::ScopedSingleProcessLocker::ScopedSingleProcessLocker(CarlaPlugin* const plugin, const bool block) noexcept
  1580. : fPlugin(plugin),
  1581. fBlock(block)
  1582. {
  1583. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  1584. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  1585. carla_debug("CarlaPlugin::ScopedSingleProcessLocker(%p, %s)", plugin, bool2str(block));
  1586. if (! fBlock)
  1587. return;
  1588. plugin->pData->singleMutex.lock();
  1589. }
  1590. CarlaPlugin::ScopedSingleProcessLocker::~ScopedSingleProcessLocker() noexcept
  1591. {
  1592. CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
  1593. CARLA_SAFE_ASSERT_RETURN(fPlugin->pData != nullptr,);
  1594. carla_debug("CarlaPlugin::~ScopedSingleProcessLocker()");
  1595. if (! fBlock)
  1596. return;
  1597. #ifndef BUILD_BRIDGE
  1598. if (fPlugin->pData->singleMutex.wasTryLockCalled())
  1599. fPlugin->pData->needsReset = true;
  1600. #endif
  1601. fPlugin->pData->singleMutex.unlock();
  1602. }
  1603. // -------------------------------------------------------------------
  1604. CARLA_BACKEND_END_NAMESPACE