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.

DssiPlugin.cpp 69KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985
  1. /*
  2. * Carla DSSI Plugin
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #ifdef WANT_DSSI
  19. #include "CarlaLadspaUtils.hpp"
  20. #include "dssi/dssi.h"
  21. CARLA_BACKEND_START_NAMESPACE
  22. #if 0
  23. }
  24. #endif
  25. class DssiPlugin : public CarlaPlugin
  26. {
  27. public:
  28. DssiPlugin(CarlaEngine* const engine, const unsigned int id)
  29. : CarlaPlugin(engine, id),
  30. fHandle(nullptr),
  31. fHandle2(nullptr),
  32. fDescriptor(nullptr),
  33. fDssiDescriptor(nullptr),
  34. fAudioInBuffers(nullptr),
  35. fAudioOutBuffers(nullptr),
  36. fParamBuffers(nullptr)
  37. {
  38. carla_debug("DssiPlugin::DssiPlugin(%p, %i)", engine, id);
  39. carla_zeroStruct<snd_seq_event_t>(fMidiEvents, MAX_MIDI_EVENTS);
  40. kData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_DSSI_GUI);
  41. }
  42. ~DssiPlugin() override
  43. {
  44. carla_debug("DssiPlugin::~DssiPlugin()");
  45. // close UI
  46. if (fHints & PLUGIN_HAS_GUI)
  47. {
  48. showGui(false);
  49. // Wait a bit first, then force kill
  50. if (kData->osc.thread.isRunning() && ! kData->osc.thread.wait(kData->engine->getOptions().oscUiTimeout))
  51. {
  52. carla_stderr("DSSI GUI thread still running, forcing termination now");
  53. kData->osc.thread.terminate();
  54. }
  55. }
  56. kData->singleMutex.lock();
  57. kData->masterMutex.lock();
  58. if (kData->active)
  59. {
  60. deactivate();
  61. kData->active = false;
  62. }
  63. if (fDescriptor != nullptr)
  64. {
  65. if (fDescriptor->cleanup != nullptr)
  66. {
  67. if (fHandle != nullptr)
  68. fDescriptor->cleanup(fHandle);
  69. if (fHandle2 != nullptr)
  70. fDescriptor->cleanup(fHandle2);
  71. }
  72. fHandle = nullptr;
  73. fHandle2 = nullptr;
  74. fDescriptor = nullptr;
  75. fDssiDescriptor = nullptr;
  76. }
  77. clearBuffers();
  78. }
  79. // -------------------------------------------------------------------
  80. // Information (base)
  81. PluginType type() const override
  82. {
  83. return PLUGIN_DSSI;
  84. }
  85. PluginCategory category() override
  86. {
  87. if (fHints & PLUGIN_IS_SYNTH)
  88. return PLUGIN_CATEGORY_SYNTH;
  89. return getPluginCategoryFromName(fName);
  90. }
  91. long uniqueId() const override
  92. {
  93. CARLA_ASSERT(fDescriptor != nullptr);
  94. return fDescriptor->UniqueID;
  95. }
  96. // -------------------------------------------------------------------
  97. // Information (count)
  98. // nothing
  99. // -------------------------------------------------------------------
  100. // Information (current data)
  101. int32_t chunkData(void** const dataPtr) override
  102. {
  103. CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS);
  104. CARLA_ASSERT(fDssiDescriptor != nullptr);
  105. CARLA_ASSERT(fDssiDescriptor->get_custom_data != nullptr);
  106. CARLA_ASSERT(fHandle != nullptr);
  107. CARLA_ASSERT(fHandle2 == nullptr);
  108. CARLA_ASSERT(dataPtr != nullptr);
  109. unsigned long dataSize = 0;
  110. if (fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->get_custom_data(fHandle, dataPtr, &dataSize) != 0)
  111. return static_cast<int32_t>(dataSize);
  112. return 0;
  113. }
  114. // -------------------------------------------------------------------
  115. // Information (per-plugin data)
  116. unsigned int availableOptions() override
  117. {
  118. CARLA_ASSERT(fDssiDescriptor != nullptr);
  119. if (fDssiDescriptor == nullptr)
  120. return 0x0;
  121. #ifdef __USE_GNU
  122. const bool isDssiVst = fFilename.contains("dssi-vst", true);
  123. #else
  124. const bool isDssiVst = fFilename.contains("dssi-vst");
  125. #endif
  126. unsigned int options = 0x0;
  127. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  128. if (isDssiVst)
  129. {
  130. if (kData->engine->getOptions().useDssiVstChunks && fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr)
  131. options |= PLUGIN_OPTION_USE_CHUNKS;
  132. }
  133. else
  134. {
  135. if (kData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK)
  136. {
  137. if (fOptions & PLUGIN_OPTION_FORCE_STEREO)
  138. options |= PLUGIN_OPTION_FORCE_STEREO;
  139. else if (kData->audioIn.count <= 1 && kData->audioOut.count <= 1 && (kData->audioIn.count != 0 || kData->audioOut.count != 0))
  140. options |= PLUGIN_OPTION_FORCE_STEREO;
  141. }
  142. options |= PLUGIN_OPTION_FIXED_BUFFER;
  143. }
  144. if (fDssiDescriptor->run_synth != nullptr || fDssiDescriptor->run_multiple_synths != nullptr)
  145. {
  146. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  147. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  148. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  149. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  150. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  151. }
  152. return options;
  153. }
  154. float getParameterValue(const uint32_t parameterId) override
  155. {
  156. CARLA_ASSERT(fParamBuffers != nullptr);
  157. CARLA_ASSERT(parameterId < kData->param.count);
  158. return fParamBuffers[parameterId];
  159. }
  160. void getLabel(char* const strBuf) override
  161. {
  162. CARLA_ASSERT(fDescriptor != nullptr);
  163. if (fDescriptor->Label != nullptr)
  164. std::strncpy(strBuf, fDescriptor->Label, STR_MAX);
  165. else
  166. CarlaPlugin::getLabel(strBuf);
  167. }
  168. void getMaker(char* const strBuf) override
  169. {
  170. CARLA_ASSERT(fDescriptor != nullptr);
  171. if (fDescriptor->Maker != nullptr)
  172. std::strncpy(strBuf, fDescriptor->Maker, STR_MAX);
  173. else
  174. CarlaPlugin::getMaker(strBuf);
  175. }
  176. void getCopyright(char* const strBuf) override
  177. {
  178. CARLA_ASSERT(fDescriptor != nullptr);
  179. if (fDescriptor->Copyright != nullptr)
  180. std::strncpy(strBuf, fDescriptor->Copyright, STR_MAX);
  181. else
  182. CarlaPlugin::getCopyright(strBuf);
  183. }
  184. void getRealName(char* const strBuf) override
  185. {
  186. CARLA_ASSERT(fDescriptor != nullptr);
  187. if (fDescriptor->Name != nullptr)
  188. std::strncpy(strBuf, fDescriptor->Name, STR_MAX);
  189. else
  190. CarlaPlugin::getRealName(strBuf);
  191. }
  192. void getParameterName(const uint32_t parameterId, char* const strBuf) override
  193. {
  194. CARLA_ASSERT(fDescriptor != nullptr);
  195. CARLA_ASSERT(parameterId < kData->param.count);
  196. const int32_t rindex(kData->param.data[parameterId].rindex);
  197. if (rindex < static_cast<int32_t>(fDescriptor->PortCount))
  198. std::strncpy(strBuf, fDescriptor->PortNames[rindex], STR_MAX);
  199. else
  200. CarlaPlugin::getParameterName(parameterId, strBuf);
  201. }
  202. // -------------------------------------------------------------------
  203. // Set data (state)
  204. // nothing
  205. // -------------------------------------------------------------------
  206. // Set data (internal stuff)
  207. // nothing
  208. // -------------------------------------------------------------------
  209. // Set data (plugin-specific stuff)
  210. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  211. {
  212. CARLA_ASSERT(parameterId < kData->param.count);
  213. const float fixedValue(kData->param.fixValue(parameterId, value));
  214. fParamBuffers[parameterId] = fixedValue;
  215. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  216. }
  217. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  218. {
  219. CARLA_ASSERT(fDescriptor != nullptr);
  220. CARLA_ASSERT(fHandle != nullptr);
  221. CARLA_ASSERT(type != nullptr);
  222. CARLA_ASSERT(key != nullptr);
  223. CARLA_ASSERT(value != nullptr);
  224. carla_debug("DssiPlugin::setCustomData(%s, %s, %s, %s)", type, key, value, bool2str(sendGui));
  225. if (type == nullptr)
  226. return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui));
  227. if (std::strcmp(type, CUSTOM_DATA_STRING) != 0)
  228. return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  229. if (key == nullptr)
  230. return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui));
  231. if (value == nullptr)
  232. return carla_stderr2("DssiPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));
  233. if (fDssiDescriptor->configure != nullptr)
  234. {
  235. fDssiDescriptor->configure(fHandle, key, value);
  236. if (fHandle2)
  237. fDssiDescriptor->configure(fHandle2, key, value);
  238. }
  239. if (sendGui && kData->osc.data.target != nullptr)
  240. osc_send_configure(&kData->osc.data, key, value);
  241. if (std::strcmp(key, "reloadprograms") == 0 || std::strcmp(key, "load") == 0 || std::strncmp(key, "patches", 7) == 0)
  242. {
  243. const ScopedDisabler sd(this);
  244. reloadPrograms(false);
  245. }
  246. CarlaPlugin::setCustomData(type, key, value, sendGui);
  247. }
  248. void setChunkData(const char* const stringData) override
  249. {
  250. CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS);
  251. CARLA_ASSERT(fDssiDescriptor != nullptr);
  252. CARLA_ASSERT(fDssiDescriptor->set_custom_data != nullptr);
  253. CARLA_ASSERT(fHandle != nullptr);
  254. CARLA_ASSERT(fHandle2 == nullptr);
  255. CARLA_ASSERT(stringData != nullptr);
  256. if (fDssiDescriptor->set_custom_data == nullptr)
  257. return;
  258. QByteArray chunk(QByteArray::fromBase64(stringData));
  259. CARLA_ASSERT(chunk.size() > 0);
  260. if (chunk.size() > 0)
  261. {
  262. const ScopedSingleProcessLocker spl(this, true);
  263. fDssiDescriptor->set_custom_data(fHandle, chunk.data(), chunk.size());
  264. }
  265. }
  266. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  267. {
  268. CARLA_ASSERT(fDssiDescriptor != nullptr);
  269. CARLA_ASSERT(fHandle != nullptr);
  270. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));
  271. if (index < -1)
  272. index = -1;
  273. else if (index > static_cast<int32_t>(kData->midiprog.count))
  274. return;
  275. if (index >= 0 && fDssiDescriptor != nullptr && fDssiDescriptor->select_program != nullptr)
  276. {
  277. const uint32_t bank = kData->midiprog.data[index].bank;
  278. const uint32_t program = kData->midiprog.data[index].program;
  279. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  280. fDssiDescriptor->select_program(fHandle, bank, program);
  281. if (fHandle2 != nullptr)
  282. fDssiDescriptor->select_program(fHandle2, bank, program);
  283. }
  284. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  285. }
  286. // -------------------------------------------------------------------
  287. // Set gui stuff
  288. void showGui(const bool yesNo) override
  289. {
  290. if (yesNo)
  291. {
  292. kData->osc.thread.start();
  293. }
  294. else
  295. {
  296. if (kData->osc.data.target != nullptr)
  297. {
  298. osc_send_hide(&kData->osc.data);
  299. osc_send_quit(&kData->osc.data);
  300. kData->osc.data.free();
  301. }
  302. if (kData->osc.thread.isRunning() && ! kData->osc.thread.wait(kData->engine->getOptions().oscUiTimeout))
  303. kData->osc.thread.terminate();
  304. }
  305. }
  306. // -------------------------------------------------------------------
  307. // Plugin state
  308. void reload() override
  309. {
  310. carla_debug("DssiPlugin::reload() - start");
  311. CARLA_ASSERT(kData->engine != nullptr);
  312. CARLA_ASSERT(fDescriptor != nullptr);
  313. CARLA_ASSERT(fDssiDescriptor != nullptr);
  314. CARLA_ASSERT(fHandle != nullptr);
  315. if (kData->engine == nullptr)
  316. return;
  317. if (fDescriptor == nullptr)
  318. return;
  319. if (fDssiDescriptor == nullptr)
  320. return;
  321. if (fHandle == nullptr)
  322. return;
  323. const ProcessMode processMode(kData->engine->getProccessMode());
  324. // Safely disable plugin for reload
  325. const ScopedDisabler sd(this);
  326. if (kData->active)
  327. deactivate();
  328. clearBuffers();
  329. const float sampleRate(static_cast<float>(kData->engine->getSampleRate()));
  330. const uint32_t portCount(static_cast<uint32_t>(fDescriptor->PortCount));
  331. uint32_t aIns, aOuts, mIns, params, j;
  332. aIns = aOuts = mIns = params = 0;
  333. bool forcedStereoIn, forcedStereoOut;
  334. forcedStereoIn = forcedStereoOut = false;
  335. bool needsCtrlIn, needsCtrlOut;
  336. needsCtrlIn = needsCtrlOut = false;
  337. if (portCount > 0)
  338. {
  339. CARLA_ASSERT(fDescriptor->PortDescriptors != nullptr);
  340. CARLA_ASSERT(fDescriptor->PortRangeHints != nullptr);
  341. CARLA_ASSERT(fDescriptor->PortNames != nullptr);
  342. for (uint32_t i=0; i < portCount; ++i)
  343. {
  344. const LADSPA_PortDescriptor portType = fDescriptor->PortDescriptors[i];
  345. if (LADSPA_IS_PORT_AUDIO(portType))
  346. {
  347. if (LADSPA_IS_PORT_INPUT(portType))
  348. aIns += 1;
  349. else if (LADSPA_IS_PORT_OUTPUT(portType))
  350. aOuts += 1;
  351. }
  352. else if (LADSPA_IS_PORT_CONTROL(portType))
  353. params += 1;
  354. }
  355. }
  356. if ((fOptions & PLUGIN_OPTION_FORCE_STEREO) != 0 && (aIns == 1 || aOuts == 1))
  357. {
  358. if (fHandle2 == nullptr)
  359. fHandle2 = fDescriptor->instantiate(fDescriptor, (unsigned long)sampleRate);
  360. if (aIns == 1)
  361. {
  362. aIns = 2;
  363. forcedStereoIn = true;
  364. }
  365. if (aOuts == 1)
  366. {
  367. aOuts = 2;
  368. forcedStereoOut = true;
  369. }
  370. }
  371. if (fDssiDescriptor->run_synth != nullptr || fDssiDescriptor->run_multiple_synths != nullptr)
  372. {
  373. mIns = 1;
  374. needsCtrlIn = true;
  375. }
  376. if (aIns > 0)
  377. {
  378. kData->audioIn.createNew(aIns);
  379. fAudioInBuffers = new float*[aIns];
  380. for (uint32_t i=0; i < aIns; ++i)
  381. fAudioInBuffers[i] = nullptr;
  382. }
  383. if (aOuts > 0)
  384. {
  385. kData->audioOut.createNew(aOuts);
  386. fAudioOutBuffers = new float*[aOuts];
  387. needsCtrlIn = true;
  388. for (uint32_t i=0; i < aOuts; ++i)
  389. fAudioOutBuffers[i] = nullptr;
  390. }
  391. if (params > 0)
  392. {
  393. kData->param.createNew(params);
  394. fParamBuffers = new float[params];
  395. for (uint32_t i=0; i < params; ++i)
  396. fParamBuffers[i] = 0.0f;
  397. }
  398. const uint portNameSize(kData->engine->maxPortNameSize());
  399. CarlaString portName;
  400. for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iCtrl=0; i < portCount; ++i)
  401. {
  402. const LADSPA_PortDescriptor portType = fDescriptor->PortDescriptors[i];
  403. const LADSPA_PortRangeHint portRangeHints = fDescriptor->PortRangeHints[i];
  404. CARLA_ASSERT(fDescriptor->PortNames[i] != nullptr);
  405. if (LADSPA_IS_PORT_AUDIO(portType))
  406. {
  407. portName.clear();
  408. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  409. {
  410. portName = fName;
  411. portName += ":";
  412. }
  413. portName += fDescriptor->PortNames[i];
  414. portName.truncate(portNameSize);
  415. if (LADSPA_IS_PORT_INPUT(portType))
  416. {
  417. j = iAudioIn++;
  418. kData->audioIn.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
  419. kData->audioIn.ports[j].rindex = i;
  420. if (forcedStereoIn)
  421. {
  422. portName += "_2";
  423. kData->audioIn.ports[1].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
  424. kData->audioIn.ports[1].rindex = i;
  425. }
  426. }
  427. else if (LADSPA_IS_PORT_OUTPUT(portType))
  428. {
  429. j = iAudioOut++;
  430. kData->audioOut.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  431. kData->audioOut.ports[j].rindex = i;
  432. if (forcedStereoOut)
  433. {
  434. portName += "_2";
  435. kData->audioOut.ports[1].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  436. kData->audioOut.ports[1].rindex = i;
  437. }
  438. }
  439. else
  440. carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
  441. }
  442. else if (LADSPA_IS_PORT_CONTROL(portType))
  443. {
  444. j = iCtrl++;
  445. kData->param.data[j].index = j;
  446. kData->param.data[j].rindex = i;
  447. kData->param.data[j].hints = 0x0;
  448. kData->param.data[j].midiChannel = 0;
  449. kData->param.data[j].midiCC = -1;
  450. float min, max, def, step, stepSmall, stepLarge;
  451. // min value
  452. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  453. min = portRangeHints.LowerBound;
  454. else
  455. min = 0.0f;
  456. // max value
  457. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  458. max = portRangeHints.UpperBound;
  459. else
  460. max = 1.0f;
  461. if (min > max)
  462. max = min;
  463. else if (max < min)
  464. min = max;
  465. if (max - min == 0.0f)
  466. {
  467. carla_stderr2("WARNING - Broken plugin parameter '%s': max - min == 0.0f", fDescriptor->PortNames[i]);
  468. max = min + 0.1f;
  469. }
  470. // default value
  471. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  472. if (def < min)
  473. def = min;
  474. else if (def > max)
  475. def = max;
  476. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  477. {
  478. min *= sampleRate;
  479. max *= sampleRate;
  480. def *= sampleRate;
  481. kData->param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
  482. }
  483. if (LADSPA_IS_HINT_TOGGLED(portRangeHints.HintDescriptor))
  484. {
  485. step = max - min;
  486. stepSmall = step;
  487. stepLarge = step;
  488. kData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  489. }
  490. else if (LADSPA_IS_HINT_INTEGER(portRangeHints.HintDescriptor))
  491. {
  492. step = 1.0f;
  493. stepSmall = 1.0f;
  494. stepLarge = 10.0f;
  495. kData->param.data[j].hints |= PARAMETER_IS_INTEGER;
  496. }
  497. else
  498. {
  499. float range = max - min;
  500. step = range/100.0f;
  501. stepSmall = range/1000.0f;
  502. stepLarge = range/10.0f;
  503. }
  504. if (LADSPA_IS_PORT_INPUT(portType))
  505. {
  506. kData->param.data[j].type = PARAMETER_INPUT;
  507. kData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  508. kData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  509. needsCtrlIn = true;
  510. // MIDI CC value
  511. if (fDssiDescriptor->get_midi_controller_for_port != nullptr)
  512. {
  513. int controller = fDssiDescriptor->get_midi_controller_for_port(fHandle, i);
  514. if (DSSI_CONTROLLER_IS_SET(controller) && DSSI_IS_CC(controller))
  515. {
  516. int16_t cc = DSSI_CC_NUMBER(controller);
  517. if (! MIDI_IS_CONTROL_BANK_SELECT(cc))
  518. kData->param.data[j].midiCC = cc;
  519. }
  520. }
  521. }
  522. else if (LADSPA_IS_PORT_OUTPUT(portType))
  523. {
  524. if (std::strcmp(fDescriptor->PortNames[i], "latency") == 0 || std::strcmp(fDescriptor->PortNames[i], "_latency") == 0)
  525. {
  526. min = 0.0f;
  527. max = sampleRate;
  528. def = 0.0f;
  529. step = 1.0f;
  530. stepSmall = 1.0f;
  531. stepLarge = 1.0f;
  532. kData->param.data[j].type = PARAMETER_LATENCY;
  533. kData->param.data[j].hints = 0;
  534. }
  535. else if (std::strcmp(fDescriptor->PortNames[i], "_sample-rate") == 0)
  536. {
  537. def = sampleRate;
  538. step = 1.0f;
  539. stepSmall = 1.0f;
  540. stepLarge = 1.0f;
  541. kData->param.data[j].type = PARAMETER_SAMPLE_RATE;
  542. kData->param.data[j].hints = 0;
  543. }
  544. else
  545. {
  546. kData->param.data[j].type = PARAMETER_OUTPUT;
  547. kData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  548. kData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  549. needsCtrlOut = true;
  550. }
  551. }
  552. else
  553. {
  554. kData->param.data[j].type = PARAMETER_UNKNOWN;
  555. carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)");
  556. }
  557. // extra parameter hints
  558. if (LADSPA_IS_HINT_LOGARITHMIC(portRangeHints.HintDescriptor))
  559. kData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  560. kData->param.ranges[j].min = min;
  561. kData->param.ranges[j].max = max;
  562. kData->param.ranges[j].def = def;
  563. kData->param.ranges[j].step = step;
  564. kData->param.ranges[j].stepSmall = stepSmall;
  565. kData->param.ranges[j].stepLarge = stepLarge;
  566. // Start parameters in their default values
  567. fParamBuffers[j] = def;
  568. fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);
  569. if (fHandle2 != nullptr)
  570. fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
  571. }
  572. else
  573. {
  574. // Not Audio or Control
  575. carla_stderr2("ERROR - Got a broken Port (neither Audio or Control)");
  576. fDescriptor->connect_port(fHandle, i, nullptr);
  577. if (fHandle2 != nullptr)
  578. fDescriptor->connect_port(fHandle2, i, nullptr);
  579. }
  580. }
  581. if (needsCtrlIn)
  582. {
  583. portName.clear();
  584. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  585. {
  586. portName = fName;
  587. portName += ":";
  588. }
  589. portName += "events-in";
  590. portName.truncate(portNameSize);
  591. kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
  592. }
  593. if (needsCtrlOut)
  594. {
  595. portName.clear();
  596. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  597. {
  598. portName = fName;
  599. portName += ":";
  600. }
  601. portName += "events-out";
  602. portName.truncate(portNameSize);
  603. kData->event.portOut = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);
  604. }
  605. if (forcedStereoIn || forcedStereoOut)
  606. fOptions |= PLUGIN_OPTION_FORCE_STEREO;
  607. else
  608. fOptions &= ~PLUGIN_OPTION_FORCE_STEREO;
  609. // plugin hints
  610. fHints = 0x0;
  611. if (LADSPA_IS_HARD_RT_CAPABLE(fDescriptor->Properties))
  612. fHints |= PLUGIN_IS_RTSAFE;
  613. if (fGuiFilename.isNotEmpty())
  614. fHints |= PLUGIN_HAS_GUI;
  615. if (mIns == 1 && aIns == 0 && aOuts > 0)
  616. fHints |= PLUGIN_IS_SYNTH;
  617. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  618. fHints |= PLUGIN_CAN_DRYWET;
  619. if (aOuts > 0)
  620. fHints |= PLUGIN_CAN_VOLUME;
  621. if (aOuts >= 2 && aOuts % 2 == 0)
  622. fHints |= PLUGIN_CAN_BALANCE;
  623. // extra plugin hints
  624. kData->extraHints = 0x0;
  625. if (mIns > 0)
  626. kData->extraHints |= PLUGIN_HINT_HAS_MIDI_IN;
  627. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  628. kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK;
  629. // check latency
  630. if (fHints & PLUGIN_CAN_DRYWET)
  631. {
  632. for (uint32_t i=0; i < kData->param.count; ++i)
  633. {
  634. if (kData->param.data[i].type != PARAMETER_LATENCY)
  635. continue;
  636. // we need to pre-run the plugin so it can update its latency control-port
  637. float tmpIn[aIns][2];
  638. float tmpOut[aOuts][2];
  639. for (j=0; j < aIns; ++j)
  640. {
  641. tmpIn[j][0] = 0.0f;
  642. tmpIn[j][1] = 0.0f;
  643. fDescriptor->connect_port(fHandle, kData->audioIn.ports[j].rindex, tmpIn[j]);
  644. }
  645. for (j=0; j < aOuts; ++j)
  646. {
  647. tmpOut[j][0] = 0.0f;
  648. tmpOut[j][1] = 0.0f;
  649. fDescriptor->connect_port(fHandle, kData->audioOut.ports[j].rindex, tmpOut[j]);
  650. }
  651. if (fDescriptor->activate != nullptr)
  652. fDescriptor->activate(fHandle);
  653. fDescriptor->run(fHandle, 2);
  654. if (fDescriptor->deactivate != nullptr)
  655. fDescriptor->deactivate(fHandle);
  656. const uint32_t latency = (uint32_t)fParamBuffers[i];
  657. if (kData->latency != latency)
  658. {
  659. kData->latency = latency;
  660. kData->client->setLatency(latency);
  661. kData->recreateLatencyBuffers();
  662. }
  663. break;
  664. }
  665. }
  666. bufferSizeChanged(kData->engine->getBufferSize());
  667. reloadPrograms(true);
  668. if (kData->active)
  669. activate();
  670. carla_debug("DssiPlugin::reload() - end");
  671. }
  672. void reloadPrograms(const bool init) override
  673. {
  674. carla_debug("DssiPlugin::reloadPrograms(%s)", bool2str(init));
  675. uint32_t i, oldCount = kData->midiprog.count;
  676. const int32_t current = kData->midiprog.current;
  677. // Delete old programs
  678. kData->midiprog.clear();
  679. // Query new programs
  680. uint32_t count = 0;
  681. if (fDssiDescriptor->get_program != nullptr && fDssiDescriptor->select_program != nullptr)
  682. {
  683. while (fDssiDescriptor->get_program(fHandle, count))
  684. count++;
  685. }
  686. if (count > 0)
  687. {
  688. kData->midiprog.createNew(count);
  689. // Update data
  690. for (i=0; i < count; ++i)
  691. {
  692. const DSSI_Program_Descriptor* const pdesc(fDssiDescriptor->get_program(fHandle, i));
  693. CARLA_ASSERT(pdesc != nullptr);
  694. CARLA_ASSERT(pdesc->Name != nullptr);
  695. kData->midiprog.data[i].bank = static_cast<uint32_t>(pdesc->Bank);
  696. kData->midiprog.data[i].program = static_cast<uint32_t>(pdesc->Program);
  697. kData->midiprog.data[i].name = carla_strdup(pdesc->Name);
  698. }
  699. }
  700. #ifndef BUILD_BRIDGE
  701. // Update OSC Names
  702. if (kData->engine->isOscControlRegistered())
  703. {
  704. kData->engine->osc_send_control_set_midi_program_count(fId, count);
  705. for (i=0; i < count; ++i)
  706. kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name);
  707. }
  708. #endif
  709. if (init)
  710. {
  711. if (count > 0)
  712. setMidiProgram(0, false, false, false);
  713. }
  714. else
  715. {
  716. // Check if current program is invalid
  717. bool programChanged = false;
  718. if (count == oldCount+1)
  719. {
  720. // one midi program added, probably created by user
  721. kData->midiprog.current = oldCount;
  722. programChanged = true;
  723. }
  724. else if (current < 0 && count > 0)
  725. {
  726. // programs exist now, but not before
  727. kData->midiprog.current = 0;
  728. programChanged = true;
  729. }
  730. else if (current >= 0 && count == 0)
  731. {
  732. // programs existed before, but not anymore
  733. kData->midiprog.current = -1;
  734. programChanged = true;
  735. }
  736. else if (current >= static_cast<int32_t>(count))
  737. {
  738. // current midi program > count
  739. kData->midiprog.current = 0;
  740. programChanged = true;
  741. }
  742. else
  743. {
  744. // no change
  745. kData->midiprog.current = current;
  746. }
  747. if (programChanged)
  748. setMidiProgram(kData->midiprog.current, true, true, true);
  749. kData->engine->callback(CALLBACK_RELOAD_PROGRAMS, fId, 0, 0, 0.0f, nullptr);
  750. }
  751. }
  752. // -------------------------------------------------------------------
  753. // Plugin processing
  754. void activate() override
  755. {
  756. CARLA_ASSERT(fDescriptor != nullptr);
  757. CARLA_ASSERT(fHandle != nullptr);
  758. if (fDescriptor->activate != nullptr)
  759. {
  760. fDescriptor->activate(fHandle);
  761. if (fHandle2 != nullptr)
  762. fDescriptor->activate(fHandle2);
  763. }
  764. }
  765. void deactivate() override
  766. {
  767. CARLA_ASSERT(fDescriptor != nullptr);
  768. CARLA_ASSERT(fHandle != nullptr);
  769. if (fDescriptor->deactivate != nullptr)
  770. {
  771. fDescriptor->deactivate(fHandle);
  772. if (fHandle2 != nullptr)
  773. fDescriptor->deactivate(fHandle2);
  774. }
  775. }
  776. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  777. {
  778. uint32_t i, k;
  779. // --------------------------------------------------------------------------------------------------------
  780. // Check if active
  781. if (! kData->active)
  782. {
  783. // disable any output sound
  784. for (i=0; i < kData->audioOut.count; ++i)
  785. carla_zeroFloat(outBuffer[i], frames);
  786. return;
  787. }
  788. unsigned long midiEventCount = 0;
  789. // --------------------------------------------------------------------------------------------------------
  790. // Check if needs reset
  791. if (kData->needsReset)
  792. {
  793. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  794. {
  795. for (unsigned char j=0, l=MAX_MIDI_CHANNELS; j < MAX_MIDI_CHANNELS; ++j)
  796. {
  797. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[j]);
  798. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[j+l]);
  799. fMidiEvents[j].type = SND_SEQ_EVENT_CONTROLLER;
  800. fMidiEvents[j].data.control.channel = j;
  801. fMidiEvents[j].data.control.param = MIDI_CONTROL_ALL_NOTES_OFF;
  802. fMidiEvents[j+l].type = SND_SEQ_EVENT_CONTROLLER;
  803. fMidiEvents[j+l].data.control.channel = j;
  804. fMidiEvents[j+l].data.control.param = MIDI_CONTROL_ALL_SOUND_OFF;
  805. }
  806. midiEventCount = MAX_MIDI_CHANNELS*2;
  807. }
  808. else if (kData->ctrlChannel >= 0 && kData->ctrlChannel < MAX_MIDI_CHANNELS)
  809. {
  810. for (unsigned char j=0; j < MAX_MIDI_NOTE; ++j)
  811. {
  812. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[j]);
  813. fMidiEvents[j].type = SND_SEQ_EVENT_NOTEOFF;
  814. fMidiEvents[j].data.note.channel = kData->ctrlChannel;
  815. fMidiEvents[j].data.note.note = j;
  816. }
  817. midiEventCount = MAX_MIDI_NOTE;
  818. }
  819. if (kData->latency > 0)
  820. {
  821. for (i=0; i < kData->audioIn.count; ++i)
  822. carla_zeroFloat(kData->latencyBuffers[i], kData->latency);
  823. }
  824. kData->needsReset = false;
  825. }
  826. // --------------------------------------------------------------------------------------------------------
  827. // Event Input and Processing
  828. if (kData->event.portIn != nullptr)
  829. {
  830. // ----------------------------------------------------------------------------------------------------
  831. // MIDI Input (External)
  832. if (kData->extNotes.mutex.tryLock())
  833. {
  834. while (midiEventCount < MAX_MIDI_EVENTS && ! kData->extNotes.data.isEmpty())
  835. {
  836. const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));
  837. CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  838. fMidiEvents[midiEventCount].type = (note.velo > 0) ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF;
  839. fMidiEvents[midiEventCount].data.note.channel = note.channel;
  840. fMidiEvents[midiEventCount].data.note.note = note.note;
  841. fMidiEvents[midiEventCount].data.note.velocity = note.velo;
  842. midiEventCount += 1;
  843. }
  844. kData->extNotes.mutex.unlock();
  845. } // End of MIDI Input (External)
  846. // ----------------------------------------------------------------------------------------------------
  847. // Event Input (System)
  848. bool allNotesOffSent = false;
  849. bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
  850. uint32_t time, nEvents = kData->event.portIn->getEventCount();
  851. uint32_t startTime = 0;
  852. uint32_t timeOffset = 0;
  853. uint32_t nextBankId = 0;
  854. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  855. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  856. for (i=0; i < nEvents; ++i)
  857. {
  858. const EngineEvent& event(kData->event.portIn->getEvent(i));
  859. time = event.time;
  860. if (time >= frames)
  861. continue;
  862. CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset);
  863. if (time > timeOffset && sampleAccurate)
  864. {
  865. if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset, midiEventCount))
  866. {
  867. startTime = 0;
  868. timeOffset = time;
  869. midiEventCount = 0;
  870. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  871. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  872. else
  873. nextBankId = 0;
  874. }
  875. else
  876. startTime += timeOffset;
  877. }
  878. // Control change
  879. switch (event.type)
  880. {
  881. case kEngineEventTypeNull:
  882. break;
  883. case kEngineEventTypeControl:
  884. {
  885. const EngineControlEvent& ctrlEvent = event.ctrl;
  886. switch (ctrlEvent.type)
  887. {
  888. case kEngineControlEventTypeNull:
  889. break;
  890. case kEngineControlEventTypeParameter:
  891. {
  892. #ifndef BUILD_BRIDGE
  893. // Control backend stuff
  894. if (event.channel == kData->ctrlChannel)
  895. {
  896. float value;
  897. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
  898. {
  899. value = ctrlEvent.value;
  900. setDryWet(value, false, false);
  901. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  902. continue;
  903. }
  904. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
  905. {
  906. value = ctrlEvent.value*127.0f/100.0f;
  907. setVolume(value, false, false);
  908. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  909. continue;
  910. }
  911. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
  912. {
  913. float left, right;
  914. value = ctrlEvent.value/0.5f - 1.0f;
  915. if (value < 0.0f)
  916. {
  917. left = -1.0f;
  918. right = (value*2.0f)+1.0f;
  919. }
  920. else if (value > 0.0f)
  921. {
  922. left = (value*2.0f)-1.0f;
  923. right = 1.0f;
  924. }
  925. else
  926. {
  927. left = -1.0f;
  928. right = 1.0f;
  929. }
  930. setBalanceLeft(left, false, false);
  931. setBalanceRight(right, false, false);
  932. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  933. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  934. continue;
  935. }
  936. }
  937. #endif
  938. // Control plugin parameters
  939. for (k=0; k < kData->param.count; ++k)
  940. {
  941. if (kData->param.data[k].midiChannel != event.channel)
  942. continue;
  943. if (kData->param.data[k].midiCC != ctrlEvent.param)
  944. continue;
  945. if (kData->param.data[k].type != PARAMETER_INPUT)
  946. continue;
  947. if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  948. continue;
  949. float value;
  950. if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  951. {
  952. value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
  953. }
  954. else
  955. {
  956. value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);
  957. if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
  958. value = std::rint(value);
  959. }
  960. setParameterValue(k, value, false, false, false);
  961. postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  962. }
  963. break;
  964. }
  965. case kEngineControlEventTypeMidiBank:
  966. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  967. nextBankId = ctrlEvent.param;
  968. break;
  969. case kEngineControlEventTypeMidiProgram:
  970. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  971. {
  972. const uint32_t nextProgramId = ctrlEvent.param;
  973. for (k=0; k < kData->midiprog.count; ++k)
  974. {
  975. if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
  976. {
  977. setMidiProgram(k, false, false, false);
  978. postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
  979. break;
  980. }
  981. }
  982. }
  983. break;
  984. case kEngineControlEventTypeAllSoundOff:
  985. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  986. {
  987. if (midiEventCount >= MAX_MIDI_EVENTS)
  988. continue;
  989. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]);
  990. fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time;
  991. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CONTROLLER;
  992. fMidiEvents[midiEventCount].data.control.channel = event.channel;
  993. fMidiEvents[midiEventCount].data.control.param = MIDI_CONTROL_ALL_SOUND_OFF;
  994. midiEventCount += 1;
  995. }
  996. break;
  997. case kEngineControlEventTypeAllNotesOff:
  998. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  999. {
  1000. if (event.channel == kData->ctrlChannel && ! allNotesOffSent)
  1001. {
  1002. allNotesOffSent = true;
  1003. sendMidiAllNotesOffToCallback();
  1004. }
  1005. if (midiEventCount >= MAX_MIDI_EVENTS)
  1006. continue;
  1007. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]);
  1008. fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time;
  1009. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CONTROLLER;
  1010. fMidiEvents[midiEventCount].data.control.channel = event.channel;
  1011. fMidiEvents[midiEventCount].data.control.param = MIDI_CONTROL_ALL_NOTES_OFF;
  1012. midiEventCount += 1;
  1013. }
  1014. break;
  1015. }
  1016. break;
  1017. }
  1018. case kEngineEventTypeMidi:
  1019. {
  1020. if (midiEventCount >= MAX_MIDI_EVENTS)
  1021. continue;
  1022. const EngineMidiEvent& midiEvent(event.midi);
  1023. uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
  1024. uint8_t channel = event.channel;
  1025. // Fix bad note-off (per DSSI spec)
  1026. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  1027. status -= 0x10;
  1028. carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]);
  1029. fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time;
  1030. if (MIDI_IS_STATUS_NOTE_OFF(status))
  1031. {
  1032. const uint8_t note = midiEvent.data[1];
  1033. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_NOTEOFF;
  1034. fMidiEvents[midiEventCount].data.note.channel = channel;
  1035. fMidiEvents[midiEventCount].data.note.note = note;
  1036. postponeRtEvent(kPluginPostRtEventNoteOff, channel, note, 0.0f);
  1037. }
  1038. else if (MIDI_IS_STATUS_NOTE_ON(status))
  1039. {
  1040. const uint8_t note = midiEvent.data[1];
  1041. const uint8_t velo = midiEvent.data[2];
  1042. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_NOTEON;
  1043. fMidiEvents[midiEventCount].data.note.channel = channel;
  1044. fMidiEvents[midiEventCount].data.note.note = note;
  1045. fMidiEvents[midiEventCount].data.note.velocity = velo;
  1046. postponeRtEvent(kPluginPostRtEventNoteOn, channel, note, velo);
  1047. }
  1048. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) != 0)
  1049. {
  1050. const uint8_t note = midiEvent.data[1];
  1051. const uint8_t pressure = midiEvent.data[2];
  1052. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_KEYPRESS;
  1053. fMidiEvents[midiEventCount].data.note.channel = channel;
  1054. fMidiEvents[midiEventCount].data.note.note = note;
  1055. fMidiEvents[midiEventCount].data.note.velocity = pressure;
  1056. }
  1057. else if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fOptions & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0)
  1058. {
  1059. const uint8_t control = midiEvent.data[1];
  1060. const uint8_t value = midiEvent.data[2];
  1061. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CONTROLLER;
  1062. fMidiEvents[midiEventCount].data.control.channel = channel;
  1063. fMidiEvents[midiEventCount].data.control.param = control;
  1064. fMidiEvents[midiEventCount].data.control.value = value;
  1065. }
  1066. else if (MIDI_IS_STATUS_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) != 0)
  1067. {
  1068. const uint8_t pressure = midiEvent.data[1];
  1069. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CHANPRESS;
  1070. fMidiEvents[midiEventCount].data.control.channel = channel;
  1071. fMidiEvents[midiEventCount].data.control.value = pressure;
  1072. }
  1073. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (fOptions & PLUGIN_OPTION_SEND_PITCHBEND) != 0)
  1074. {
  1075. const uint8_t lsb = midiEvent.data[1];
  1076. const uint8_t msb = midiEvent.data[2];
  1077. fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_PITCHBEND;
  1078. fMidiEvents[midiEventCount].data.control.channel = channel;
  1079. fMidiEvents[midiEventCount].data.control.value = ((msb << 7) | lsb) - 8192;
  1080. }
  1081. else
  1082. continue;
  1083. midiEventCount += 1;
  1084. break;
  1085. }
  1086. }
  1087. }
  1088. kData->postRtEvents.trySplice();
  1089. if (frames > timeOffset)
  1090. processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset, midiEventCount);
  1091. } // End of Event Input and Processing
  1092. // --------------------------------------------------------------------------------------------------------
  1093. // Plugin processing (no events)
  1094. else
  1095. {
  1096. processSingle(inBuffer, outBuffer, frames, 0, midiEventCount);
  1097. } // End of Plugin processing (no events)
  1098. CARLA_PROCESS_CONTINUE_CHECK;
  1099. // --------------------------------------------------------------------------------------------------------
  1100. // Control Output
  1101. if (kData->event.portOut != nullptr)
  1102. {
  1103. uint8_t channel;
  1104. uint16_t param;
  1105. float value;
  1106. for (k=0; k < kData->param.count; ++k)
  1107. {
  1108. if (kData->param.data[k].type != PARAMETER_OUTPUT)
  1109. continue;
  1110. kData->param.ranges[k].fixValue(fParamBuffers[k]);
  1111. if (kData->param.data[k].midiCC > 0)
  1112. {
  1113. channel = kData->param.data[k].midiChannel;
  1114. param = static_cast<uint16_t>(kData->param.data[k].midiCC);
  1115. value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
  1116. kData->event.portOut->writeControlEvent(0, channel, kEngineControlEventTypeParameter, param, value);
  1117. }
  1118. }
  1119. } // End of Control Output
  1120. }
  1121. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const unsigned long midiEventCount)
  1122. {
  1123. CARLA_ASSERT(frames > 0);
  1124. if (frames == 0)
  1125. return false;
  1126. if (kData->audioIn.count > 0)
  1127. {
  1128. CARLA_ASSERT(inBuffer != nullptr);
  1129. if (inBuffer == nullptr)
  1130. return false;
  1131. }
  1132. if (kData->audioOut.count > 0)
  1133. {
  1134. CARLA_ASSERT(outBuffer != nullptr);
  1135. if (outBuffer == nullptr)
  1136. return false;
  1137. }
  1138. uint32_t i, k;
  1139. // --------------------------------------------------------------------------------------------------------
  1140. // Try lock, silence otherwise
  1141. if (kData->engine->isOffline())
  1142. {
  1143. kData->singleMutex.lock();
  1144. }
  1145. else if (! kData->singleMutex.tryLock())
  1146. {
  1147. for (i=0; i < kData->audioOut.count; ++i)
  1148. {
  1149. for (k=0; k < frames; ++k)
  1150. outBuffer[i][k+timeOffset] = 0.0f;
  1151. }
  1152. return false;
  1153. }
  1154. // --------------------------------------------------------------------------------------------------------
  1155. // Reset audio buffers
  1156. for (i=0; i < kData->audioIn.count; ++i)
  1157. carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames);
  1158. for (i=0; i < kData->audioOut.count; ++i)
  1159. carla_zeroFloat(fAudioOutBuffers[i], frames);
  1160. // --------------------------------------------------------------------------------------------------------
  1161. // Run plugin
  1162. if (fDssiDescriptor->run_synth != nullptr)
  1163. {
  1164. fDssiDescriptor->run_synth(fHandle, frames, fMidiEvents, midiEventCount);
  1165. if (fHandle2 != nullptr)
  1166. fDssiDescriptor->run_synth(fHandle2, frames, fMidiEvents, midiEventCount);
  1167. }
  1168. else if (fDssiDescriptor->run_multiple_synths != nullptr)
  1169. {
  1170. unsigned long instances = (fHandle2 != nullptr) ? 2 : 1;
  1171. LADSPA_Handle handlePtr[2] = { fHandle, fHandle2 };
  1172. snd_seq_event_t* midiEventsPtr[2] = { fMidiEvents, fMidiEvents };
  1173. unsigned long midiEventCountPtr[2] = { midiEventCount, midiEventCount };
  1174. fDssiDescriptor->run_multiple_synths(instances, handlePtr, frames, midiEventsPtr, midiEventCountPtr);
  1175. }
  1176. else
  1177. {
  1178. fDescriptor->run(fHandle, frames);
  1179. if (fHandle2 != nullptr)
  1180. fDescriptor->run(fHandle2, frames);
  1181. }
  1182. #ifndef BUILD_BRIDGE
  1183. // --------------------------------------------------------------------------------------------------------
  1184. // Post-processing (dry/wet, volume and balance)
  1185. {
  1186. const bool doDryWet = (fHints & PLUGIN_CAN_DRYWET) != 0 && kData->postProc.dryWet != 1.0f;
  1187. const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) != 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);
  1188. bool isPair;
  1189. float bufValue, oldBufLeft[doBalance ? frames : 1];
  1190. for (i=0; i < kData->audioOut.count; ++i)
  1191. {
  1192. // Dry/Wet
  1193. if (doDryWet)
  1194. {
  1195. for (k=0; k < frames; ++k)
  1196. {
  1197. // TODO
  1198. //if (k < kData->latency && kData->latency < frames)
  1199. // bufValue = (kData->audioIn.count == 1) ? kData->latencyBuffers[0][k] : kData->latencyBuffers[i][k];
  1200. //else
  1201. // bufValue = (kData->audioIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency];
  1202. bufValue = fAudioInBuffers[(kData->audioIn.count == 1) ? 0 : i][k];
  1203. fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
  1204. }
  1205. }
  1206. // Balance
  1207. if (doBalance)
  1208. {
  1209. isPair = (i % 2 == 0);
  1210. if (isPair)
  1211. {
  1212. CARLA_ASSERT(i+1 < kData->audioOut.count);
  1213. carla_copyFloat(oldBufLeft, fAudioOutBuffers[i], frames);
  1214. }
  1215. float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
  1216. float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;
  1217. for (k=0; k < frames; ++k)
  1218. {
  1219. if (isPair)
  1220. {
  1221. // left
  1222. fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  1223. fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
  1224. }
  1225. else
  1226. {
  1227. // right
  1228. fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
  1229. fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
  1230. }
  1231. }
  1232. }
  1233. // Volume (and buffer copy)
  1234. {
  1235. for (k=0; k < frames; ++k)
  1236. outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * kData->postProc.volume;
  1237. }
  1238. }
  1239. #if 0
  1240. // Latency, save values for next callback, TODO
  1241. if (kData->latency > 0 && kData->latency < frames)
  1242. {
  1243. for (i=0; i < kData->audioIn.count; ++i)
  1244. carla_copyFloat(kData->latencyBuffers[i], inBuffer[i] + (frames - kData->latency), kData->latency);
  1245. }
  1246. #endif
  1247. } // End of Post-processing
  1248. #else
  1249. for (i=0; i < kData->audioOut.count; ++i)
  1250. {
  1251. for (k=0; k < frames; ++k)
  1252. outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k];
  1253. }
  1254. #endif
  1255. // --------------------------------------------------------------------------------------------------------
  1256. kData->singleMutex.unlock();
  1257. return true;
  1258. }
  1259. void bufferSizeChanged(const uint32_t newBufferSize) override
  1260. {
  1261. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  1262. carla_debug("DssiPlugin::bufferSizeChanged(%i) - start", newBufferSize);
  1263. for (uint32_t i=0; i < kData->audioIn.count; ++i)
  1264. {
  1265. if (fAudioInBuffers[i] != nullptr)
  1266. delete[] fAudioInBuffers[i];
  1267. fAudioInBuffers[i] = new float[newBufferSize];
  1268. }
  1269. for (uint32_t i=0; i < kData->audioOut.count; ++i)
  1270. {
  1271. if (fAudioOutBuffers[i] != nullptr)
  1272. delete[] fAudioOutBuffers[i];
  1273. fAudioOutBuffers[i] = new float[newBufferSize];
  1274. }
  1275. if (fHandle2 == nullptr)
  1276. {
  1277. for (uint32_t i=0; i < kData->audioIn.count; ++i)
  1278. {
  1279. CARLA_ASSERT(fAudioInBuffers[i] != nullptr);
  1280. fDescriptor->connect_port(fHandle, kData->audioIn.ports[i].rindex, fAudioInBuffers[i]);
  1281. }
  1282. for (uint32_t i=0; i < kData->audioOut.count; ++i)
  1283. {
  1284. CARLA_ASSERT(fAudioOutBuffers[i] != nullptr);
  1285. fDescriptor->connect_port(fHandle, kData->audioOut.ports[i].rindex, fAudioOutBuffers[i]);
  1286. }
  1287. }
  1288. else
  1289. {
  1290. if (kData->audioIn.count > 0)
  1291. {
  1292. CARLA_ASSERT(kData->audioIn.count == 2);
  1293. CARLA_ASSERT(fAudioInBuffers[0] != nullptr);
  1294. CARLA_ASSERT(fAudioInBuffers[1] != nullptr);
  1295. fDescriptor->connect_port(fHandle, kData->audioIn.ports[0].rindex, fAudioInBuffers[0]);
  1296. fDescriptor->connect_port(fHandle2, kData->audioIn.ports[1].rindex, fAudioInBuffers[1]);
  1297. }
  1298. if (kData->audioOut.count > 0)
  1299. {
  1300. CARLA_ASSERT(kData->audioOut.count == 2);
  1301. CARLA_ASSERT(fAudioOutBuffers[0] != nullptr);
  1302. CARLA_ASSERT(fAudioOutBuffers[1] != nullptr);
  1303. fDescriptor->connect_port(fHandle, kData->audioOut.ports[0].rindex, fAudioOutBuffers[0]);
  1304. fDescriptor->connect_port(fHandle2, kData->audioOut.ports[1].rindex, fAudioOutBuffers[1]);
  1305. }
  1306. }
  1307. carla_debug("DssiPlugin::bufferSizeChanged(%i) - start", newBufferSize);
  1308. }
  1309. void sampleRateChanged(const double newSampleRate) override
  1310. {
  1311. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  1312. carla_debug("DssiPlugin::sampleRateChanged(%g) - start", newSampleRate);
  1313. // TODO
  1314. (void)newSampleRate;
  1315. carla_debug("DssiPlugin::sampleRateChanged(%g) - end", newSampleRate);
  1316. }
  1317. // -------------------------------------------------------------------
  1318. // Plugin buffers
  1319. void clearBuffers() override
  1320. {
  1321. carla_debug("DssiPlugin::clearBuffers() - start");
  1322. if (fAudioInBuffers != nullptr)
  1323. {
  1324. for (uint32_t i=0; i < kData->audioIn.count; ++i)
  1325. {
  1326. if (fAudioInBuffers[i] != nullptr)
  1327. {
  1328. delete[] fAudioInBuffers[i];
  1329. fAudioInBuffers[i] = nullptr;
  1330. }
  1331. }
  1332. delete[] fAudioInBuffers;
  1333. fAudioInBuffers = nullptr;
  1334. }
  1335. if (fAudioOutBuffers != nullptr)
  1336. {
  1337. for (uint32_t i=0; i < kData->audioOut.count; ++i)
  1338. {
  1339. if (fAudioOutBuffers[i] != nullptr)
  1340. {
  1341. delete[] fAudioOutBuffers[i];
  1342. fAudioOutBuffers[i] = nullptr;
  1343. }
  1344. }
  1345. delete[] fAudioOutBuffers;
  1346. fAudioOutBuffers = nullptr;
  1347. }
  1348. if (fParamBuffers != nullptr)
  1349. {
  1350. delete[] fParamBuffers;
  1351. fParamBuffers = nullptr;
  1352. }
  1353. CarlaPlugin::clearBuffers();
  1354. carla_debug("DssiPlugin::clearBuffers() - end");
  1355. }
  1356. // -------------------------------------------------------------------
  1357. // Post-poned UI Stuff
  1358. void uiParameterChange(const uint32_t index, const float value) override
  1359. {
  1360. CARLA_ASSERT(index < kData->param.count);
  1361. if (index >= kData->param.count)
  1362. return;
  1363. if (kData->osc.data.target == nullptr)
  1364. return;
  1365. osc_send_control(&kData->osc.data, kData->param.data[index].rindex, value);
  1366. }
  1367. void uiMidiProgramChange(const uint32_t index) override
  1368. {
  1369. CARLA_ASSERT(index < kData->midiprog.count);
  1370. if (index >= kData->midiprog.count)
  1371. return;
  1372. if (kData->osc.data.target == nullptr)
  1373. return;
  1374. osc_send_program(&kData->osc.data, kData->midiprog.data[index].bank, kData->midiprog.data[index].program);
  1375. }
  1376. void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) override
  1377. {
  1378. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1379. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1380. CARLA_ASSERT(velo > 0 && velo < MAX_MIDI_VALUE);
  1381. if (channel >= MAX_MIDI_CHANNELS)
  1382. return;
  1383. if (note >= MAX_MIDI_NOTE)
  1384. return;
  1385. if (velo >= MAX_MIDI_VALUE)
  1386. return;
  1387. if (kData->osc.data.target == nullptr)
  1388. return;
  1389. #if 0
  1390. uint8_t midiData[4] = { 0 };
  1391. midiData[1] = MIDI_STATUS_NOTE_ON + channel;
  1392. midiData[2] = note;
  1393. midiData[3] = velo;
  1394. osc_send_midi(&kData->osc.data, midiData);
  1395. #endif
  1396. }
  1397. void uiNoteOff(const uint8_t channel, const uint8_t note) override
  1398. {
  1399. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1400. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1401. if (channel >= MAX_MIDI_CHANNELS)
  1402. return;
  1403. if (note >= MAX_MIDI_NOTE)
  1404. return;
  1405. if (kData->osc.data.target == nullptr)
  1406. return;
  1407. #if 0
  1408. uint8_t midiData[4] = { 0 };
  1409. midiData[1] = MIDI_STATUS_NOTE_OFF + channel;
  1410. midiData[2] = note;
  1411. osc_send_midi(&kData->osc.data, midiData);
  1412. #endif
  1413. }
  1414. // -------------------------------------------------------------------
  1415. const void* getExtraStuff() override
  1416. {
  1417. return fGuiFilename.isNotEmpty() ? (const char*)fGuiFilename : nullptr;
  1418. }
  1419. bool init(const char* const filename, const char* const name, const char* const label, const char* const guiFilename)
  1420. {
  1421. CARLA_ASSERT(kData->engine != nullptr);
  1422. CARLA_ASSERT(kData->client == nullptr);
  1423. CARLA_ASSERT(filename != nullptr);
  1424. CARLA_ASSERT(label != nullptr);
  1425. // ---------------------------------------------------------------
  1426. // first checks
  1427. if (kData->engine == nullptr)
  1428. {
  1429. return false;
  1430. }
  1431. if (kData->client != nullptr)
  1432. {
  1433. kData->engine->setLastError("Plugin client is already registered");
  1434. return false;
  1435. }
  1436. if (filename == nullptr)
  1437. {
  1438. kData->engine->setLastError("null filename");
  1439. return false;
  1440. }
  1441. if (label == nullptr)
  1442. {
  1443. kData->engine->setLastError("null label");
  1444. return false;
  1445. }
  1446. // ---------------------------------------------------------------
  1447. // open DLL
  1448. if (! kData->libOpen(filename))
  1449. {
  1450. kData->engine->setLastError(kData->libError(filename));
  1451. return false;
  1452. }
  1453. // ---------------------------------------------------------------
  1454. // get DLL main entry
  1455. const DSSI_Descriptor_Function descFn = (DSSI_Descriptor_Function)kData->libSymbol("dssi_descriptor");
  1456. if (descFn == nullptr)
  1457. {
  1458. kData->engine->setLastError("Could not find the DSSI Descriptor in the plugin library");
  1459. return false;
  1460. }
  1461. // ---------------------------------------------------------------
  1462. // get descriptor that matches label
  1463. unsigned long i = 0;
  1464. while ((fDssiDescriptor = descFn(i++)) != nullptr)
  1465. {
  1466. fDescriptor = fDssiDescriptor->LADSPA_Plugin;
  1467. if (fDescriptor != nullptr && fDescriptor->Label != nullptr && std::strcmp(fDescriptor->Label, label) == 0)
  1468. break;
  1469. }
  1470. if (fDescriptor == nullptr || fDssiDescriptor == nullptr)
  1471. {
  1472. kData->engine->setLastError("Could not find the requested plugin label in the plugin library");
  1473. return false;
  1474. }
  1475. // ---------------------------------------------------------------
  1476. // get info
  1477. if (name != nullptr)
  1478. fName = kData->engine->getUniquePluginName(name);
  1479. else if (fDescriptor->Name != nullptr)
  1480. fName = kData->engine->getUniquePluginName(fDescriptor->Name);
  1481. else
  1482. fName = kData->engine->getUniquePluginName(fDescriptor->Label);
  1483. fFilename = filename;
  1484. // ---------------------------------------------------------------
  1485. // register client
  1486. kData->client = kData->engine->addClient(this);
  1487. if (kData->client == nullptr || ! kData->client->isOk())
  1488. {
  1489. kData->engine->setLastError("Failed to register plugin client");
  1490. return false;
  1491. }
  1492. // ---------------------------------------------------------------
  1493. // initialize plugin
  1494. fHandle = fDescriptor->instantiate(fDescriptor, (unsigned long)kData->engine->getSampleRate());
  1495. if (fHandle == nullptr)
  1496. {
  1497. kData->engine->setLastError("Plugin failed to initialize");
  1498. return false;
  1499. }
  1500. // ---------------------------------------------------------------
  1501. // gui stuff
  1502. if (guiFilename != nullptr)
  1503. {
  1504. fGuiFilename = guiFilename;
  1505. kData->osc.thread.setOscData(guiFilename, fDescriptor->Label);
  1506. }
  1507. // ---------------------------------------------------------------
  1508. // load plugin settings
  1509. {
  1510. #ifdef __USE_GNU
  1511. const bool isDssiVst = fFilename.contains("dssi-vst", true);
  1512. #else
  1513. const bool isDssiVst = fFilename.contains("dssi-vst");
  1514. #endif
  1515. // set default options
  1516. fOptions = 0x0;
  1517. fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1518. if (kData->engine->getOptions().forceStereo)
  1519. fOptions |= PLUGIN_OPTION_FORCE_STEREO;
  1520. if (isDssiVst)
  1521. {
  1522. fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
  1523. if (kData->engine->getOptions().useDssiVstChunks && fDssiDescriptor->get_custom_data != nullptr && fDssiDescriptor->set_custom_data != nullptr)
  1524. fOptions |= PLUGIN_OPTION_USE_CHUNKS;
  1525. }
  1526. if (fDssiDescriptor->run_synth != nullptr || fDssiDescriptor->run_multiple_synths != nullptr)
  1527. {
  1528. fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1529. fOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  1530. fOptions |= PLUGIN_OPTION_SEND_PITCHBEND;
  1531. fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1532. if (fDssiDescriptor->run_synth == nullptr)
  1533. carla_stderr2("Plugin can ONLY use run_multiple_synths!");
  1534. }
  1535. // load settings
  1536. kData->idStr = "DSSI/";
  1537. kData->idStr += std::strrchr(filename, OS_SEP)+1;
  1538. kData->idStr += "/";
  1539. kData->idStr += label;
  1540. fOptions = kData->loadSettings(fOptions, availableOptions());
  1541. // ignore settings, we need this anyway
  1542. if (isDssiVst)
  1543. fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
  1544. }
  1545. return true;
  1546. }
  1547. private:
  1548. LADSPA_Handle fHandle;
  1549. LADSPA_Handle fHandle2;
  1550. const LADSPA_Descriptor* fDescriptor;
  1551. const DSSI_Descriptor* fDssiDescriptor;
  1552. CarlaString fGuiFilename;
  1553. float** fAudioInBuffers;
  1554. float** fAudioOutBuffers;
  1555. float* fParamBuffers;
  1556. snd_seq_event_t fMidiEvents[MAX_MIDI_EVENTS];
  1557. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DssiPlugin)
  1558. };
  1559. CARLA_BACKEND_END_NAMESPACE
  1560. #else // WANT_DSSI
  1561. # warning Building without DSSI support
  1562. #endif
  1563. CARLA_BACKEND_START_NAMESPACE
  1564. CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init, const char* const guiFilename)
  1565. {
  1566. carla_debug("CarlaPlugin::newDSSI({%p, \"%s\", \"%s\", \"%s\"}, \"%s\")", init.engine, init.filename, init.name, init.label, guiFilename);
  1567. #ifdef WANT_DSSI
  1568. DssiPlugin* const plugin(new DssiPlugin(init.engine, init.id));
  1569. if (! plugin->init(init.filename, init.name, init.label, guiFilename))
  1570. {
  1571. delete plugin;
  1572. return nullptr;
  1573. }
  1574. plugin->reload();
  1575. if (init.engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK && ! CarlaPluginProtectedData::canRunInRack(plugin))
  1576. {
  1577. init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo DSSI plugins, sorry!");
  1578. delete plugin;
  1579. return nullptr;
  1580. }
  1581. return plugin;
  1582. #else
  1583. init.engine->setLastError("DSSI support not available");
  1584. return nullptr;
  1585. #endif
  1586. }
  1587. CARLA_BACKEND_END_NAMESPACE