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

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