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

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