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