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

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