Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CarlaPlugin.cpp 65KB

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