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