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

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