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

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