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