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

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