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