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.

CarlaPluginVST2.cpp 82KB

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
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
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
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
10 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
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
10 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
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
10 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
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
10 years ago
11 years ago
10 years ago
9 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
9 years ago
9 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439
  1. /*
  2. * Carla VST Plugin
  3. * Copyright (C) 2011-2016 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. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  20. # define USE_JUCE_FOR_VST
  21. #endif
  22. #ifndef USE_JUCE_FOR_VST
  23. #include "CarlaVstUtils.hpp"
  24. #include "CarlaMathUtils.hpp"
  25. #include "CarlaPluginUI.hpp"
  26. #include "juce_core/juce_core.h"
  27. #include <pthread.h>
  28. #undef VST_FORCE_DEPRECATED
  29. #define VST_FORCE_DEPRECATED 0
  30. #undef kEffectMagic
  31. #define kEffectMagic (CCONST( 'V', 's', 't', 'P' ))
  32. using juce::File;
  33. CARLA_BACKEND_START_NAMESPACE
  34. // -----------------------------------------------------
  35. const uint PLUGIN_CAN_PROCESS_REPLACING = 0x1000;
  36. const uint PLUGIN_HAS_COCKOS_EXTENSIONS = 0x2000;
  37. const uint PLUGIN_USES_OLD_VSTSDK = 0x4000;
  38. const uint PLUGIN_WANTS_MIDI_INPUT = 0x8000;
  39. static const int32_t kVstMidiEventSize = static_cast<int32_t>(sizeof(VstMidiEvent));
  40. // -----------------------------------------------------
  41. class CarlaPluginVST2 : public CarlaPlugin,
  42. private CarlaPluginUI::CloseCallback
  43. {
  44. public:
  45. CarlaPluginVST2(CarlaEngine* const engine, const uint id)
  46. : CarlaPlugin(engine, id),
  47. fUnique1(1),
  48. fEffect(nullptr),
  49. fMidiEventCount(0),
  50. fTimeInfo(),
  51. fNeedIdle(false),
  52. fLastChunk(nullptr),
  53. fIsProcessing(false),
  54. fMainThread(pthread_self()),
  55. #ifdef PTW32_DLLPORT
  56. fProcThread({nullptr, 0}),
  57. #else
  58. fProcThread(0),
  59. #endif
  60. fEvents(),
  61. fUI(),
  62. fUnique2(2)
  63. {
  64. carla_debug("CarlaPluginVST2::CarlaPluginVST2(%p, %i)", engine, id);
  65. carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
  66. carla_zeroStruct(fTimeInfo);
  67. for (ushort i=0; i < kPluginMaxMidiEvents*2; ++i)
  68. fEvents.data[i] = (VstEvent*)&fMidiEvents[i];
  69. // make plugin valid
  70. srand(id);
  71. fUnique1 = fUnique2 = rand();
  72. }
  73. ~CarlaPluginVST2() override
  74. {
  75. carla_debug("CarlaPluginVST2::~CarlaPluginVST2()");
  76. // close UI
  77. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  78. {
  79. showCustomUI(false);
  80. }
  81. pData->singleMutex.lock();
  82. pData->masterMutex.lock();
  83. if (pData->client != nullptr && pData->client->isActive())
  84. pData->client->deactivate();
  85. CARLA_ASSERT(! fIsProcessing);
  86. if (pData->active)
  87. {
  88. deactivate();
  89. pData->active = false;
  90. }
  91. if (fEffect != nullptr)
  92. {
  93. dispatcher(effClose, 0, 0, nullptr, 0.0f);
  94. fEffect = nullptr;
  95. }
  96. // make plugin invalid
  97. fUnique2 += 1;
  98. if (fLastChunk != nullptr)
  99. {
  100. std::free(fLastChunk);
  101. fLastChunk = nullptr;
  102. }
  103. clearBuffers();
  104. }
  105. // -------------------------------------------------------------------
  106. // Information (base)
  107. PluginType getType() const noexcept override
  108. {
  109. return PLUGIN_VST2;
  110. }
  111. PluginCategory getCategory() const noexcept override
  112. {
  113. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, CarlaPlugin::getCategory());
  114. const intptr_t category(dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f));
  115. switch (category)
  116. {
  117. case kPlugCategSynth:
  118. return PLUGIN_CATEGORY_SYNTH;
  119. case kPlugCategAnalysis:
  120. return PLUGIN_CATEGORY_UTILITY;
  121. case kPlugCategMastering:
  122. return PLUGIN_CATEGORY_DYNAMICS;
  123. case kPlugCategRoomFx:
  124. return PLUGIN_CATEGORY_DELAY;
  125. case kPlugCategRestoration:
  126. return PLUGIN_CATEGORY_UTILITY;
  127. case kPlugCategGenerator:
  128. return PLUGIN_CATEGORY_SYNTH;
  129. }
  130. if (fEffect->flags & effFlagsIsSynth)
  131. return PLUGIN_CATEGORY_SYNTH;
  132. return CarlaPlugin::getCategory();
  133. }
  134. int64_t getUniqueId() const noexcept override
  135. {
  136. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  137. return static_cast<int64_t>(fEffect->uniqueID);
  138. }
  139. // -------------------------------------------------------------------
  140. // Information (count)
  141. // nothing
  142. // -------------------------------------------------------------------
  143. // Information (current data)
  144. std::size_t getChunkData(void** const dataPtr) noexcept override
  145. {
  146. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS, 0);
  147. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  148. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  149. *dataPtr = nullptr;
  150. try {
  151. const intptr_t ret = dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr, 0.0f);
  152. CARLA_SAFE_ASSERT_RETURN(ret >= 0, 0);
  153. return static_cast<std::size_t>(ret);
  154. } CARLA_SAFE_EXCEPTION_RETURN("CarlaPluginVST2::getChunkData", 0);
  155. }
  156. // -------------------------------------------------------------------
  157. // Information (per-plugin data)
  158. uint getOptionsAvailable() const noexcept override
  159. {
  160. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  161. uint options = 0x0;
  162. // can't disable fixed buffers if using latency or MIDI output
  163. if (pData->latency.frames == 0 && ! hasMidiOutput())
  164. options |= PLUGIN_OPTION_FIXED_BUFFERS;
  165. if (fEffect->numPrograms > 1)
  166. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  167. if (fEffect->flags & effFlagsProgramChunks)
  168. options |= PLUGIN_OPTION_USE_CHUNKS;
  169. if (hasMidiInput())
  170. {
  171. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  172. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  173. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  174. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  175. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  176. }
  177. return options;
  178. }
  179. float getParameterValue(const uint32_t parameterId) const noexcept override
  180. {
  181. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0.0f);
  182. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  183. return fEffect->getParameter(fEffect, static_cast<int32_t>(parameterId));
  184. }
  185. void getLabel(char* const strBuf) const noexcept override
  186. {
  187. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  188. strBuf[0] = '\0';
  189. dispatcher(effGetProductString, 0, 0, strBuf, 0.0f);
  190. }
  191. void getMaker(char* const strBuf) const noexcept override
  192. {
  193. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  194. strBuf[0] = '\0';
  195. dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
  196. }
  197. void getCopyright(char* const strBuf) const noexcept override
  198. {
  199. getMaker(strBuf);
  200. }
  201. void getRealName(char* const strBuf) const noexcept override
  202. {
  203. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  204. strBuf[0] = '\0';
  205. dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
  206. }
  207. void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  208. {
  209. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  210. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  211. strBuf[0] = '\0';
  212. VstParameterProperties prop;
  213. carla_zeroStruct(prop);
  214. if (dispatcher(effGetParameterProperties, static_cast<int32_t>(parameterId), 0, &prop, 0) == 1 && prop.label[0] != '\0')
  215. {
  216. std::strncpy(strBuf, prop.label, 64);
  217. strBuf[64] = '\0';
  218. return;
  219. }
  220. strBuf[0] = '\0';
  221. dispatcher(effGetParamName, static_cast<int32_t>(parameterId), 0, strBuf, 0.0f);
  222. }
  223. void getParameterText(const uint32_t parameterId, char* const strBuf) const noexcept override
  224. {
  225. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  226. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  227. strBuf[0] = '\0';
  228. dispatcher(effGetParamDisplay, static_cast<int32_t>(parameterId), 0, strBuf, 0.0f);
  229. if (strBuf[0] == '\0')
  230. std::snprintf(strBuf, STR_MAX, "%f", getParameterValue(parameterId));
  231. }
  232. void getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  233. {
  234. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  235. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  236. strBuf[0] = '\0';
  237. dispatcher(effGetParamLabel, static_cast<int32_t>(parameterId), 0, strBuf, 0.0f);
  238. }
  239. // -------------------------------------------------------------------
  240. // Set data (state)
  241. // nothing
  242. // -------------------------------------------------------------------
  243. // Set data (internal stuff)
  244. void setName(const char* const newName) override
  245. {
  246. CarlaPlugin::setName(newName);
  247. if (fUI.window != nullptr)
  248. {
  249. CarlaString guiTitle(pData->name);
  250. guiTitle += " (GUI)";
  251. fUI.window->setTitle(guiTitle.buffer());
  252. }
  253. }
  254. // -------------------------------------------------------------------
  255. // Set data (plugin-specific stuff)
  256. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  257. {
  258. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  259. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  260. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  261. fEffect->setParameter(fEffect, static_cast<int32_t>(parameterId), fixedValue);
  262. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  263. }
  264. void setChunkData(const void* const data, const std::size_t dataSize) override
  265. {
  266. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS,);
  267. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  268. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  269. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  270. if (fLastChunk != nullptr)
  271. std::free(fLastChunk);
  272. fLastChunk = std::malloc(dataSize);
  273. CARLA_SAFE_ASSERT_RETURN(fLastChunk != nullptr,);
  274. std::memcpy(fLastChunk, data, dataSize);
  275. {
  276. const ScopedSingleProcessLocker spl(this, true);
  277. dispatcher(effSetChunk, 0 /* bank */, static_cast<intptr_t>(dataSize), fLastChunk, 0.0f);
  278. }
  279. // simulate an updateDisplay callback
  280. handleAudioMasterCallback(audioMasterUpdateDisplay, 0, 0, nullptr, 0.0f);
  281. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  282. const bool sendOsc(pData->engine->isOscControlRegistered());
  283. #else
  284. const bool sendOsc(false);
  285. #endif
  286. pData->updateParameterValues(this, sendOsc, true, false);
  287. }
  288. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  289. {
  290. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  291. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  292. if (index >= 0)
  293. {
  294. try {
  295. dispatcher(effBeginSetProgram, 0, 0, nullptr, 0.0f);
  296. } CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",);
  297. {
  298. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  299. try {
  300. dispatcher(effSetProgram, 0, index, nullptr, 0.0f);
  301. } CARLA_SAFE_EXCEPTION("effSetProgram");
  302. }
  303. try {
  304. dispatcher(effEndSetProgram, 0, 0, nullptr, 0.0f);
  305. } CARLA_SAFE_EXCEPTION("effEndSetProgram");
  306. }
  307. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback);
  308. }
  309. // -------------------------------------------------------------------
  310. // Set ui stuff
  311. void showCustomUI(const bool yesNo) override
  312. {
  313. if (fUI.isVisible == yesNo)
  314. return;
  315. if (yesNo)
  316. {
  317. CarlaString uiTitle(pData->name);
  318. uiTitle += " (GUI)";
  319. intptr_t value = 0;
  320. void* vstPtr = nullptr;
  321. ERect* vstRect = nullptr;
  322. if (fUI.window == nullptr)
  323. {
  324. const char* msg = nullptr;
  325. const uintptr_t frontendWinId(pData->engine->getOptions().frontendWinId);
  326. #if defined(CARLA_OS_LINUX)
  327. # ifdef HAVE_X11
  328. fUI.window = CarlaPluginUI::newX11(this, frontendWinId, false);
  329. # else
  330. msg = "UI is only for systems with X11";
  331. (void)frontendWinId; // unused
  332. # endif
  333. #elif defined(CARLA_OS_MAC)
  334. # ifdef __LP64__
  335. fUI.window = CarlaPluginUI::newCocoa(this, frontendWinId);
  336. # endif
  337. #elif defined(CARLA_OS_WIN)
  338. fUI.window = CarlaPluginUI::newWindows(this, frontendWinId);
  339. #else
  340. msg = "Unknown UI type";
  341. #endif
  342. if (fUI.window == nullptr)
  343. return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, msg);
  344. fUI.window->setTitle(uiTitle.buffer());
  345. }
  346. vstPtr = fUI.window->getPtr();
  347. dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f);
  348. #ifdef HAVE_X11
  349. value = (intptr_t)fUI.window->getDisplay();
  350. #endif
  351. if (dispatcher(effEditOpen, 0, value, vstPtr, 0.0f) != 0)
  352. {
  353. if (vstRect == nullptr || vstRect->right - vstRect->left < 2)
  354. dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f);
  355. if (vstRect != nullptr)
  356. {
  357. const int width(vstRect->right - vstRect->left);
  358. const int height(vstRect->bottom - vstRect->top);
  359. CARLA_SAFE_ASSERT_INT2(width > 1 && height > 1, width, height);
  360. if (width > 1 && height > 1)
  361. fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), false);
  362. }
  363. fUI.window->show();
  364. fUI.isVisible = true;
  365. }
  366. else
  367. {
  368. delete fUI.window;
  369. fUI.window = nullptr;
  370. return pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, "Plugin refused to open its own UI");
  371. }
  372. }
  373. else
  374. {
  375. fUI.isVisible = false;
  376. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  377. fUI.window->hide();
  378. dispatcher(effEditClose, 0, 0, nullptr, 0.0f);
  379. }
  380. }
  381. void idle() override
  382. {
  383. if (fNeedIdle)
  384. dispatcher(effIdle, 0, 0, nullptr, 0.0f);
  385. CarlaPlugin::idle();
  386. }
  387. void uiIdle() override
  388. {
  389. if (fUI.window != nullptr)
  390. {
  391. fUI.window->idle();
  392. if (fUI.isVisible)
  393. dispatcher(effEditIdle, 0, 0, nullptr, 0.0f);
  394. }
  395. CarlaPlugin::uiIdle();
  396. }
  397. // -------------------------------------------------------------------
  398. // Plugin state
  399. void reload() override
  400. {
  401. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  402. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  403. carla_debug("CarlaPluginVST2::reload() - start");
  404. const EngineProcessMode processMode(pData->engine->getProccessMode());
  405. // Safely disable plugin for reload
  406. const ScopedDisabler sd(this);
  407. if (pData->active)
  408. deactivate();
  409. clearBuffers();
  410. uint32_t aIns, aOuts, mIns, mOuts, params;
  411. bool needsCtrlIn, needsCtrlOut;
  412. needsCtrlIn = needsCtrlOut = false;
  413. aIns = (fEffect->numInputs > 0) ? static_cast<uint32_t>(fEffect->numInputs) : 0;
  414. aOuts = (fEffect->numOutputs > 0) ? static_cast<uint32_t>(fEffect->numOutputs) : 0;
  415. params = (fEffect->numParams > 0) ? static_cast<uint32_t>(fEffect->numParams) : 0;
  416. if (hasMidiInput())
  417. {
  418. mIns = 1;
  419. needsCtrlIn = true;
  420. }
  421. else
  422. mIns = 0;
  423. if (hasMidiOutput())
  424. {
  425. mOuts = 1;
  426. needsCtrlOut = true;
  427. }
  428. else
  429. mOuts = 0;
  430. if (aIns > 0)
  431. {
  432. pData->audioIn.createNew(aIns);
  433. }
  434. if (aOuts > 0)
  435. {
  436. pData->audioOut.createNew(aOuts);
  437. needsCtrlIn = true;
  438. }
  439. if (params > 0)
  440. {
  441. pData->param.createNew(params, false);
  442. needsCtrlIn = true;
  443. }
  444. const uint portNameSize(pData->engine->getMaxPortNameSize());
  445. CarlaString portName;
  446. // Audio Ins
  447. for (uint32_t j=0; j < aIns; ++j)
  448. {
  449. portName.clear();
  450. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  451. {
  452. portName = pData->name;
  453. portName += ":";
  454. }
  455. if (aIns > 1)
  456. {
  457. portName += "input_";
  458. portName += CarlaString(j+1);
  459. }
  460. else
  461. portName += "input";
  462. portName.truncate(portNameSize);
  463. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  464. pData->audioIn.ports[j].rindex = j;
  465. }
  466. // Audio Outs
  467. for (uint32_t j=0; j < aOuts; ++j)
  468. {
  469. portName.clear();
  470. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  471. {
  472. portName = pData->name;
  473. portName += ":";
  474. }
  475. if (aOuts > 1)
  476. {
  477. portName += "output_";
  478. portName += CarlaString(j+1);
  479. }
  480. else
  481. portName += "output";
  482. portName.truncate(portNameSize);
  483. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  484. pData->audioOut.ports[j].rindex = j;
  485. }
  486. for (uint32_t j=0; j < params; ++j)
  487. {
  488. pData->param.data[j].type = PARAMETER_INPUT;
  489. pData->param.data[j].index = static_cast<int32_t>(j);
  490. pData->param.data[j].rindex = static_cast<int32_t>(j);
  491. float min, max, def, step, stepSmall, stepLarge;
  492. VstParameterProperties prop;
  493. carla_zeroStruct(prop);
  494. if (pData->hints & PLUGIN_HAS_COCKOS_EXTENSIONS)
  495. {
  496. double vrange[2] = { 0.0, 1.0 };
  497. bool isInteger = false;
  498. if (static_cast<uintptr_t>(dispatcher(effVendorSpecific, static_cast<int32_t>(0xdeadbef0), static_cast<int32_t>(j), vrange, 0.0f)) >= 0xbeef)
  499. {
  500. min = static_cast<float>(vrange[0]);
  501. max = static_cast<float>(vrange[1]);
  502. if (min > max)
  503. {
  504. carla_stderr2("WARNING - Broken plugin parameter min > max (with cockos extensions)");
  505. min = max - 0.1f;
  506. }
  507. else if (carla_isEqual(min, max))
  508. {
  509. carla_stderr2("WARNING - Broken plugin parameter min == max (with cockos extensions)");
  510. max = min + 0.1f;
  511. }
  512. // only use values as integer if we have a proper range
  513. if (max - min >= 1.0f)
  514. isInteger = dispatcher(effVendorSpecific, kVstParameterUsesIntStep, static_cast<int32_t>(j), nullptr, 0.0f) >= 0xbeef;
  515. }
  516. else
  517. {
  518. min = 0.0f;
  519. max = 1.0f;
  520. }
  521. if (isInteger)
  522. {
  523. step = 1.0f;
  524. stepSmall = 1.0f;
  525. stepLarge = 10.0f;
  526. }
  527. else
  528. {
  529. const float range = max - min;
  530. step = range/100.0f;
  531. stepSmall = range/1000.0f;
  532. stepLarge = range/10.0f;
  533. }
  534. }
  535. else if (dispatcher(effGetParameterProperties, static_cast<int32_t>(j), 0, &prop, 0) == 1)
  536. {
  537. if (prop.flags & kVstParameterUsesIntegerMinMax)
  538. {
  539. min = static_cast<float>(prop.minInteger);
  540. max = static_cast<float>(prop.maxInteger);
  541. if (min > max)
  542. {
  543. carla_stderr2("WARNING - Broken plugin parameter min > max");
  544. min = max - 0.1f;
  545. }
  546. else if (carla_isEqual(min, max))
  547. {
  548. carla_stderr2("WARNING - Broken plugin parameter min == max");
  549. max = min + 0.1f;
  550. }
  551. }
  552. else
  553. {
  554. min = 0.0f;
  555. max = 1.0f;
  556. }
  557. if (prop.flags & kVstParameterIsSwitch)
  558. {
  559. step = max - min;
  560. stepSmall = step;
  561. stepLarge = step;
  562. pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  563. }
  564. else if (prop.flags & kVstParameterUsesIntStep)
  565. {
  566. step = static_cast<float>(prop.stepInteger);
  567. stepSmall = static_cast<float>(prop.stepInteger)/10.0f;
  568. stepLarge = static_cast<float>(prop.largeStepInteger);
  569. pData->param.data[j].hints |= PARAMETER_IS_INTEGER;
  570. }
  571. else if (prop.flags & kVstParameterUsesFloatStep)
  572. {
  573. step = prop.stepFloat;
  574. stepSmall = prop.smallStepFloat;
  575. stepLarge = prop.largeStepFloat;
  576. }
  577. else
  578. {
  579. const float range = max - min;
  580. step = range/100.0f;
  581. stepSmall = range/1000.0f;
  582. stepLarge = range/10.0f;
  583. }
  584. if (prop.flags & kVstParameterCanRamp)
  585. pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  586. }
  587. else
  588. {
  589. min = 0.0f;
  590. max = 1.0f;
  591. step = 0.001f;
  592. stepSmall = 0.0001f;
  593. stepLarge = 0.1f;
  594. }
  595. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  596. #ifndef BUILD_BRIDGE
  597. pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  598. #endif
  599. if ((pData->hints & PLUGIN_USES_OLD_VSTSDK) != 0 || dispatcher(effCanBeAutomated, static_cast<int32_t>(j), 0, nullptr, 0.0f) == 1)
  600. pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  601. // no such thing as VST default parameters
  602. def = fEffect->getParameter(fEffect, static_cast<int32_t>(j));
  603. if (def < min)
  604. def = min;
  605. else if (def > max)
  606. def = max;
  607. pData->param.ranges[j].min = min;
  608. pData->param.ranges[j].max = max;
  609. pData->param.ranges[j].def = def;
  610. pData->param.ranges[j].step = step;
  611. pData->param.ranges[j].stepSmall = stepSmall;
  612. pData->param.ranges[j].stepLarge = stepLarge;
  613. }
  614. if (needsCtrlIn)
  615. {
  616. portName.clear();
  617. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  618. {
  619. portName = pData->name;
  620. portName += ":";
  621. }
  622. portName += "events-in";
  623. portName.truncate(portNameSize);
  624. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  625. }
  626. if (needsCtrlOut)
  627. {
  628. portName.clear();
  629. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  630. {
  631. portName = pData->name;
  632. portName += ":";
  633. }
  634. portName += "events-out";
  635. portName.truncate(portNameSize);
  636. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  637. }
  638. // plugin hints
  639. const intptr_t vstCategory = dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f);
  640. pData->hints = 0x0;
  641. if (vstCategory == kPlugCategSynth || vstCategory == kPlugCategGenerator)
  642. pData->hints |= PLUGIN_IS_SYNTH;
  643. if (fEffect->flags & effFlagsHasEditor)
  644. {
  645. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  646. pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
  647. }
  648. if (dispatcher(effGetVstVersion, 0, 0, nullptr, 0.0f) < kVstVersion)
  649. pData->hints |= PLUGIN_USES_OLD_VSTSDK;
  650. if ((fEffect->flags & effFlagsCanReplacing) != 0 && fEffect->processReplacing != fEffect->process)
  651. pData->hints |= PLUGIN_CAN_PROCESS_REPLACING;
  652. if (static_cast<uintptr_t>(dispatcher(effCanDo, 0, 0, const_cast<char*>("hasCockosExtensions"), 0.0f)) == 0xbeef0000)
  653. pData->hints |= PLUGIN_HAS_COCKOS_EXTENSIONS;
  654. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  655. pData->hints |= PLUGIN_CAN_DRYWET;
  656. if (aOuts > 0)
  657. pData->hints |= PLUGIN_CAN_VOLUME;
  658. if (aOuts >= 2 && aOuts % 2 == 0)
  659. pData->hints |= PLUGIN_CAN_BALANCE;
  660. // extra plugin hints
  661. pData->extraHints = 0x0;
  662. if (mIns > 0)
  663. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  664. if (mOuts > 0)
  665. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  666. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
  667. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  668. // dummy pre-start to get latency and wantEvents() on old plugins
  669. {
  670. activate();
  671. deactivate();
  672. }
  673. // check initial latency
  674. #ifdef VESTIGE_HEADER
  675. char* const empty3Ptr = &fEffect->empty3[0];
  676. int32_t initialDelay = *(int32_t*)empty3Ptr;
  677. const uint32_t latency = (initialDelay > 0) ? static_cast<uint32_t>(initialDelay) : 0;
  678. #else
  679. const uint32_t latency = (fEffect->initialDelay > 0) ? static_cast<uint32_t>(fEffect->initialDelay) : 0;
  680. #endif
  681. if (latency != 0)
  682. {
  683. pData->client->setLatency(latency);
  684. #ifndef BUILD_BRIDGE
  685. pData->latency.recreateBuffers(std::max(aIns, aOuts), latency);
  686. #endif
  687. }
  688. //bufferSizeChanged(pData->engine->getBufferSize());
  689. reloadPrograms(true);
  690. if (pData->active)
  691. activate();
  692. carla_debug("CarlaPluginVST2::reload() - end");
  693. }
  694. void reloadPrograms(const bool doInit) override
  695. {
  696. carla_debug("CarlaPluginVST2::reloadPrograms(%s)", bool2str(doInit));
  697. const uint32_t oldCount = pData->prog.count;
  698. const int32_t current = pData->prog.current;
  699. // Delete old programs
  700. pData->prog.clear();
  701. // Query new programs
  702. uint32_t newCount = (fEffect->numPrograms > 0) ? static_cast<uint32_t>(fEffect->numPrograms) : 0;
  703. if (newCount > 0)
  704. {
  705. pData->prog.createNew(newCount);
  706. // Update names
  707. for (int32_t i=0; i < fEffect->numPrograms; ++i)
  708. {
  709. char strBuf[STR_MAX+1] = { '\0' };
  710. if (dispatcher(effGetProgramNameIndexed, i, 0, strBuf, 0.0f) != 1)
  711. {
  712. // program will be [re-]changed later
  713. dispatcher(effSetProgram, 0, i, nullptr, 0.0f);
  714. dispatcher(effGetProgramName, 0, 0, strBuf, 0.0f);
  715. }
  716. pData->prog.names[i] = carla_strdup(strBuf);
  717. }
  718. }
  719. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  720. // Update OSC Names
  721. if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
  722. {
  723. pData->engine->oscSend_control_set_program_count(pData->id, newCount);
  724. for (uint32_t i=0; i < newCount; ++i)
  725. pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]);
  726. }
  727. #endif
  728. if (doInit)
  729. {
  730. if (newCount > 0)
  731. setProgram(0, false, false, false);
  732. }
  733. else
  734. {
  735. // Check if current program is invalid
  736. bool programChanged = false;
  737. if (newCount == oldCount+1)
  738. {
  739. // one program added, probably created by user
  740. pData->prog.current = static_cast<int32_t>(oldCount);
  741. programChanged = true;
  742. }
  743. else if (current < 0 && newCount > 0)
  744. {
  745. // programs exist now, but not before
  746. pData->prog.current = 0;
  747. programChanged = true;
  748. }
  749. else if (current >= 0 && newCount == 0)
  750. {
  751. // programs existed before, but not anymore
  752. pData->prog.current = -1;
  753. programChanged = true;
  754. }
  755. else if (current >= static_cast<int32_t>(newCount))
  756. {
  757. // current program > count
  758. pData->prog.current = 0;
  759. programChanged = true;
  760. }
  761. else
  762. {
  763. // no change
  764. pData->prog.current = current;
  765. }
  766. if (programChanged)
  767. {
  768. setProgram(pData->prog.current, true, true, true);
  769. }
  770. else
  771. {
  772. // Program was changed during update, re-set it
  773. if (pData->prog.current >= 0)
  774. dispatcher(effSetProgram, 0, pData->prog.current, nullptr, 0.0f);
  775. }
  776. pData->engine->callback(ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0.0f, nullptr);
  777. }
  778. }
  779. // -------------------------------------------------------------------
  780. // Plugin processing
  781. void activate() noexcept override
  782. {
  783. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  784. try {
  785. dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
  786. } catch(...) {}
  787. try {
  788. dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
  789. } catch(...) {}
  790. }
  791. void deactivate() noexcept override
  792. {
  793. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  794. try {
  795. dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
  796. } catch(...) {}
  797. try {
  798. dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
  799. } catch(...) {}
  800. }
  801. void process(const float** const audioIn, float** const audioOut, const float** const, float** const, const uint32_t frames) override
  802. {
  803. fProcThread = pthread_self();
  804. // --------------------------------------------------------------------------------------------------------
  805. // Check if active
  806. if (! pData->active)
  807. {
  808. // disable any output sound
  809. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  810. FloatVectorOperations::clear(audioOut[i], static_cast<int>(frames));
  811. return;
  812. }
  813. fMidiEventCount = 0;
  814. carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
  815. // --------------------------------------------------------------------------------------------------------
  816. // Check if needs reset
  817. if (pData->needsReset)
  818. {
  819. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  820. {
  821. fMidiEventCount = MAX_MIDI_CHANNELS*2;
  822. for (uint8_t i=0, k=MAX_MIDI_CHANNELS; i < MAX_MIDI_CHANNELS; ++i)
  823. {
  824. fMidiEvents[k].type = kVstMidiType;
  825. fMidiEvents[k].byteSize = kVstMidiEventSize;
  826. fMidiEvents[k].midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
  827. fMidiEvents[k].midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  828. fMidiEvents[k+i].type = kVstMidiType;
  829. fMidiEvents[k+i].byteSize = kVstMidiEventSize;
  830. fMidiEvents[k+i].midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
  831. fMidiEvents[k+i].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  832. }
  833. }
  834. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  835. {
  836. fMidiEventCount = MAX_MIDI_NOTE;
  837. for (uint8_t i=0; i < MAX_MIDI_NOTE; ++i)
  838. {
  839. fMidiEvents[i].type = kVstMidiType;
  840. fMidiEvents[i].byteSize = kVstMidiEventSize;
  841. fMidiEvents[i].midiData[0] = char(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
  842. fMidiEvents[i].midiData[1] = char(i);
  843. }
  844. }
  845. pData->needsReset = false;
  846. }
  847. // --------------------------------------------------------------------------------------------------------
  848. // Set TimeInfo
  849. const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
  850. fTimeInfo.flags = kVstTransportChanged;
  851. if (timeInfo.playing)
  852. fTimeInfo.flags |= kVstTransportPlaying;
  853. fTimeInfo.samplePos = double(timeInfo.frame);
  854. fTimeInfo.sampleRate = pData->engine->getSampleRate();
  855. if (timeInfo.usecs != 0)
  856. {
  857. fTimeInfo.nanoSeconds = double(timeInfo.usecs)/1000.0;
  858. fTimeInfo.flags |= kVstNanosValid;
  859. }
  860. if (timeInfo.valid & EngineTimeInfo::kValidBBT)
  861. {
  862. double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar;
  863. double ppqBeat = double(timeInfo.bbt.beat - 1);
  864. double ppqTick = double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat;
  865. // PPQ Pos
  866. fTimeInfo.ppqPos = ppqBar + ppqBeat + ppqTick;
  867. fTimeInfo.flags |= kVstPpqPosValid;
  868. // Tempo
  869. fTimeInfo.tempo = timeInfo.bbt.beatsPerMinute;
  870. fTimeInfo.flags |= kVstTempoValid;
  871. // Bars
  872. fTimeInfo.barStartPos = ppqBar;
  873. fTimeInfo.flags |= kVstBarsValid;
  874. // Time Signature
  875. fTimeInfo.timeSigNumerator = static_cast<int32_t>(timeInfo.bbt.beatsPerBar);
  876. fTimeInfo.timeSigDenominator = static_cast<int32_t>(timeInfo.bbt.beatType);
  877. fTimeInfo.flags |= kVstTimeSigValid;
  878. }
  879. else
  880. {
  881. // Tempo
  882. fTimeInfo.tempo = 120.0;
  883. fTimeInfo.flags |= kVstTempoValid;
  884. // Time Signature
  885. fTimeInfo.timeSigNumerator = 4;
  886. fTimeInfo.timeSigDenominator = 4;
  887. fTimeInfo.flags |= kVstTimeSigValid;
  888. // Missing info
  889. fTimeInfo.ppqPos = 0.0;
  890. fTimeInfo.barStartPos = 0.0;
  891. }
  892. // --------------------------------------------------------------------------------------------------------
  893. // Event Input and Processing
  894. if (pData->event.portIn != nullptr)
  895. {
  896. // ----------------------------------------------------------------------------------------------------
  897. // MIDI Input (External)
  898. if (pData->extNotes.mutex.tryLock())
  899. {
  900. ExternalMidiNote note = { 0, 0, 0 };
  901. for (; fMidiEventCount < kPluginMaxMidiEvents*2 && ! pData->extNotes.data.isEmpty();)
  902. {
  903. note = pData->extNotes.data.getFirst(note, true);
  904. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  905. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  906. vstMidiEvent.type = kVstMidiType;
  907. vstMidiEvent.byteSize = kVstMidiEventSize;
  908. vstMidiEvent.midiData[0] = char((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  909. vstMidiEvent.midiData[1] = char(note.note);
  910. vstMidiEvent.midiData[2] = char(note.velo);
  911. }
  912. pData->extNotes.mutex.unlock();
  913. } // End of MIDI Input (External)
  914. // ----------------------------------------------------------------------------------------------------
  915. // Event Input (System)
  916. #ifndef BUILD_BRIDGE
  917. bool allNotesOffSent = false;
  918. #endif
  919. bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
  920. uint32_t startTime = 0;
  921. uint32_t timeOffset = 0;
  922. for (uint32_t i=0, numEvents = pData->event.portIn->getEventCount(); i < numEvents; ++i)
  923. {
  924. const EngineEvent& event(pData->event.portIn->getEvent(i));
  925. if (event.time >= frames)
  926. continue;
  927. CARLA_ASSERT_INT2(event.time >= timeOffset, event.time, timeOffset);
  928. if (isSampleAccurate && event.time > timeOffset)
  929. {
  930. if (processSingle(audioIn, audioOut, event.time - timeOffset, timeOffset))
  931. {
  932. startTime = 0;
  933. timeOffset = event.time;
  934. if (fMidiEventCount > 0)
  935. {
  936. carla_zeroStructs(fMidiEvents, fMidiEventCount);
  937. fMidiEventCount = 0;
  938. }
  939. }
  940. else
  941. startTime += timeOffset;
  942. }
  943. switch (event.type)
  944. {
  945. case kEngineEventTypeNull:
  946. break;
  947. case kEngineEventTypeControl: {
  948. const EngineControlEvent& ctrlEvent(event.ctrl);
  949. switch (ctrlEvent.type)
  950. {
  951. case kEngineControlEventTypeNull:
  952. break;
  953. case kEngineControlEventTypeParameter: {
  954. #ifndef BUILD_BRIDGE
  955. // Control backend stuff
  956. if (event.channel == pData->ctrlChannel)
  957. {
  958. float value;
  959. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  960. {
  961. value = ctrlEvent.value;
  962. setDryWet(value, false, false);
  963. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  964. }
  965. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  966. {
  967. value = ctrlEvent.value*127.0f/100.0f;
  968. setVolume(value, false, false);
  969. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  970. }
  971. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  972. {
  973. float left, right;
  974. value = ctrlEvent.value/0.5f - 1.0f;
  975. if (value < 0.0f)
  976. {
  977. left = -1.0f;
  978. right = (value*2.0f)+1.0f;
  979. }
  980. else if (value > 0.0f)
  981. {
  982. left = (value*2.0f)-1.0f;
  983. right = 1.0f;
  984. }
  985. else
  986. {
  987. left = -1.0f;
  988. right = 1.0f;
  989. }
  990. setBalanceLeft(left, false, false);
  991. setBalanceRight(right, false, false);
  992. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  993. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  994. }
  995. }
  996. #endif
  997. // Control plugin parameters
  998. uint32_t k;
  999. for (k=0; k < pData->param.count; ++k)
  1000. {
  1001. if (pData->param.data[k].midiChannel != event.channel)
  1002. continue;
  1003. if (pData->param.data[k].midiCC != ctrlEvent.param)
  1004. continue;
  1005. if (pData->param.data[k].type != PARAMETER_INPUT)
  1006. continue;
  1007. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  1008. continue;
  1009. float value;
  1010. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  1011. {
  1012. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  1013. }
  1014. else
  1015. {
  1016. if (pData->param.data[k].hints & PARAMETER_IS_LOGARITHMIC)
  1017. value = pData->param.ranges[k].getUnnormalizedLogValue(ctrlEvent.value);
  1018. else
  1019. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  1020. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  1021. value = std::rint(value);
  1022. }
  1023. setParameterValue(k, value, false, false, false);
  1024. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  1025. }
  1026. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_CONTROL)
  1027. {
  1028. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1029. continue;
  1030. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1031. carla_zeroStruct(vstMidiEvent);
  1032. vstMidiEvent.type = kVstMidiType;
  1033. vstMidiEvent.byteSize = kVstMidiEventSize;
  1034. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : event.time);
  1035. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1036. vstMidiEvent.midiData[1] = char(ctrlEvent.param);
  1037. vstMidiEvent.midiData[2] = char(ctrlEvent.value*127.0f);
  1038. }
  1039. break;
  1040. } // case kEngineControlEventTypeParameter
  1041. case kEngineControlEventTypeMidiBank:
  1042. break;
  1043. case kEngineControlEventTypeMidiProgram:
  1044. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1045. {
  1046. if (ctrlEvent.param < pData->prog.count)
  1047. {
  1048. setProgram(ctrlEvent.param, false, false, false);
  1049. pData->postponeRtEvent(kPluginPostRtEventProgramChange, ctrlEvent.param, 0, 0.0f);
  1050. break;
  1051. }
  1052. }
  1053. break;
  1054. case kEngineControlEventTypeAllSoundOff:
  1055. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1056. {
  1057. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1058. continue;
  1059. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1060. carla_zeroStruct(vstMidiEvent);
  1061. vstMidiEvent.type = kVstMidiType;
  1062. vstMidiEvent.byteSize = kVstMidiEventSize;
  1063. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : event.time);
  1064. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1065. vstMidiEvent.midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  1066. }
  1067. break;
  1068. case kEngineControlEventTypeAllNotesOff:
  1069. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1070. {
  1071. #ifndef BUILD_BRIDGE
  1072. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  1073. {
  1074. allNotesOffSent = true;
  1075. sendMidiAllNotesOffToCallback();
  1076. }
  1077. #endif
  1078. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1079. continue;
  1080. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1081. carla_zeroStruct(vstMidiEvent);
  1082. vstMidiEvent.type = kVstMidiType;
  1083. vstMidiEvent.byteSize = kVstMidiEventSize;
  1084. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : event.time);
  1085. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1086. vstMidiEvent.midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  1087. }
  1088. break;
  1089. } // switch (ctrlEvent.type)
  1090. break;
  1091. } // case kEngineEventTypeControl
  1092. case kEngineEventTypeMidi: {
  1093. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1094. continue;
  1095. const EngineMidiEvent& midiEvent(event.midi);
  1096. if (midiEvent.size > 3)
  1097. continue;
  1098. static_assert(3 <= EngineMidiEvent::kDataSize, "Incorrect data");
  1099. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  1100. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  1101. continue;
  1102. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  1103. continue;
  1104. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  1105. continue;
  1106. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  1107. continue;
  1108. // Fix bad note-off
  1109. if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
  1110. status = MIDI_STATUS_NOTE_OFF;
  1111. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1112. carla_zeroStruct(vstMidiEvent);
  1113. vstMidiEvent.type = kVstMidiType;
  1114. vstMidiEvent.byteSize = kVstMidiEventSize;
  1115. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : event.time);
  1116. vstMidiEvent.midiData[0] = char(status | (event.channel & MIDI_CHANNEL_BIT));
  1117. vstMidiEvent.midiData[1] = char(midiEvent.size >= 2 ? midiEvent.data[1] : 0);
  1118. vstMidiEvent.midiData[2] = char(midiEvent.size >= 3 ? midiEvent.data[2] : 0);
  1119. if (status == MIDI_STATUS_NOTE_ON)
  1120. pData->postponeRtEvent(kPluginPostRtEventNoteOn, event.channel, midiEvent.data[1], midiEvent.data[2]);
  1121. else if (status == MIDI_STATUS_NOTE_OFF)
  1122. pData->postponeRtEvent(kPluginPostRtEventNoteOff, event.channel, midiEvent.data[1], 0.0f);
  1123. } break;
  1124. } // switch (event.type)
  1125. }
  1126. pData->postRtEvents.trySplice();
  1127. if (frames > timeOffset)
  1128. processSingle(audioIn, audioOut, frames - timeOffset, timeOffset);
  1129. } // End of Event Input and Processing
  1130. // --------------------------------------------------------------------------------------------------------
  1131. // Plugin processing (no events)
  1132. else
  1133. {
  1134. processSingle(audioIn, audioOut, frames, 0);
  1135. } // End of Plugin processing (no events)
  1136. // --------------------------------------------------------------------------------------------------------
  1137. // MIDI Output
  1138. if (pData->event.portOut != nullptr)
  1139. {
  1140. // reverse lookup MIDI events
  1141. for (uint32_t k = (kPluginMaxMidiEvents*2)-1; k >= fMidiEventCount; --k)
  1142. {
  1143. if (fMidiEvents[k].type == 0)
  1144. break;
  1145. const VstMidiEvent& vstMidiEvent(fMidiEvents[k]);
  1146. CARLA_SAFE_ASSERT_CONTINUE(vstMidiEvent.deltaFrames >= 0);
  1147. CARLA_SAFE_ASSERT_CONTINUE(vstMidiEvent.midiData[0] != 0);
  1148. uint8_t midiData[3];
  1149. midiData[0] = static_cast<uint8_t>(vstMidiEvent.midiData[0]);
  1150. midiData[1] = static_cast<uint8_t>(vstMidiEvent.midiData[1]);
  1151. midiData[2] = static_cast<uint8_t>(vstMidiEvent.midiData[2]);
  1152. pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(vstMidiEvent.deltaFrames), 3, midiData);
  1153. }
  1154. } // End of MIDI Output
  1155. }
  1156. bool processSingle(const float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  1157. {
  1158. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  1159. if (pData->audioIn.count > 0)
  1160. {
  1161. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  1162. }
  1163. if (pData->audioOut.count > 0)
  1164. {
  1165. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  1166. }
  1167. // --------------------------------------------------------------------------------------------------------
  1168. // Try lock, silence otherwise
  1169. if (pData->engine->isOffline())
  1170. {
  1171. pData->singleMutex.lock();
  1172. }
  1173. else if (! pData->singleMutex.tryLock())
  1174. {
  1175. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1176. {
  1177. for (uint32_t k=0; k < frames; ++k)
  1178. outBuffer[i][k+timeOffset] = 0.0f;
  1179. }
  1180. return false;
  1181. }
  1182. // --------------------------------------------------------------------------------------------------------
  1183. // Set audio buffers
  1184. float* vstInBuffer[pData->audioIn.count];
  1185. float* vstOutBuffer[pData->audioOut.count];
  1186. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  1187. vstInBuffer[i] = const_cast<float*>(inBuffer[i]+timeOffset);
  1188. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1189. vstOutBuffer[i] = outBuffer[i]+timeOffset;
  1190. // --------------------------------------------------------------------------------------------------------
  1191. // Set MIDI events
  1192. if (fMidiEventCount > 0)
  1193. {
  1194. fEvents.numEvents = static_cast<int32_t>(fMidiEventCount);
  1195. fEvents.reserved = 0;
  1196. dispatcher(effProcessEvents, 0, 0, &fEvents, 0.0f);
  1197. }
  1198. // --------------------------------------------------------------------------------------------------------
  1199. // Run plugin
  1200. fIsProcessing = true;
  1201. if (pData->hints & PLUGIN_CAN_PROCESS_REPLACING)
  1202. {
  1203. fEffect->processReplacing(fEffect, (pData->audioIn.count > 0) ? vstInBuffer : nullptr, (pData->audioOut.count > 0) ? vstOutBuffer : nullptr, static_cast<int32_t>(frames));
  1204. }
  1205. else
  1206. {
  1207. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1208. FloatVectorOperations::clear(vstOutBuffer[i], static_cast<int>(frames));
  1209. #if ! VST_FORCE_DEPRECATED
  1210. fEffect->process(fEffect, (pData->audioIn.count > 0) ? vstInBuffer : nullptr, (pData->audioOut.count > 0) ? vstOutBuffer : nullptr, static_cast<int32_t>(frames));
  1211. #endif
  1212. }
  1213. fIsProcessing = false;
  1214. fTimeInfo.samplePos += frames;
  1215. #ifndef BUILD_BRIDGE
  1216. // --------------------------------------------------------------------------------------------------------
  1217. // Post-processing (dry/wet, volume and balance)
  1218. {
  1219. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && carla_isNotEqual(pData->postProc.volume, 1.0f);
  1220. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
  1221. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  1222. bool isPair;
  1223. float bufValue, oldBufLeft[doBalance ? frames : 1];
  1224. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1225. {
  1226. // Dry/Wet
  1227. if (doDryWet)
  1228. {
  1229. for (uint32_t k=0; k < frames; ++k)
  1230. {
  1231. bufValue = inBuffer[(pData->audioIn.count == 1) ? 0 : i][k+timeOffset];
  1232. outBuffer[i][k+timeOffset] = (outBuffer[i][k+timeOffset] * 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. FloatVectorOperations::copy(oldBufLeft, outBuffer[i]+timeOffset, static_cast<int>(frames));
  1243. }
  1244. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  1245. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  1246. for (uint32_t k=0; k < frames; ++k)
  1247. {
  1248. if (isPair)
  1249. {
  1250. // left
  1251. outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL);
  1252. outBuffer[i][k+timeOffset] += outBuffer[i+1][k+timeOffset] * (1.0f - balRangeR);
  1253. }
  1254. else
  1255. {
  1256. // right
  1257. outBuffer[i][k+timeOffset] = outBuffer[i][k+timeOffset] * balRangeR;
  1258. outBuffer[i][k+timeOffset] += oldBufLeft[k] * balRangeL;
  1259. }
  1260. }
  1261. }
  1262. // Volume
  1263. if (doVolume)
  1264. {
  1265. for (uint32_t k=0; k < frames; ++k)
  1266. outBuffer[i][k+timeOffset] *= pData->postProc.volume;
  1267. }
  1268. }
  1269. } // End of Post-processing
  1270. #endif
  1271. // --------------------------------------------------------------------------------------------------------
  1272. pData->singleMutex.unlock();
  1273. return true;
  1274. }
  1275. void bufferSizeChanged(const uint32_t newBufferSize) override
  1276. {
  1277. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  1278. carla_debug("CarlaPluginVST2::bufferSizeChanged(%i)", newBufferSize);
  1279. if (pData->active)
  1280. deactivate();
  1281. #if ! VST_FORCE_DEPRECATED
  1282. dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast<int32_t>(newBufferSize), nullptr, static_cast<float>(pData->engine->getSampleRate()));
  1283. #endif
  1284. dispatcher(effSetBlockSize, 0, static_cast<int32_t>(newBufferSize), nullptr, 0.0f);
  1285. if (pData->active)
  1286. activate();
  1287. }
  1288. void sampleRateChanged(const double newSampleRate) override
  1289. {
  1290. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  1291. carla_debug("CarlaPluginVST2::sampleRateChanged(%g)", newSampleRate);
  1292. if (pData->active)
  1293. deactivate();
  1294. #if ! VST_FORCE_DEPRECATED
  1295. dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast<int32_t>(pData->engine->getBufferSize()), nullptr, static_cast<float>(newSampleRate));
  1296. #endif
  1297. dispatcher(effSetSampleRate, 0, 0, nullptr, static_cast<float>(newSampleRate));
  1298. if (pData->active)
  1299. activate();
  1300. }
  1301. // -------------------------------------------------------------------
  1302. // Plugin buffers
  1303. // nothing
  1304. // -------------------------------------------------------------------
  1305. // Post-poned UI Stuff
  1306. // nothing
  1307. // -------------------------------------------------------------------
  1308. protected:
  1309. void handlePluginUIClosed() override
  1310. {
  1311. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  1312. carla_debug("CarlaPluginVST2::handlePluginUIClosed()");
  1313. showCustomUI(false);
  1314. pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
  1315. }
  1316. void handlePluginUIResized(const uint width, const uint height) override
  1317. {
  1318. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  1319. carla_debug("CarlaPluginVST2::handlePluginUIResized(%u, %u)", width, height);
  1320. return; // unused
  1321. (void)width; (void)height;
  1322. }
  1323. // -------------------------------------------------------------------
  1324. intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) const noexcept
  1325. {
  1326. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  1327. #ifdef DEBUG
  1328. if (opcode != effIdle && opcode != effEditIdle && opcode != effProcessEvents)
  1329. carla_debug("CarlaPluginVST2::dispatcher(%02i:%s, %i, " P_INTPTR ", %p, %f)", opcode, vstEffectOpcode2str(opcode), index, value, ptr, opt);
  1330. #endif
  1331. try {
  1332. return fEffect->dispatcher(fEffect, opcode, index, value, ptr, opt);
  1333. } CARLA_SAFE_EXCEPTION_RETURN("Vst dispatcher", 0);
  1334. }
  1335. intptr_t handleAudioMasterCallback(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  1336. {
  1337. #ifdef DEBUG
  1338. if (opcode != audioMasterGetTime)
  1339. carla_debug("CarlaPluginVST2::handleAudioMasterCallback(%02i:%s, %i, " P_INTPTR ", %p, %f)", opcode, vstMasterOpcode2str(opcode), index, value, ptr, opt);
  1340. #endif
  1341. intptr_t ret = 0;
  1342. switch (opcode)
  1343. {
  1344. case audioMasterAutomate: {
  1345. CARLA_SAFE_ASSERT_BREAK(pData->enabled);
  1346. // plugins should never do this:
  1347. CARLA_SAFE_ASSERT_INT(index >= 0 && index < static_cast<int32_t>(pData->param.count), index);
  1348. if (index < 0 || index >= static_cast<int32_t>(pData->param.count))
  1349. break;
  1350. const uint32_t uindex(static_cast<uint32_t>(index));
  1351. const float fixedValue(pData->param.getFixedValue(uindex, opt));
  1352. // Called from plugin process thread, nasty!
  1353. if (pthread_equal(pthread_self(), fProcThread))
  1354. {
  1355. CARLA_SAFE_ASSERT(fIsProcessing);
  1356. pData->postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, fixedValue);
  1357. }
  1358. // Called from UI
  1359. else if (fUI.isVisible)
  1360. {
  1361. CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true);
  1362. }
  1363. // Unknown
  1364. // TODO - check if plugin or UI is initializing
  1365. else
  1366. {
  1367. carla_stdout("audioMasterAutomate called from unknown source");
  1368. setParameterValue(uindex, fixedValue, true, true, true);
  1369. //pData->postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, fixedValue);
  1370. }
  1371. break;
  1372. }
  1373. case audioMasterCurrentId:
  1374. ret = fEffect->uniqueID;
  1375. break;
  1376. case audioMasterIdle:
  1377. if (pthread_equal(pthread_self(), fMainThread))
  1378. {
  1379. pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
  1380. if (pData->engine->getType() != kEngineTypePlugin)
  1381. pData->engine->idle();
  1382. }
  1383. break;
  1384. #if ! VST_FORCE_DEPRECATED
  1385. case audioMasterPinConnected:
  1386. // Deprecated in VST SDK 2.4
  1387. // TODO
  1388. break;
  1389. case audioMasterWantMidi:
  1390. // Deprecated in VST SDK 2.4
  1391. pData->hints |= PLUGIN_WANTS_MIDI_INPUT;
  1392. break;
  1393. #endif
  1394. case audioMasterGetTime:
  1395. ret = (intptr_t)&fTimeInfo;
  1396. break;
  1397. case audioMasterProcessEvents:
  1398. CARLA_SAFE_ASSERT_RETURN(pData->enabled, 0);
  1399. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, 0);
  1400. CARLA_SAFE_ASSERT_RETURN(pData->event.portOut != nullptr, 0);
  1401. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1402. return 0;
  1403. if (const VstEvents* const vstEvents = (const VstEvents*)ptr)
  1404. {
  1405. for (int32_t i=0; i < vstEvents->numEvents && i < kPluginMaxMidiEvents*2; ++i)
  1406. {
  1407. if (vstEvents->events[i] == nullptr)
  1408. break;
  1409. const VstMidiEvent* const vstMidiEvent((const VstMidiEvent*)vstEvents->events[i]);
  1410. if (vstMidiEvent->type != kVstMidiType)
  1411. continue;
  1412. // reverse-find first free event, and put it there
  1413. for (uint32_t j=(kPluginMaxMidiEvents*2)-1; j >= fMidiEventCount; --j)
  1414. {
  1415. if (fMidiEvents[j].type == 0)
  1416. {
  1417. std::memcpy(&fMidiEvents[j], vstMidiEvent, sizeof(VstMidiEvent));
  1418. break;
  1419. }
  1420. }
  1421. }
  1422. }
  1423. ret = 1;
  1424. break;
  1425. #if ! VST_FORCE_DEPRECATED
  1426. case audioMasterSetTime:
  1427. // Deprecated in VST SDK 2.4
  1428. break;
  1429. case audioMasterTempoAt:
  1430. // Deprecated in VST SDK 2.4
  1431. ret = static_cast<intptr_t>(fTimeInfo.tempo * 10000);
  1432. break;
  1433. case audioMasterGetNumAutomatableParameters:
  1434. // Deprecated in VST SDK 2.4
  1435. ret = static_cast<intptr_t>(pData->engine->getOptions().maxParameters);
  1436. ret = carla_minPositive<intptr_t>(ret, fEffect->numParams);
  1437. break;
  1438. case audioMasterGetParameterQuantization:
  1439. // Deprecated in VST SDK 2.4
  1440. ret = 1; // full single float precision
  1441. break;
  1442. #endif
  1443. #if 0
  1444. case audioMasterIOChanged:
  1445. CARLA_ASSERT(pData->enabled);
  1446. // TESTING
  1447. if (! pData->enabled)
  1448. {
  1449. ret = 1;
  1450. break;
  1451. }
  1452. if (x_engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK)
  1453. {
  1454. carla_stderr2("CarlaPluginVST2::handleAudioMasterIOChanged() - plugin asked IO change, but it's not supported in rack mode");
  1455. return 0;
  1456. }
  1457. engineProcessLock();
  1458. m_enabled = false;
  1459. engineProcessUnlock();
  1460. if (m_active)
  1461. {
  1462. effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
  1463. effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
  1464. }
  1465. reload();
  1466. if (m_active)
  1467. {
  1468. effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
  1469. effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
  1470. }
  1471. x_engine->callback(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0, nullptr);
  1472. ret = 1;
  1473. break;
  1474. #endif
  1475. #if ! VST_FORCE_DEPRECATED
  1476. case audioMasterNeedIdle:
  1477. // Deprecated in VST SDK 2.4
  1478. fNeedIdle = true;
  1479. ret = 1;
  1480. break;
  1481. #endif
  1482. case audioMasterSizeWindow:
  1483. CARLA_SAFE_ASSERT_BREAK(fUI.window != nullptr);
  1484. CARLA_SAFE_ASSERT_BREAK(index > 0);
  1485. CARLA_SAFE_ASSERT_BREAK(value > 0);
  1486. fUI.window->setSize(static_cast<uint>(index), static_cast<uint>(value), true);
  1487. ret = 1;
  1488. break;
  1489. case audioMasterGetSampleRate:
  1490. ret = static_cast<intptr_t>(pData->engine->getSampleRate());
  1491. break;
  1492. case audioMasterGetBlockSize:
  1493. ret = static_cast<intptr_t>(pData->engine->getBufferSize());
  1494. break;
  1495. case audioMasterGetInputLatency:
  1496. ret = 0;
  1497. break;
  1498. case audioMasterGetOutputLatency:
  1499. ret = 0;
  1500. break;
  1501. #if ! VST_FORCE_DEPRECATED
  1502. case audioMasterGetPreviousPlug:
  1503. // Deprecated in VST SDK 2.4
  1504. // TODO
  1505. break;
  1506. case audioMasterGetNextPlug:
  1507. // Deprecated in VST SDK 2.4
  1508. // TODO
  1509. break;
  1510. case audioMasterWillReplaceOrAccumulate:
  1511. // Deprecated in VST SDK 2.4
  1512. ret = 1; // replace
  1513. break;
  1514. #endif
  1515. case audioMasterGetCurrentProcessLevel:
  1516. if (pthread_equal(pthread_self(), fProcThread))
  1517. {
  1518. CARLA_SAFE_ASSERT(fIsProcessing);
  1519. if (pData->engine->isOffline())
  1520. ret = kVstProcessLevelOffline;
  1521. else
  1522. ret = kVstProcessLevelRealtime;
  1523. }
  1524. else
  1525. ret = kVstProcessLevelUser;
  1526. break;
  1527. case audioMasterGetAutomationState:
  1528. ret = pData->active ? kVstAutomationReadWrite : kVstAutomationOff;
  1529. break;
  1530. case audioMasterOfflineStart:
  1531. case audioMasterOfflineRead:
  1532. case audioMasterOfflineWrite:
  1533. case audioMasterOfflineGetCurrentPass:
  1534. case audioMasterOfflineGetCurrentMetaPass:
  1535. // TODO
  1536. break;
  1537. #if ! VST_FORCE_DEPRECATED
  1538. case audioMasterSetOutputSampleRate:
  1539. // Deprecated in VST SDK 2.4
  1540. break;
  1541. case audioMasterGetOutputSpeakerArrangement:
  1542. // Deprecated in VST SDK 2.4
  1543. // TODO
  1544. break;
  1545. #endif
  1546. case audioMasterVendorSpecific:
  1547. // TODO - cockos extensions
  1548. break;
  1549. #if ! VST_FORCE_DEPRECATED
  1550. case audioMasterSetIcon:
  1551. // Deprecated in VST SDK 2.4
  1552. break;
  1553. #endif
  1554. #if ! VST_FORCE_DEPRECATED
  1555. case audioMasterOpenWindow:
  1556. case audioMasterCloseWindow:
  1557. // Deprecated in VST SDK 2.4
  1558. // TODO
  1559. break;
  1560. #endif
  1561. case audioMasterGetDirectory:
  1562. // TODO
  1563. break;
  1564. case audioMasterUpdateDisplay:
  1565. // Idle UI if visible
  1566. if (fUI.isVisible)
  1567. dispatcher(effEditIdle, 0, 0, nullptr, 0.0f);
  1568. // Update current program
  1569. if (pData->prog.count > 0)
  1570. {
  1571. const int32_t current = static_cast<int32_t>(dispatcher(effGetProgram, 0, 0, nullptr, 0.0f));
  1572. if (current >= 0 && current < static_cast<int32_t>(pData->prog.count))
  1573. {
  1574. char strBuf[STR_MAX+1] = { '\0' };
  1575. dispatcher(effGetProgramName, 0, 0, strBuf, 0.0f);
  1576. if (pData->prog.names[current] != nullptr)
  1577. delete[] pData->prog.names[current];
  1578. pData->prog.names[current] = carla_strdup(strBuf);
  1579. if (pData->prog.current != current)
  1580. {
  1581. pData->prog.current = current;
  1582. pData->engine->callback(ENGINE_CALLBACK_PROGRAM_CHANGED, pData->id, current, 0, 0.0f, nullptr);
  1583. }
  1584. }
  1585. }
  1586. pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0.0f, nullptr);
  1587. ret = 1;
  1588. break;
  1589. case audioMasterBeginEdit:
  1590. case audioMasterEndEdit:
  1591. // TODO
  1592. break;
  1593. case audioMasterOpenFileSelector:
  1594. case audioMasterCloseFileSelector:
  1595. // TODO
  1596. break;
  1597. #if ! VST_FORCE_DEPRECATED
  1598. case audioMasterEditFile:
  1599. // Deprecated in VST SDK 2.4
  1600. // TODO
  1601. break;
  1602. case audioMasterGetChunkFile:
  1603. // Deprecated in VST SDK 2.4
  1604. // TODO
  1605. break;
  1606. case audioMasterGetInputSpeakerArrangement:
  1607. // Deprecated in VST SDK 2.4
  1608. // TODO
  1609. break;
  1610. #endif
  1611. default:
  1612. carla_debug("CarlaPluginVST2::handleAudioMasterCallback(%02i:%s, %i, " P_INTPTR ", %p, %f) UNDEF", opcode, vstMasterOpcode2str(opcode), index, value, ptr, opt);
  1613. break;
  1614. }
  1615. return ret;
  1616. // unused
  1617. (void)opt;
  1618. }
  1619. bool canDo(const char* const feature) const noexcept
  1620. {
  1621. try {
  1622. return (fEffect->dispatcher(fEffect, effCanDo, 0, 0, const_cast<char*>(feature), 0.0f) == 1);
  1623. } CARLA_SAFE_EXCEPTION_RETURN("vstPluginCanDo", false);
  1624. }
  1625. bool hasMidiInput() const noexcept
  1626. {
  1627. return (canDo("receiveVstEvents") || canDo("receiveVstMidiEvent") || (fEffect->flags & effFlagsIsSynth) > 0 || (pData->hints & PLUGIN_WANTS_MIDI_INPUT));
  1628. }
  1629. bool hasMidiOutput() const noexcept
  1630. {
  1631. return (canDo("sendVstEvents") || canDo("sendVstMidiEvent"));
  1632. }
  1633. // -------------------------------------------------------------------
  1634. const void* getNativeDescriptor() const noexcept override
  1635. {
  1636. return fEffect;
  1637. }
  1638. // -------------------------------------------------------------------
  1639. public:
  1640. bool init(const char* const filename, const char* const name, const int64_t uniqueId, const uint options)
  1641. {
  1642. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1643. // ---------------------------------------------------------------
  1644. // first checks
  1645. if (pData->client != nullptr)
  1646. {
  1647. pData->engine->setLastError("Plugin client is already registered");
  1648. return false;
  1649. }
  1650. if (filename == nullptr || filename[0] == '\0')
  1651. {
  1652. pData->engine->setLastError("null filename");
  1653. return false;
  1654. }
  1655. // ---------------------------------------------------------------
  1656. // open DLL
  1657. if (! pData->libOpen(filename))
  1658. {
  1659. pData->engine->setLastError(pData->libError(filename));
  1660. return false;
  1661. }
  1662. // ---------------------------------------------------------------
  1663. // get DLL main entry
  1664. VST_Function vstFn = pData->libSymbol<VST_Function>("VSTPluginMain");
  1665. if (vstFn == nullptr)
  1666. {
  1667. vstFn = pData->libSymbol<VST_Function>("main");
  1668. if (vstFn == nullptr)
  1669. {
  1670. pData->engine->setLastError("Could not find the VST main entry in the plugin library");
  1671. return false;
  1672. }
  1673. }
  1674. // ---------------------------------------------------------------
  1675. // initialize plugin (part 1)
  1676. sCurrentUniqueId = uniqueId;
  1677. sLastCarlaPluginVST2 = this;
  1678. try {
  1679. fEffect = vstFn(carla_vst_audioMasterCallback);
  1680. } CARLA_SAFE_EXCEPTION_RETURN("Vst init", false);
  1681. sLastCarlaPluginVST2 = nullptr;
  1682. sCurrentUniqueId = 0;
  1683. if (fEffect == nullptr)
  1684. {
  1685. pData->engine->setLastError("Plugin failed to initialize");
  1686. return false;
  1687. }
  1688. if (fEffect->magic != kEffectMagic)
  1689. {
  1690. pData->engine->setLastError("Plugin is not valid (wrong vst effect magic code)");
  1691. return false;
  1692. }
  1693. #ifdef VESTIGE_HEADER
  1694. fEffect->ptr1 = this;
  1695. #else
  1696. fEffect->resvd1 = (intptr_t)this;
  1697. #endif
  1698. dispatcher(effOpen, 0, 0, nullptr, 0.0f);
  1699. // ---------------------------------------------------------------
  1700. // get info
  1701. if (name != nullptr && name[0] != '\0')
  1702. {
  1703. pData->name = pData->engine->getUniquePluginName(name);
  1704. }
  1705. else
  1706. {
  1707. char strBuf[STR_MAX+1];
  1708. carla_zeroChars(strBuf, STR_MAX+1);
  1709. dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
  1710. if (strBuf[0] != '\0')
  1711. pData->name = pData->engine->getUniquePluginName(strBuf);
  1712. else if (const char* const shortname = std::strrchr(filename, CARLA_OS_SEP))
  1713. pData->name = pData->engine->getUniquePluginName(shortname+1);
  1714. else
  1715. pData->name = pData->engine->getUniquePluginName("unknown");
  1716. }
  1717. pData->filename = carla_strdup(filename);
  1718. // ---------------------------------------------------------------
  1719. // register client
  1720. pData->client = pData->engine->addClient(this);
  1721. if (pData->client == nullptr || ! pData->client->isOk())
  1722. {
  1723. pData->engine->setLastError("Failed to register plugin client");
  1724. return false;
  1725. }
  1726. // ---------------------------------------------------------------
  1727. // initialize plugin (part 2)
  1728. #if ! VST_FORCE_DEPRECATED
  1729. dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast<int32_t>(pData->engine->getBufferSize()), nullptr, static_cast<float>(pData->engine->getSampleRate()));
  1730. #endif
  1731. dispatcher(effSetSampleRate, 0, 0, nullptr, static_cast<float>(pData->engine->getSampleRate()));
  1732. dispatcher(effSetBlockSize, 0, static_cast<int32_t>(pData->engine->getBufferSize()), nullptr, 0.0f);
  1733. dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  1734. if (dispatcher(effGetVstVersion, 0, 0, nullptr, 0.0f) < kVstVersion)
  1735. pData->hints |= PLUGIN_USES_OLD_VSTSDK;
  1736. if (static_cast<uintptr_t>(dispatcher(effCanDo, 0, 0, const_cast<char*>("hasCockosExtensions"), 0.0f)) == 0xbeef0000)
  1737. pData->hints |= PLUGIN_HAS_COCKOS_EXTENSIONS;
  1738. // ---------------------------------------------------------------
  1739. // set default options
  1740. pData->options = 0x0;
  1741. if (pData->latency.frames != 0 || hasMidiOutput())
  1742. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  1743. else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
  1744. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  1745. if (fEffect->numPrograms > 1)
  1746. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1747. if (fEffect->flags & effFlagsProgramChunks)
  1748. pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  1749. if (hasMidiInput())
  1750. {
  1751. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1752. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  1753. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  1754. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1755. if (options & PLUGIN_OPTION_SEND_CONTROL_CHANGES)
  1756. pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  1757. }
  1758. return true;
  1759. // unused
  1760. (void)uniqueId;
  1761. }
  1762. private:
  1763. int fUnique1;
  1764. AEffect* fEffect;
  1765. uint32_t fMidiEventCount;
  1766. VstMidiEvent fMidiEvents[kPluginMaxMidiEvents*2];
  1767. VstTimeInfo fTimeInfo;
  1768. bool fNeedIdle;
  1769. void* fLastChunk;
  1770. bool fIsProcessing;
  1771. pthread_t fMainThread;
  1772. pthread_t fProcThread;
  1773. struct FixedVstEvents {
  1774. int32_t numEvents;
  1775. intptr_t reserved;
  1776. VstEvent* data[kPluginMaxMidiEvents*2];
  1777. FixedVstEvents() noexcept
  1778. : numEvents(0),
  1779. reserved(0)
  1780. {
  1781. carla_zeroPointers(data, kPluginMaxMidiEvents*2);
  1782. }
  1783. CARLA_DECLARE_NON_COPY_STRUCT(FixedVstEvents);
  1784. } fEvents;
  1785. struct UI {
  1786. bool isVisible;
  1787. CarlaPluginUI* window;
  1788. UI() noexcept
  1789. : isVisible(false),
  1790. window(nullptr) {}
  1791. ~UI()
  1792. {
  1793. CARLA_ASSERT(! isVisible);
  1794. if (window != nullptr)
  1795. {
  1796. delete window;
  1797. window = nullptr;
  1798. }
  1799. }
  1800. CARLA_DECLARE_NON_COPY_STRUCT(UI);
  1801. } fUI;
  1802. int fUnique2;
  1803. static intptr_t sCurrentUniqueId;
  1804. static CarlaPluginVST2* sLastCarlaPluginVST2;
  1805. // -------------------------------------------------------------------
  1806. static intptr_t carla_vst_hostCanDo(const char* const feature)
  1807. {
  1808. carla_debug("carla_vst_hostCanDo(\"%s\")", feature);
  1809. if (std::strcmp(feature, "supplyIdle") == 0)
  1810. return 1;
  1811. if (std::strcmp(feature, "sendVstEvents") == 0)
  1812. return 1;
  1813. if (std::strcmp(feature, "sendVstMidiEvent") == 0)
  1814. return 1;
  1815. if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
  1816. return 1;
  1817. if (std::strcmp(feature, "sendVstTimeInfo") == 0)
  1818. return 1;
  1819. if (std::strcmp(feature, "receiveVstEvents") == 0)
  1820. return 1;
  1821. if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
  1822. return 1;
  1823. if (std::strcmp(feature, "receiveVstTimeInfo") == 0)
  1824. return -1;
  1825. if (std::strcmp(feature, "reportConnectionChanges") == 0)
  1826. return -1;
  1827. if (std::strcmp(feature, "acceptIOChanges") == 0)
  1828. return 1;
  1829. if (std::strcmp(feature, "sizeWindow") == 0)
  1830. return 1;
  1831. if (std::strcmp(feature, "offline") == 0)
  1832. return -1;
  1833. if (std::strcmp(feature, "openFileSelector") == 0)
  1834. return -1;
  1835. if (std::strcmp(feature, "closeFileSelector") == 0)
  1836. return -1;
  1837. if (std::strcmp(feature, "startStopProcess") == 0)
  1838. return 1;
  1839. if (std::strcmp(feature, "supportShell") == 0)
  1840. return 1;
  1841. if (std::strcmp(feature, "shellCategory") == 0)
  1842. return 1;
  1843. // unimplemented
  1844. carla_stderr("carla_vst_hostCanDo(\"%s\") - unknown feature", feature);
  1845. return 0;
  1846. }
  1847. static intptr_t VSTCALLBACK carla_vst_audioMasterCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
  1848. {
  1849. #if defined(DEBUG) && ! defined(CARLA_OS_WIN)
  1850. if (opcode != audioMasterGetTime && opcode != audioMasterProcessEvents && opcode != audioMasterGetCurrentProcessLevel && opcode != audioMasterGetOutputLatency)
  1851. carla_debug("carla_vst_audioMasterCallback(%p, %02i:%s, %i, " P_INTPTR ", %p, %f)", effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, opt);
  1852. #endif
  1853. switch (opcode)
  1854. {
  1855. case audioMasterVersion:
  1856. return kVstVersion;
  1857. case audioMasterCurrentId:
  1858. if (sCurrentUniqueId != 0)
  1859. return sCurrentUniqueId;
  1860. break;
  1861. case audioMasterGetVendorString:
  1862. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  1863. std::strcpy((char*)ptr, "falkTX");
  1864. return 1;
  1865. case audioMasterGetProductString:
  1866. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  1867. std::strcpy((char*)ptr, "Carla");
  1868. return 1;
  1869. case audioMasterGetVendorVersion:
  1870. return CARLA_VERSION_HEX;
  1871. case audioMasterCanDo:
  1872. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  1873. return carla_vst_hostCanDo((const char*)ptr);
  1874. case audioMasterGetLanguage:
  1875. return kVstLangEnglish;
  1876. }
  1877. // Check if 'resvd1' points to us, otherwise register ourselfs if possible
  1878. CarlaPluginVST2* self = nullptr;
  1879. if (effect != nullptr)
  1880. {
  1881. #ifdef VESTIGE_HEADER
  1882. if (effect->ptr1 != nullptr)
  1883. {
  1884. self = (CarlaPluginVST2*)effect->ptr1;
  1885. if (self->fUnique1 != self->fUnique2)
  1886. self = nullptr;
  1887. }
  1888. #else
  1889. if (effect->resvd1 != 0)
  1890. {
  1891. self = (CarlaPluginVST2*)effect->resvd1;
  1892. if (self->fUnique1 != self->fUnique2)
  1893. self = nullptr;
  1894. }
  1895. #endif
  1896. if (self != nullptr)
  1897. {
  1898. if (self->fEffect == nullptr)
  1899. self->fEffect = effect;
  1900. if (self->fEffect != effect)
  1901. {
  1902. carla_stderr2("carla_vst_audioMasterCallback() - host pointer mismatch: %p != %p", self->fEffect, effect);
  1903. self = nullptr;
  1904. }
  1905. }
  1906. else if (sLastCarlaPluginVST2 != nullptr)
  1907. {
  1908. #ifdef VESTIGE_HEADER
  1909. effect->ptr1 = sLastCarlaPluginVST2;
  1910. #else
  1911. effect->resvd1 = (intptr_t)sLastCarlaPluginVST2;
  1912. #endif
  1913. self = sLastCarlaPluginVST2;
  1914. }
  1915. }
  1916. return (self != nullptr) ? self->handleAudioMasterCallback(opcode, index, value, ptr, opt) : 0;
  1917. }
  1918. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginVST2)
  1919. };
  1920. intptr_t CarlaPluginVST2::sCurrentUniqueId = 0;
  1921. CarlaPluginVST2* CarlaPluginVST2::sLastCarlaPluginVST2 = nullptr;
  1922. CARLA_BACKEND_END_NAMESPACE
  1923. #endif // ! USE_JUCE_FOR_VST
  1924. // -------------------------------------------------------------------------------------------------------------------
  1925. CARLA_BACKEND_START_NAMESPACE
  1926. CarlaPlugin* CarlaPlugin::newVST2(const Initializer& init)
  1927. {
  1928. carla_debug("CarlaPlugin::newVST2({%p, \"%s\", \"%s\", " P_INT64 "})", init.engine, init.filename, init.name, init.uniqueId);
  1929. #ifdef USE_JUCE_FOR_VST
  1930. return newJuce(init, "VST");
  1931. #else
  1932. CarlaPluginVST2* const plugin(new CarlaPluginVST2(init.engine, init.id));
  1933. if (! plugin->init(init.filename, init.name, init.uniqueId, init.options))
  1934. {
  1935. delete plugin;
  1936. return nullptr;
  1937. }
  1938. return plugin;
  1939. #endif
  1940. }
  1941. // -------------------------------------------------------------------------------------------------------------------
  1942. CARLA_BACKEND_END_NAMESPACE