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

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
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
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
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
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
6 years ago
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
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
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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988
  1. /*
  2. * Carla VST2 Plugin
  3. * Copyright (C) 2011-2022 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. #include "AppConfig.h"
  20. #if defined(USING_JUCE) && JUCE_PLUGINHOST_VST
  21. # define USE_JUCE_FOR_VST2
  22. #endif
  23. #include "CarlaBackendUtils.hpp"
  24. #include "CarlaMathUtils.hpp"
  25. #include "CarlaProcessUtils.hpp"
  26. #include "CarlaScopeUtils.hpp"
  27. #include "CarlaVst2Utils.hpp"
  28. #include "CarlaPluginUI.hpp"
  29. #ifdef CARLA_OS_MAC
  30. # include "CarlaMacUtils.hpp"
  31. # import <Foundation/Foundation.h>
  32. #endif
  33. #include <pthread.h>
  34. #include "water/memory/ByteOrder.h"
  35. #undef VST_FORCE_DEPRECATED
  36. #define VST_FORCE_DEPRECATED 0
  37. #undef kEffectMagic
  38. #define kEffectMagic (CCONST( 'V', 's', 't', 'P' ))
  39. using water::ByteOrder;
  40. CARLA_BACKEND_START_NAMESPACE
  41. // -----------------------------------------------------
  42. const uint PLUGIN_CAN_PROCESS_REPLACING = 0x1000;
  43. const uint PLUGIN_HAS_COCKOS_EXTENSIONS = 0x2000;
  44. const uint PLUGIN_USES_OLD_VSTSDK = 0x4000;
  45. const uint PLUGIN_WANTS_MIDI_INPUT = 0x8000;
  46. static const int32_t kVstMidiEventSize = static_cast<int32_t>(sizeof(VstMidiEvent));
  47. #ifdef PTW32_DLLPORT
  48. static const pthread_t kNullThread = {nullptr, 0};
  49. #else
  50. static const pthread_t kNullThread = 0;
  51. #endif
  52. // --------------------------------------------------------------------------------------------------------------------
  53. class CarlaPluginVST2 : public CarlaPlugin,
  54. private CarlaPluginUI::Callback
  55. {
  56. public:
  57. CarlaPluginVST2(CarlaEngine* const engine, const uint id)
  58. : CarlaPlugin(engine, id),
  59. fUnique1(1),
  60. fEffect(nullptr),
  61. fMidiEventCount(0),
  62. fTimeInfo(),
  63. fNeedIdle(false),
  64. fLastChunk(nullptr),
  65. fIsInitializing(true),
  66. fIsProcessing(false),
  67. fChangingValuesThread(kNullThread),
  68. fIdleThread(kNullThread),
  69. fMainThread(pthread_self()),
  70. fProcThread(kNullThread),
  71. #ifdef CARLA_OS_MAC
  72. fBundleLoader(),
  73. #endif
  74. fFirstActive(true),
  75. fBufferSize(engine->getBufferSize()),
  76. fAudioOutBuffers(nullptr),
  77. fLastTimeInfo(),
  78. fEvents(),
  79. fUI(),
  80. fUnique2(2)
  81. {
  82. carla_debug("CarlaPluginVST2::CarlaPluginVST2(%p, %i)", engine, id);
  83. carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
  84. carla_zeroStruct(fTimeInfo);
  85. for (ushort i=0; i < kPluginMaxMidiEvents*2; ++i)
  86. fEvents.data[i] = (VstEvent*)&fMidiEvents[i];
  87. // make plugin valid
  88. srand(id);
  89. fUnique1 = fUnique2 = rand();
  90. }
  91. ~CarlaPluginVST2() override
  92. {
  93. carla_debug("CarlaPluginVST2::~CarlaPluginVST2()");
  94. // close UI
  95. if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
  96. {
  97. showCustomUI(false);
  98. if (fUI.isOpen)
  99. {
  100. fUI.isOpen = false;
  101. dispatcher(effEditClose);
  102. }
  103. }
  104. pData->singleMutex.lock();
  105. pData->masterMutex.lock();
  106. if (pData->client != nullptr && pData->client->isActive())
  107. pData->client->deactivate(true);
  108. CARLA_ASSERT(! fIsProcessing);
  109. if (pData->active)
  110. {
  111. deactivate();
  112. pData->active = false;
  113. }
  114. if (fEffect != nullptr)
  115. {
  116. dispatcher(effClose);
  117. fEffect = nullptr;
  118. }
  119. // make plugin invalid
  120. fUnique2 += 1;
  121. if (fLastChunk != nullptr)
  122. {
  123. std::free(fLastChunk);
  124. fLastChunk = nullptr;
  125. }
  126. clearBuffers();
  127. }
  128. // -------------------------------------------------------------------
  129. // Information (base)
  130. PluginType getType() const noexcept override
  131. {
  132. return PLUGIN_VST2;
  133. }
  134. PluginCategory getCategory() const noexcept override
  135. {
  136. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, CarlaPlugin::getCategory());
  137. const intptr_t category = dispatcher(effGetPlugCategory);
  138. switch (category)
  139. {
  140. case kPlugCategSynth:
  141. return PLUGIN_CATEGORY_SYNTH;
  142. case kPlugCategAnalysis:
  143. return PLUGIN_CATEGORY_UTILITY;
  144. case kPlugCategMastering:
  145. return PLUGIN_CATEGORY_DYNAMICS;
  146. case kPlugCategRoomFx:
  147. return PLUGIN_CATEGORY_DELAY;
  148. case kPlugCategRestoration:
  149. return PLUGIN_CATEGORY_UTILITY;
  150. case kPlugCategGenerator:
  151. return PLUGIN_CATEGORY_SYNTH;
  152. }
  153. if (fEffect->flags & effFlagsIsSynth)
  154. return PLUGIN_CATEGORY_SYNTH;
  155. return CarlaPlugin::getCategory();
  156. }
  157. int64_t getUniqueId() const noexcept override
  158. {
  159. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  160. return static_cast<int64_t>(fEffect->uniqueID);
  161. }
  162. uint32_t getLatencyInFrames() const noexcept override
  163. {
  164. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  165. const int latency = fEffect->initialDelay;
  166. CARLA_SAFE_ASSERT_RETURN(latency >= 0, 0);
  167. return static_cast<uint32_t>(latency);
  168. }
  169. // -------------------------------------------------------------------
  170. // Information (count)
  171. // nothing
  172. // -------------------------------------------------------------------
  173. // Information (current data)
  174. std::size_t getChunkData(void** const dataPtr) noexcept override
  175. {
  176. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS, 0);
  177. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  178. CARLA_SAFE_ASSERT_RETURN(dataPtr != nullptr, 0);
  179. *dataPtr = nullptr;
  180. try {
  181. const intptr_t ret = dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr);
  182. CARLA_SAFE_ASSERT_RETURN(ret >= 0, 0);
  183. return static_cast<std::size_t>(ret);
  184. } CARLA_SAFE_EXCEPTION_RETURN("CarlaPluginVST2::getChunkData", 0);
  185. }
  186. // -------------------------------------------------------------------
  187. // Information (per-plugin data)
  188. uint getOptionsAvailable() const noexcept override
  189. {
  190. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  191. uint options = 0x0;
  192. // can't disable fixed buffers if using latency or MIDI output
  193. if (pData->latency.frames == 0 && ! hasMidiOutput())
  194. options |= PLUGIN_OPTION_FIXED_BUFFERS;
  195. if (fEffect->numPrograms > 1)
  196. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  197. if (fEffect->flags & effFlagsProgramChunks)
  198. options |= PLUGIN_OPTION_USE_CHUNKS;
  199. if (hasMidiInput())
  200. {
  201. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  202. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  203. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  204. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  205. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  206. options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  207. options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  208. }
  209. return options;
  210. }
  211. float getParameterValue(const uint32_t parameterId) const noexcept override
  212. {
  213. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0.0f);
  214. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  215. return fEffect->getParameter(fEffect, static_cast<int32_t>(parameterId));
  216. }
  217. bool getLabel(char* const strBuf) const noexcept override
  218. {
  219. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  220. strBuf[0] = '\0';
  221. dispatcher(effGetProductString, 0, 0, strBuf);
  222. return true;
  223. }
  224. bool getMaker(char* const strBuf) const noexcept override
  225. {
  226. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  227. strBuf[0] = '\0';
  228. dispatcher(effGetVendorString, 0, 0, strBuf);
  229. return true;
  230. }
  231. bool getCopyright(char* const strBuf) const noexcept override
  232. {
  233. return getMaker(strBuf);
  234. }
  235. bool getRealName(char* const strBuf) const noexcept override
  236. {
  237. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  238. strBuf[0] = '\0';
  239. dispatcher(effGetEffectName, 0, 0, strBuf);
  240. return true;
  241. }
  242. bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  243. {
  244. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  245. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  246. strBuf[0] = '\0';
  247. VstParameterProperties prop;
  248. carla_zeroStruct(prop);
  249. if (dispatcher(effGetParameterProperties, static_cast<int32_t>(parameterId), 0, &prop) == 1
  250. && prop.label[0] != '\0')
  251. {
  252. std::strncpy(strBuf, prop.label, VestigeMaxLabelLen);
  253. strBuf[VestigeMaxLabelLen] = '\0';
  254. return true;
  255. }
  256. strBuf[0] = '\0';
  257. dispatcher(effGetParamName, static_cast<int32_t>(parameterId), 0, strBuf);
  258. return true;
  259. }
  260. bool getParameterText(const uint32_t parameterId, char* const strBuf) noexcept override
  261. {
  262. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  263. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  264. strBuf[0] = '\0';
  265. dispatcher(effGetParamDisplay, static_cast<int32_t>(parameterId), 0, strBuf);
  266. if (strBuf[0] == '\0')
  267. std::snprintf(strBuf, STR_MAX, "%.12g", static_cast<double>(getParameterValue(parameterId)));
  268. return true;
  269. }
  270. bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  271. {
  272. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  273. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  274. strBuf[0] = '\0';
  275. dispatcher(effGetParamLabel, static_cast<int32_t>(parameterId), 0, strBuf);
  276. return true;
  277. }
  278. bool getParameterGroupName(const uint32_t parameterId, char* const strBuf) const noexcept override
  279. {
  280. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, false);
  281. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  282. strBuf[0] = '\0';
  283. VstParameterProperties prop;
  284. carla_zeroStruct(prop);
  285. if (dispatcher(effGetParameterProperties, static_cast<int32_t>(parameterId), 0, &prop) == 1
  286. && prop.category != 0 && prop.categoryLabel[0] != '\0')
  287. {
  288. std::snprintf(strBuf, STR_MAX, "%d:%s", prop.category, prop.categoryLabel);
  289. return true;
  290. }
  291. return false;
  292. }
  293. // -------------------------------------------------------------------
  294. // Set data (state)
  295. // nothing
  296. // -------------------------------------------------------------------
  297. // Set data (internal stuff)
  298. void setName(const char* const newName) override
  299. {
  300. CarlaPlugin::setName(newName);
  301. if (fUI.window == nullptr || pData->uiTitle.isNotEmpty())
  302. return;
  303. CarlaString uiTitle(pData->name);
  304. uiTitle += " (GUI)";
  305. fUI.window->setTitle(uiTitle.buffer());
  306. }
  307. // -------------------------------------------------------------------
  308. // Set data (plugin-specific stuff)
  309. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  310. {
  311. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  312. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  313. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  314. fEffect->setParameter(fEffect, static_cast<int32_t>(parameterId), fixedValue);
  315. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  316. }
  317. void setParameterValueRT(const uint32_t parameterId, const float value, const uint32_t frameOffset, const bool sendCallbackLater) noexcept override
  318. {
  319. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  320. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  321. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  322. fEffect->setParameter(fEffect, static_cast<int32_t>(parameterId), fixedValue);
  323. CarlaPlugin::setParameterValueRT(parameterId, fixedValue, frameOffset, sendCallbackLater);
  324. }
  325. void setChunkData(const void* const data, const std::size_t dataSize) override
  326. {
  327. CARLA_SAFE_ASSERT_RETURN(pData->options & PLUGIN_OPTION_USE_CHUNKS,);
  328. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  329. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  330. CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);
  331. if (loadJuceSaveFormat(data, dataSize))
  332. return;
  333. if (fLastChunk != nullptr)
  334. std::free(fLastChunk);
  335. fLastChunk = std::malloc(dataSize);
  336. CARLA_SAFE_ASSERT_RETURN(fLastChunk != nullptr,);
  337. std::memcpy(fLastChunk, data, dataSize);
  338. {
  339. const ScopedSingleProcessLocker spl(this, true);
  340. const CarlaScopedValueSetter<pthread_t> svs(fChangingValuesThread, pthread_self(), kNullThread);
  341. dispatcher(effSetChunk, 0 /* bank */, static_cast<intptr_t>(dataSize), fLastChunk);
  342. }
  343. // simulate an updateDisplay callback
  344. handleAudioMasterCallback(audioMasterUpdateDisplay, 0, 0, nullptr, 0.0f);
  345. pData->updateParameterValues(this, true, true, false);
  346. }
  347. void setProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  348. {
  349. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  350. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->prog.count),);
  351. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
  352. if (index >= 0)
  353. {
  354. try {
  355. dispatcher(effBeginSetProgram);
  356. } CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",);
  357. {
  358. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  359. const CarlaScopedValueSetter<pthread_t> svs(fChangingValuesThread, pthread_self(), kNullThread);
  360. try {
  361. dispatcher(effSetProgram, 0, index);
  362. } CARLA_SAFE_EXCEPTION("effSetProgram");
  363. }
  364. try {
  365. dispatcher(effEndSetProgram);
  366. } CARLA_SAFE_EXCEPTION("effEndSetProgram");
  367. }
  368. CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  369. }
  370. void setProgramRT(const uint32_t uindex, const bool sendCallbackLater) noexcept override
  371. {
  372. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  373. CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,);
  374. try {
  375. dispatcher(effBeginSetProgram);
  376. } CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",);
  377. try {
  378. dispatcher(effSetProgram, 0, static_cast<intptr_t>(uindex));
  379. } CARLA_SAFE_EXCEPTION("effSetProgram");
  380. try {
  381. dispatcher(effEndSetProgram);
  382. } CARLA_SAFE_EXCEPTION("effEndSetProgram");
  383. CarlaPlugin::setProgramRT(uindex, sendCallbackLater);
  384. }
  385. // -------------------------------------------------------------------
  386. // Set ui stuff
  387. void setCustomUITitle(const char* const title) noexcept override
  388. {
  389. if (fUI.window != nullptr)
  390. {
  391. try {
  392. fUI.window->setTitle(title);
  393. } CARLA_SAFE_EXCEPTION("set custom ui title");
  394. }
  395. CarlaPlugin::setCustomUITitle(title);
  396. }
  397. void showCustomUI(const bool yesNo) override
  398. {
  399. if (fUI.isVisible == yesNo)
  400. return;
  401. if (yesNo)
  402. {
  403. CarlaString uiTitle;
  404. if (pData->uiTitle.isNotEmpty())
  405. {
  406. uiTitle = pData->uiTitle;
  407. }
  408. else
  409. {
  410. uiTitle = pData->name;
  411. uiTitle += " (GUI)";
  412. }
  413. intptr_t value = 0;
  414. if (fUI.window == nullptr)
  415. {
  416. const char* msg = nullptr;
  417. const EngineOptions& opts(pData->engine->getOptions());
  418. #if defined(CARLA_OS_MAC)
  419. fUI.window = CarlaPluginUI::newCocoa(this, opts.frontendWinId, opts.pluginsAreStandalone, false);
  420. #elif defined(CARLA_OS_WIN)
  421. fUI.window = CarlaPluginUI::newWindows(this, opts.frontendWinId, opts.pluginsAreStandalone, false);
  422. #elif defined(HAVE_X11)
  423. fUI.window = CarlaPluginUI::newX11(this, opts.frontendWinId, opts.pluginsAreStandalone, false, false);
  424. #else
  425. msg = "Unsupported UI type";
  426. #endif
  427. if (fUI.window == nullptr)
  428. return pData->engine->callback(true, true,
  429. ENGINE_CALLBACK_UI_STATE_CHANGED,
  430. pData->id,
  431. -1,
  432. 0, 0, 0.0f,
  433. msg);
  434. fUI.window->setTitle(uiTitle.buffer());
  435. #ifdef HAVE_X11
  436. value = (intptr_t)fUI.window->getDisplay();
  437. #endif
  438. #ifndef CARLA_OS_MAC
  439. // inform plugin of what UI scale we use
  440. dispatcher(effVendorSpecific,
  441. CCONST('P', 'r', 'e', 'S'),
  442. CCONST('A', 'e', 'C', 's'),
  443. nullptr,
  444. opts.uiScale);
  445. #endif
  446. // NOTE: there are far too many broken VST2 plugins, don't bother checking return value
  447. if (dispatcher(effEditOpen, 0, value, fUI.window->getPtr()) != 0 || true)
  448. {
  449. fUI.isOpen = true;
  450. ERect* vstRect = nullptr;
  451. dispatcher(effEditGetRect, 0, 0, &vstRect);
  452. if (vstRect != nullptr)
  453. {
  454. const int width(vstRect->right - vstRect->left);
  455. const int height(vstRect->bottom - vstRect->top);
  456. CARLA_SAFE_ASSERT_INT2(width > 1 && height > 1, width, height);
  457. if (width > 1 && height > 1)
  458. fUI.window->setSize(static_cast<uint>(width), static_cast<uint>(height), true, true);
  459. }
  460. }
  461. else
  462. {
  463. delete fUI.window;
  464. fUI.window = nullptr;
  465. carla_stderr2("Plugin refused to open its own UI");
  466. return pData->engine->callback(true, true,
  467. ENGINE_CALLBACK_UI_STATE_CHANGED,
  468. pData->id,
  469. -1,
  470. 0, 0, 0.0f,
  471. "Plugin refused to open its own UI");
  472. }
  473. }
  474. fUI.window->show();
  475. fUI.isVisible = true;
  476. }
  477. else
  478. {
  479. fUI.isVisible = false;
  480. if (fUI.window != nullptr)
  481. fUI.window->hide();
  482. if (fUI.isEmbed)
  483. {
  484. fUI.isEmbed = false;
  485. fUI.isOpen = false;
  486. dispatcher(effEditClose);
  487. }
  488. }
  489. }
  490. void* embedCustomUI(void* const ptr) override
  491. {
  492. CARLA_SAFE_ASSERT_RETURN(fUI.window == nullptr, nullptr);
  493. fUI.isEmbed = true;
  494. fUI.isOpen = true;
  495. fUI.isVisible = true;
  496. #ifndef CARLA_OS_MAC
  497. // inform plugin of what UI scale we use
  498. dispatcher(effVendorSpecific,
  499. CCONST('P', 'r', 'e', 'S'),
  500. CCONST('A', 'e', 'C', 's'),
  501. nullptr,
  502. pData->engine->getOptions().uiScale);
  503. #endif
  504. dispatcher(effEditOpen, 0, 0, ptr);
  505. ERect* vstRect = nullptr;
  506. dispatcher(effEditGetRect, 0, 0, &vstRect);
  507. if (vstRect != nullptr)
  508. {
  509. const int width = vstRect->right - vstRect->left;
  510. const int height = vstRect->bottom - vstRect->top;
  511. CARLA_SAFE_ASSERT_INT2(width > 1 && height > 1, width, height);
  512. if (width > 1 && height > 1)
  513. pData->engine->callback(true, true,
  514. ENGINE_CALLBACK_EMBED_UI_RESIZED,
  515. pData->id, width, height,
  516. 0, 0.0f, nullptr);
  517. }
  518. return nullptr;
  519. }
  520. void idle() override
  521. {
  522. if (fNeedIdle)
  523. {
  524. const CarlaScopedValueSetter<pthread_t> svs(fIdleThread, pthread_self(), kNullThread);
  525. dispatcher(effIdle);
  526. }
  527. CarlaPlugin::idle();
  528. }
  529. void uiIdle() override
  530. {
  531. if (fUI.isVisible)
  532. dispatcher(effEditIdle);
  533. if (fUI.window != nullptr)
  534. fUI.window->idle();
  535. CarlaPlugin::uiIdle();
  536. }
  537. // -------------------------------------------------------------------
  538. // Plugin state
  539. void reload() override
  540. {
  541. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  542. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  543. carla_debug("CarlaPluginVST2::reload() - start");
  544. // Safely disable plugin for reload
  545. const ScopedDisabler sd(this);
  546. const CarlaScopedValueSetter<bool> svs(fIsInitializing, fIsInitializing, false);
  547. if (pData->active)
  548. deactivate();
  549. clearBuffers();
  550. uint32_t aIns, aOuts, mIns, mOuts, params;
  551. bool needsCtrlIn, needsCtrlOut;
  552. needsCtrlIn = needsCtrlOut = false;
  553. aIns = (fEffect->numInputs > 0) ? static_cast<uint32_t>(fEffect->numInputs) : 0;
  554. aOuts = (fEffect->numOutputs > 0) ? static_cast<uint32_t>(fEffect->numOutputs) : 0;
  555. params = (fEffect->numParams > 0) ? static_cast<uint32_t>(fEffect->numParams) : 0;
  556. if (hasMidiInput())
  557. {
  558. mIns = 1;
  559. needsCtrlIn = true;
  560. }
  561. else
  562. mIns = 0;
  563. if (hasMidiOutput())
  564. {
  565. mOuts = 1;
  566. needsCtrlOut = true;
  567. }
  568. else
  569. mOuts = 0;
  570. if (aIns > 0)
  571. {
  572. pData->audioIn.createNew(aIns);
  573. }
  574. if (aOuts > 0)
  575. {
  576. pData->audioOut.createNew(aOuts);
  577. fAudioOutBuffers = new float*[aOuts];
  578. needsCtrlIn = true;
  579. for (uint32_t i=0; i < aOuts; ++i)
  580. fAudioOutBuffers[i] = nullptr;
  581. }
  582. if (params > 0)
  583. {
  584. pData->param.createNew(params, false);
  585. needsCtrlIn = true;
  586. }
  587. const EngineProcessMode processMode = pData->engine->getProccessMode();
  588. const uint portNameSize = pData->engine->getMaxPortNameSize();
  589. CarlaString portName;
  590. // Audio Ins
  591. for (uint32_t j=0; j < aIns; ++j)
  592. {
  593. portName.clear();
  594. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  595. {
  596. portName = pData->name;
  597. portName += ":";
  598. }
  599. if (aIns > 1)
  600. {
  601. portName += "input_";
  602. portName += CarlaString(j+1);
  603. }
  604. else
  605. portName += "input";
  606. portName.truncate(portNameSize);
  607. pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
  608. pData->audioIn.ports[j].rindex = j;
  609. }
  610. // Audio Outs
  611. for (uint32_t j=0; j < aOuts; ++j)
  612. {
  613. portName.clear();
  614. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  615. {
  616. portName = pData->name;
  617. portName += ":";
  618. }
  619. if (aOuts > 1)
  620. {
  621. portName += "output_";
  622. portName += CarlaString(j+1);
  623. }
  624. else
  625. portName += "output";
  626. portName.truncate(portNameSize);
  627. pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
  628. pData->audioOut.ports[j].rindex = j;
  629. }
  630. for (uint32_t j=0; j < params; ++j)
  631. {
  632. const int32_t ij = static_cast<int32_t>(j);
  633. pData->param.data[j].type = PARAMETER_INPUT;
  634. pData->param.data[j].index = ij;
  635. pData->param.data[j].rindex = ij;
  636. float min, max, def, step, stepSmall, stepLarge;
  637. VstParameterProperties prop;
  638. carla_zeroStruct(prop);
  639. if (pData->hints & PLUGIN_HAS_COCKOS_EXTENSIONS)
  640. {
  641. double vrange[2] = { 0.0, 1.0 };
  642. bool isInteger = false;
  643. if (static_cast<uintptr_t>(dispatcher(effVendorSpecific, static_cast<int32_t>(0xdeadbef0), ij, vrange)) >= 0xbeef)
  644. {
  645. min = static_cast<float>(vrange[0]);
  646. max = static_cast<float>(vrange[1]);
  647. if (min > max)
  648. {
  649. carla_stderr2("WARNING - Broken plugin parameter min > max (with cockos extensions)");
  650. min = max - 0.1f;
  651. }
  652. else if (carla_isEqual(min, max))
  653. {
  654. carla_stderr2("WARNING - Broken plugin parameter min == max (with cockos extensions)");
  655. max = min + 0.1f;
  656. }
  657. // only use values as integer if we have a proper range
  658. if (max - min >= 1.0f)
  659. isInteger = dispatcher(effVendorSpecific, kVstParameterUsesIntStep, ij) >= 0xbeef;
  660. }
  661. else
  662. {
  663. min = 0.0f;
  664. max = 1.0f;
  665. }
  666. if (isInteger)
  667. {
  668. step = 1.0f;
  669. stepSmall = 1.0f;
  670. stepLarge = 10.0f;
  671. }
  672. else
  673. {
  674. const float range = max - min;
  675. step = range/100.0f;
  676. stepSmall = range/1000.0f;
  677. stepLarge = range/10.0f;
  678. }
  679. }
  680. else if (dispatcher(effGetParameterProperties, ij, 0, &prop) == 1)
  681. {
  682. #if 0
  683. if (prop.flags & kVstParameterUsesIntegerMinMax)
  684. {
  685. min = static_cast<float>(prop.minInteger);
  686. max = static_cast<float>(prop.maxInteger);
  687. if (min > max)
  688. {
  689. carla_stderr2("WARNING - Broken plugin parameter min > max");
  690. min = max - 0.1f;
  691. }
  692. else if (carla_isEqual(min, max))
  693. {
  694. carla_stderr2("WARNING - Broken plugin parameter min == max");
  695. max = min + 0.1f;
  696. }
  697. }
  698. else
  699. #endif
  700. {
  701. min = 0.0f;
  702. max = 1.0f;
  703. }
  704. /**/ if (prop.flags & kVstParameterIsSwitch)
  705. {
  706. step = max - min;
  707. stepSmall = step;
  708. stepLarge = step;
  709. pData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  710. }
  711. else if (prop.flags & kVstParameterUsesIntStep)
  712. {
  713. step = static_cast<float>(prop.stepInteger);
  714. stepSmall = static_cast<float>(prop.stepInteger)/10.0f;
  715. stepLarge = static_cast<float>(prop.largeStepInteger);
  716. }
  717. else if (prop.flags & kVstParameterUsesFloatStep)
  718. {
  719. step = prop.stepFloat;
  720. stepSmall = prop.smallStepFloat;
  721. stepLarge = prop.largeStepFloat;
  722. }
  723. else
  724. {
  725. const float range = max - min;
  726. step = range/100.0f;
  727. stepSmall = range/1000.0f;
  728. stepLarge = range/10.0f;
  729. }
  730. if (prop.flags & kVstParameterCanRamp)
  731. pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  732. }
  733. else
  734. {
  735. min = 0.0f;
  736. max = 1.0f;
  737. step = 0.001f;
  738. stepSmall = 0.0001f;
  739. stepLarge = 0.1f;
  740. }
  741. pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  742. pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  743. if ((pData->hints & PLUGIN_USES_OLD_VSTSDK) != 0 || dispatcher(effCanBeAutomated, ij) == 1)
  744. {
  745. pData->param.data[j].hints |= PARAMETER_IS_AUTOMATABLE;
  746. if ((prop.flags & (kVstParameterIsSwitch|kVstParameterUsesIntStep)) == 0x0)
  747. pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED;
  748. }
  749. // no such thing as VST default parameters
  750. def = fEffect->getParameter(fEffect, ij);
  751. if (def < min)
  752. def = min;
  753. else if (def > max)
  754. def = max;
  755. pData->param.ranges[j].min = min;
  756. pData->param.ranges[j].max = max;
  757. pData->param.ranges[j].def = def;
  758. pData->param.ranges[j].step = step;
  759. pData->param.ranges[j].stepSmall = stepSmall;
  760. pData->param.ranges[j].stepLarge = stepLarge;
  761. }
  762. if (needsCtrlIn)
  763. {
  764. portName.clear();
  765. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  766. {
  767. portName = pData->name;
  768. portName += ":";
  769. }
  770. portName += "events-in";
  771. portName.truncate(portNameSize);
  772. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  773. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  774. pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
  775. #endif
  776. }
  777. if (needsCtrlOut)
  778. {
  779. portName.clear();
  780. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  781. {
  782. portName = pData->name;
  783. portName += ":";
  784. }
  785. portName += "events-out";
  786. portName.truncate(portNameSize);
  787. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  788. }
  789. // plugin hints
  790. const intptr_t vstCategory = dispatcher(effGetPlugCategory);
  791. pData->hints = 0x0;
  792. if (vstCategory == kPlugCategSynth || vstCategory == kPlugCategGenerator)
  793. pData->hints |= PLUGIN_IS_SYNTH;
  794. if (fEffect->flags & effFlagsHasEditor)
  795. {
  796. #if defined(CARLA_OS_MAC) && ! defined(CARLA_OS_64BIT)
  797. if (static_cast<uintptr_t>(dispatcher(effCanDo, 0, 0, const_cast<char*>("hasCockosViewAsConfig")) & 0xffff0000) == 0xbeef0000)
  798. #endif
  799. {
  800. pData->hints |= PLUGIN_HAS_CUSTOM_UI;
  801. pData->hints |= PLUGIN_HAS_CUSTOM_EMBED_UI;
  802. }
  803. pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
  804. }
  805. if (dispatcher(effGetVstVersion) < kVstVersion)
  806. pData->hints |= PLUGIN_USES_OLD_VSTSDK;
  807. if ((fEffect->flags & effFlagsCanReplacing) != 0 && fEffect->processReplacing != fEffect->process)
  808. pData->hints |= PLUGIN_CAN_PROCESS_REPLACING;
  809. if (static_cast<uintptr_t>(dispatcher(effCanDo, 0, 0, const_cast<char*>("hasCockosExtensions"))) == 0xbeef0000)
  810. pData->hints |= PLUGIN_HAS_COCKOS_EXTENSIONS;
  811. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  812. pData->hints |= PLUGIN_CAN_DRYWET;
  813. if (aOuts > 0)
  814. pData->hints |= PLUGIN_CAN_VOLUME;
  815. if (aOuts >= 2 && aOuts % 2 == 0)
  816. pData->hints |= PLUGIN_CAN_BALANCE;
  817. // extra plugin hints
  818. pData->extraHints = 0x0;
  819. if (mIns > 0)
  820. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  821. if (mOuts > 0)
  822. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
  823. // dummy pre-start to get latency and wantEvents() on old plugins
  824. {
  825. activate();
  826. deactivate();
  827. }
  828. // check initial latency
  829. const uint32_t latency = (fEffect->initialDelay > 0) ? static_cast<uint32_t>(fEffect->initialDelay) : 0;
  830. if (latency != 0)
  831. {
  832. pData->client->setLatency(latency);
  833. #ifndef BUILD_BRIDGE
  834. pData->latency.recreateBuffers(std::max(aIns, aOuts), latency);
  835. #endif
  836. }
  837. bufferSizeChanged(pData->engine->getBufferSize());
  838. reloadPrograms(true);
  839. if (pData->active)
  840. activate();
  841. carla_debug("CarlaPluginVST2::reload() - end");
  842. }
  843. void reloadPrograms(const bool doInit) override
  844. {
  845. carla_debug("CarlaPluginVST2::reloadPrograms(%s)", bool2str(doInit));
  846. const uint32_t oldCount = pData->prog.count;
  847. const int32_t current = pData->prog.current;
  848. // Delete old programs
  849. pData->prog.clear();
  850. // Query new programs
  851. uint32_t newCount = (fEffect->numPrograms > 0) ? static_cast<uint32_t>(fEffect->numPrograms) : 0;
  852. if (newCount > 0)
  853. {
  854. pData->prog.createNew(newCount);
  855. // Update names
  856. for (int32_t i=0; i < fEffect->numPrograms; ++i)
  857. {
  858. char strBuf[STR_MAX+1] = { '\0' };
  859. if (dispatcher(effGetProgramNameIndexed, i, 0, strBuf) != 1)
  860. {
  861. // program will be [re-]changed later
  862. dispatcher(effSetProgram, 0, i);
  863. dispatcher(effGetProgramName, 0, 0, strBuf);
  864. }
  865. pData->prog.names[i] = carla_strdup(strBuf);
  866. }
  867. }
  868. if (doInit)
  869. {
  870. if (newCount > 0)
  871. setProgram(0, false, false, false, true);
  872. else
  873. dispatcher(effSetProgram, 0, 0);
  874. }
  875. else
  876. {
  877. // Check if current program is invalid
  878. bool programChanged = false;
  879. if (newCount == oldCount+1)
  880. {
  881. // one program added, probably created by user
  882. pData->prog.current = static_cast<int32_t>(oldCount);
  883. programChanged = true;
  884. }
  885. else if (current < 0 && newCount > 0)
  886. {
  887. // programs exist now, but not before
  888. pData->prog.current = 0;
  889. programChanged = true;
  890. }
  891. else if (current >= 0 && newCount == 0)
  892. {
  893. // programs existed before, but not anymore
  894. pData->prog.current = -1;
  895. programChanged = true;
  896. }
  897. else if (current >= static_cast<int32_t>(newCount))
  898. {
  899. // current program > count
  900. pData->prog.current = 0;
  901. programChanged = true;
  902. }
  903. else
  904. {
  905. // no change
  906. pData->prog.current = current;
  907. }
  908. if (programChanged)
  909. {
  910. setProgram(pData->prog.current, true, true, true, false);
  911. }
  912. else
  913. {
  914. // Program was changed during update, re-set it
  915. if (pData->prog.current >= 0)
  916. dispatcher(effSetProgram, 0, pData->prog.current);
  917. }
  918. pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
  919. }
  920. }
  921. // -------------------------------------------------------------------
  922. // Plugin processing
  923. void activate() noexcept override
  924. {
  925. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  926. const int32_t iBufferSize = static_cast<int32_t>(fBufferSize);
  927. const float fSampleRate = static_cast<float>(pData->engine->getSampleRate());
  928. dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32);
  929. dispatcher(effSetBlockSizeAndSampleRate, 0, iBufferSize, nullptr, fSampleRate);
  930. dispatcher(effSetSampleRate, 0, 0, nullptr, fSampleRate);
  931. dispatcher(effSetBlockSize, 0, iBufferSize);
  932. try {
  933. dispatcher(effMainsChanged, 0, 1);
  934. } CARLA_SAFE_EXCEPTION("effMainsChanged on");
  935. try {
  936. dispatcher(effStartProcess, 0, 0);
  937. } CARLA_SAFE_EXCEPTION("effStartProcess on");
  938. fFirstActive = true;
  939. }
  940. void deactivate() noexcept override
  941. {
  942. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
  943. try {
  944. dispatcher(effStopProcess);
  945. } CARLA_SAFE_EXCEPTION("effStartProcess off");
  946. try {
  947. dispatcher(effMainsChanged);
  948. } CARLA_SAFE_EXCEPTION("effMainsChanged off");
  949. }
  950. void process(const float* const* const audioIn,
  951. float** const audioOut,
  952. const float* const* const cvIn,
  953. float** const,
  954. const uint32_t frames) override
  955. {
  956. const CarlaScopedValueSetter<pthread_t> svs(fProcThread, pthread_self(), kNullThread);
  957. // --------------------------------------------------------------------------------------------------------
  958. // Check if active
  959. if (! pData->active)
  960. {
  961. // disable any output sound
  962. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  963. carla_zeroFloats(audioOut[i], frames);
  964. return;
  965. }
  966. fMidiEventCount = 0;
  967. carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
  968. // --------------------------------------------------------------------------------------------------------
  969. // Check if needs reset
  970. if (pData->needsReset)
  971. {
  972. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  973. {
  974. fMidiEventCount = MAX_MIDI_CHANNELS*2;
  975. for (uint8_t i=0; i < MAX_MIDI_CHANNELS; ++i)
  976. {
  977. fMidiEvents[i].type = kVstMidiType;
  978. fMidiEvents[i].byteSize = kVstMidiEventSize;
  979. fMidiEvents[i].midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
  980. fMidiEvents[i].midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  981. fMidiEvents[MAX_MIDI_CHANNELS + i].type = kVstMidiType;
  982. fMidiEvents[MAX_MIDI_CHANNELS + i].byteSize = kVstMidiEventSize;
  983. fMidiEvents[MAX_MIDI_CHANNELS + i].midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (i & MIDI_CHANNEL_BIT));
  984. fMidiEvents[MAX_MIDI_CHANNELS + i].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  985. }
  986. }
  987. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  988. {
  989. fMidiEventCount = MAX_MIDI_NOTE;
  990. for (uint8_t i=0; i < MAX_MIDI_NOTE; ++i)
  991. {
  992. fMidiEvents[i].type = kVstMidiType;
  993. fMidiEvents[i].byteSize = kVstMidiEventSize;
  994. fMidiEvents[i].midiData[0] = char(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
  995. fMidiEvents[i].midiData[1] = char(i);
  996. }
  997. }
  998. pData->needsReset = false;
  999. }
  1000. // --------------------------------------------------------------------------------------------------------
  1001. // Set TimeInfo
  1002. const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
  1003. fTimeInfo.flags = 0;
  1004. if (fFirstActive || ! fLastTimeInfo.compareIgnoringRollingFrames(timeInfo, frames))
  1005. {
  1006. fTimeInfo.flags |= kVstTransportChanged;
  1007. fLastTimeInfo = timeInfo;
  1008. }
  1009. if (timeInfo.playing)
  1010. fTimeInfo.flags |= kVstTransportPlaying;
  1011. fTimeInfo.samplePos = double(timeInfo.frame);
  1012. fTimeInfo.sampleRate = pData->engine->getSampleRate();
  1013. if (timeInfo.usecs != 0)
  1014. {
  1015. fTimeInfo.nanoSeconds = double(timeInfo.usecs)/1000.0;
  1016. fTimeInfo.flags |= kVstNanosValid;
  1017. }
  1018. if (timeInfo.bbt.valid)
  1019. {
  1020. CARLA_SAFE_ASSERT_INT(timeInfo.bbt.bar > 0, timeInfo.bbt.bar);
  1021. CARLA_SAFE_ASSERT_INT(timeInfo.bbt.beat > 0, timeInfo.bbt.beat);
  1022. const double ppqBar = static_cast<double>(timeInfo.bbt.beatsPerBar) * (timeInfo.bbt.bar - 1);
  1023. // const double ppqBeat = static_cast<double>(timeInfo.bbt.beat - 1);
  1024. // const double ppqTick = timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat;
  1025. // PPQ Pos
  1026. fTimeInfo.ppqPos = fTimeInfo.samplePos / (fTimeInfo.sampleRate * 60 / timeInfo.bbt.beatsPerMinute);
  1027. // fTimeInfo.ppqPos = ppqBar + ppqBeat + ppqTick;
  1028. fTimeInfo.flags |= kVstPpqPosValid;
  1029. // Tempo
  1030. fTimeInfo.tempo = timeInfo.bbt.beatsPerMinute;
  1031. fTimeInfo.flags |= kVstTempoValid;
  1032. // Bars
  1033. fTimeInfo.barStartPos = ppqBar;
  1034. fTimeInfo.flags |= kVstBarsValid;
  1035. // Time Signature
  1036. fTimeInfo.timeSigNumerator = static_cast<int32_t>(timeInfo.bbt.beatsPerBar + 0.5f);
  1037. fTimeInfo.timeSigDenominator = static_cast<int32_t>(timeInfo.bbt.beatType + 0.5f);
  1038. fTimeInfo.flags |= kVstTimeSigValid;
  1039. }
  1040. else
  1041. {
  1042. // Tempo
  1043. fTimeInfo.tempo = 120.0;
  1044. fTimeInfo.flags |= kVstTempoValid;
  1045. // Time Signature
  1046. fTimeInfo.timeSigNumerator = 4;
  1047. fTimeInfo.timeSigDenominator = 4;
  1048. fTimeInfo.flags |= kVstTimeSigValid;
  1049. // Missing info
  1050. fTimeInfo.ppqPos = 0.0;
  1051. fTimeInfo.barStartPos = 0.0;
  1052. }
  1053. // --------------------------------------------------------------------------------------------------------
  1054. // Event Input and Processing
  1055. if (pData->event.portIn != nullptr)
  1056. {
  1057. // ----------------------------------------------------------------------------------------------------
  1058. // MIDI Input (External)
  1059. if (pData->extNotes.mutex.tryLock())
  1060. {
  1061. ExternalMidiNote note = { -1, 0, 0 };
  1062. for (; fMidiEventCount < kPluginMaxMidiEvents*2 && ! pData->extNotes.data.isEmpty();)
  1063. {
  1064. note = pData->extNotes.data.getFirst(note, true);
  1065. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  1066. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1067. vstMidiEvent.type = kVstMidiType;
  1068. vstMidiEvent.byteSize = kVstMidiEventSize;
  1069. vstMidiEvent.midiData[0] = char((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
  1070. vstMidiEvent.midiData[1] = char(note.note);
  1071. vstMidiEvent.midiData[2] = char(note.velo);
  1072. }
  1073. pData->extNotes.mutex.unlock();
  1074. } // End of MIDI Input (External)
  1075. // ----------------------------------------------------------------------------------------------------
  1076. // Event Input (System)
  1077. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1078. bool allNotesOffSent = false;
  1079. #endif
  1080. bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
  1081. uint32_t startTime = 0;
  1082. uint32_t timeOffset = 0;
  1083. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1084. if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr)
  1085. pData->event.cvSourcePorts->initPortBuffers(cvIn, frames, isSampleAccurate, pData->event.portIn);
  1086. #endif
  1087. for (uint32_t i=0, numEvents = pData->event.portIn->getEventCount(); i < numEvents; ++i)
  1088. {
  1089. EngineEvent& event(pData->event.portIn->getEvent(i));
  1090. uint32_t eventTime = event.time;
  1091. CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime < frames, eventTime, frames);
  1092. if (eventTime < timeOffset)
  1093. {
  1094. carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
  1095. eventTime, timeOffset, pData->name);
  1096. eventTime = timeOffset;
  1097. }
  1098. if (isSampleAccurate && eventTime > timeOffset)
  1099. {
  1100. if (processSingle(audioIn, audioOut, eventTime - timeOffset, timeOffset))
  1101. {
  1102. startTime = 0;
  1103. timeOffset = eventTime;
  1104. if (fMidiEventCount > 0)
  1105. {
  1106. carla_zeroStructs(fMidiEvents, fMidiEventCount);
  1107. fMidiEventCount = 0;
  1108. }
  1109. }
  1110. else
  1111. startTime += timeOffset;
  1112. }
  1113. switch (event.type)
  1114. {
  1115. case kEngineEventTypeNull:
  1116. break;
  1117. case kEngineEventTypeControl: {
  1118. EngineControlEvent& ctrlEvent(event.ctrl);
  1119. switch (ctrlEvent.type)
  1120. {
  1121. case kEngineControlEventTypeNull:
  1122. break;
  1123. case kEngineControlEventTypeParameter: {
  1124. float value;
  1125. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1126. // non-midi
  1127. if (event.channel == kEngineEventNonMidiChannel)
  1128. {
  1129. const uint32_t k = ctrlEvent.param;
  1130. CARLA_SAFE_ASSERT_CONTINUE(k < pData->param.count);
  1131. ctrlEvent.handled = true;
  1132. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  1133. setParameterValueRT(k, value, event.time, true);
  1134. continue;
  1135. }
  1136. // Control backend stuff
  1137. if (event.channel == pData->ctrlChannel)
  1138. {
  1139. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  1140. {
  1141. ctrlEvent.handled = true;
  1142. value = ctrlEvent.normalizedValue;
  1143. setDryWetRT(value, true);
  1144. }
  1145. else if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  1146. {
  1147. ctrlEvent.handled = true;
  1148. value = ctrlEvent.normalizedValue*127.0f/100.0f;
  1149. setVolumeRT(value, true);
  1150. }
  1151. else if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  1152. {
  1153. float left, right;
  1154. value = ctrlEvent.normalizedValue/0.5f - 1.0f;
  1155. if (value < 0.0f)
  1156. {
  1157. left = -1.0f;
  1158. right = (value*2.0f)+1.0f;
  1159. }
  1160. else if (value > 0.0f)
  1161. {
  1162. left = (value*2.0f)-1.0f;
  1163. right = 1.0f;
  1164. }
  1165. else
  1166. {
  1167. left = -1.0f;
  1168. right = 1.0f;
  1169. }
  1170. ctrlEvent.handled = true;
  1171. setBalanceLeftRT(left, true);
  1172. setBalanceRightRT(right, true);
  1173. }
  1174. }
  1175. #endif
  1176. // Control plugin parameters
  1177. uint32_t k;
  1178. for (k=0; k < pData->param.count; ++k)
  1179. {
  1180. if (pData->param.data[k].midiChannel != event.channel)
  1181. continue;
  1182. if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
  1183. continue;
  1184. if (pData->param.data[k].type != PARAMETER_INPUT)
  1185. continue;
  1186. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMATABLE) == 0)
  1187. continue;
  1188. ctrlEvent.handled = true;
  1189. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  1190. setParameterValueRT(k, value, event.time, true);
  1191. }
  1192. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
  1193. {
  1194. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1195. continue;
  1196. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1197. carla_zeroStruct(vstMidiEvent);
  1198. vstMidiEvent.type = kVstMidiType;
  1199. vstMidiEvent.byteSize = kVstMidiEventSize;
  1200. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1201. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1202. vstMidiEvent.midiData[1] = char(ctrlEvent.param);
  1203. vstMidiEvent.midiData[2] = char(ctrlEvent.normalizedValue*127.0f + 0.5f);
  1204. }
  1205. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1206. if (! ctrlEvent.handled)
  1207. checkForMidiLearn(event);
  1208. #endif
  1209. break;
  1210. } // case kEngineControlEventTypeParameter
  1211. case kEngineControlEventTypeMidiBank:
  1212. if ((pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) != 0)
  1213. {
  1214. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1215. continue;
  1216. VstMidiEvent& vstMidiEvent_MSB(fMidiEvents[fMidiEventCount++]);
  1217. carla_zeroStruct(vstMidiEvent_MSB);
  1218. vstMidiEvent_MSB.type = kVstMidiType;
  1219. vstMidiEvent_MSB.byteSize = kVstMidiEventSize;
  1220. vstMidiEvent_MSB.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : event.time);
  1221. vstMidiEvent_MSB.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1222. vstMidiEvent_MSB.midiData[1] = MIDI_CONTROL_BANK_SELECT;
  1223. vstMidiEvent_MSB.midiData[2] = 0;
  1224. VstMidiEvent& vstMidiEvent_LSB(fMidiEvents[fMidiEventCount++]);
  1225. carla_zeroStruct(vstMidiEvent_LSB);
  1226. vstMidiEvent_LSB.type = kVstMidiType;
  1227. vstMidiEvent_LSB.byteSize = kVstMidiEventSize;
  1228. vstMidiEvent_LSB.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1229. vstMidiEvent_LSB.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1230. vstMidiEvent_LSB.midiData[1] = MIDI_CONTROL_BANK_SELECT__LSB;
  1231. vstMidiEvent_LSB.midiData[2] = char(ctrlEvent.param);
  1232. }
  1233. break;
  1234. case kEngineControlEventTypeMidiProgram:
  1235. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1236. {
  1237. if (ctrlEvent.param < pData->prog.count)
  1238. {
  1239. setProgramRT(ctrlEvent.param, true);
  1240. break;
  1241. }
  1242. }
  1243. else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
  1244. {
  1245. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1246. continue;
  1247. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1248. carla_zeroStruct(vstMidiEvent);
  1249. vstMidiEvent.type = kVstMidiType;
  1250. vstMidiEvent.byteSize = kVstMidiEventSize;
  1251. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1252. vstMidiEvent.midiData[0] = char(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1253. vstMidiEvent.midiData[1] = char(ctrlEvent.param);
  1254. }
  1255. break;
  1256. case kEngineControlEventTypeAllSoundOff:
  1257. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1258. {
  1259. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1260. continue;
  1261. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1262. carla_zeroStruct(vstMidiEvent);
  1263. vstMidiEvent.type = kVstMidiType;
  1264. vstMidiEvent.byteSize = kVstMidiEventSize;
  1265. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1266. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1267. vstMidiEvent.midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  1268. }
  1269. break;
  1270. case kEngineControlEventTypeAllNotesOff:
  1271. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1272. {
  1273. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1274. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  1275. {
  1276. allNotesOffSent = true;
  1277. postponeRtAllNotesOff();
  1278. }
  1279. #endif
  1280. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1281. continue;
  1282. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1283. carla_zeroStruct(vstMidiEvent);
  1284. vstMidiEvent.type = kVstMidiType;
  1285. vstMidiEvent.byteSize = kVstMidiEventSize;
  1286. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1287. vstMidiEvent.midiData[0] = char(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT));
  1288. vstMidiEvent.midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  1289. }
  1290. break;
  1291. } // switch (ctrlEvent.type)
  1292. break;
  1293. } // case kEngineEventTypeControl
  1294. case kEngineEventTypeMidi: {
  1295. if (fMidiEventCount >= kPluginMaxMidiEvents*2)
  1296. continue;
  1297. const EngineMidiEvent& midiEvent(event.midi);
  1298. if (midiEvent.size > 3)
  1299. continue;
  1300. #ifdef CARLA_PROPER_CPP11_SUPPORT
  1301. static_assert(3 <= EngineMidiEvent::kDataSize, "Incorrect data");
  1302. #endif
  1303. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  1304. if ((status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON) && (pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES))
  1305. continue;
  1306. if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  1307. continue;
  1308. if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  1309. continue;
  1310. if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  1311. continue;
  1312. if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  1313. continue;
  1314. // Fix bad note-off
  1315. if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
  1316. status = MIDI_STATUS_NOTE_OFF;
  1317. VstMidiEvent& vstMidiEvent(fMidiEvents[fMidiEventCount++]);
  1318. carla_zeroStruct(vstMidiEvent);
  1319. vstMidiEvent.type = kVstMidiType;
  1320. vstMidiEvent.byteSize = kVstMidiEventSize;
  1321. vstMidiEvent.deltaFrames = static_cast<int32_t>(isSampleAccurate ? startTime : eventTime);
  1322. vstMidiEvent.midiData[0] = char(status | (event.channel & MIDI_CHANNEL_BIT));
  1323. vstMidiEvent.midiData[1] = char(midiEvent.size >= 2 ? midiEvent.data[1] : 0);
  1324. vstMidiEvent.midiData[2] = char(midiEvent.size >= 3 ? midiEvent.data[2] : 0);
  1325. if (status == MIDI_STATUS_NOTE_ON)
  1326. {
  1327. pData->postponeNoteOnRtEvent(true, event.channel, midiEvent.data[1], midiEvent.data[2]);
  1328. }
  1329. else if (status == MIDI_STATUS_NOTE_OFF)
  1330. {
  1331. pData->postponeNoteOffRtEvent(true, event.channel, midiEvent.data[1]);
  1332. }
  1333. } break;
  1334. } // switch (event.type)
  1335. }
  1336. pData->postRtEvents.trySplice();
  1337. if (frames > timeOffset)
  1338. processSingle(audioIn, audioOut, frames - timeOffset, timeOffset);
  1339. } // End of Event Input and Processing
  1340. // --------------------------------------------------------------------------------------------------------
  1341. // Plugin processing (no events)
  1342. else
  1343. {
  1344. processSingle(audioIn, audioOut, frames, 0);
  1345. } // End of Plugin processing (no events)
  1346. // --------------------------------------------------------------------------------------------------------
  1347. // MIDI Output
  1348. if (pData->event.portOut != nullptr)
  1349. {
  1350. // reverse lookup MIDI events
  1351. for (uint32_t k = (kPluginMaxMidiEvents*2)-1; k >= fMidiEventCount; --k)
  1352. {
  1353. if (fMidiEvents[k].type == 0)
  1354. break;
  1355. const VstMidiEvent& vstMidiEvent(fMidiEvents[k]);
  1356. CARLA_SAFE_ASSERT_CONTINUE(vstMidiEvent.deltaFrames >= 0);
  1357. CARLA_SAFE_ASSERT_CONTINUE(vstMidiEvent.midiData[0] != 0);
  1358. uint8_t midiData[3];
  1359. midiData[0] = static_cast<uint8_t>(vstMidiEvent.midiData[0]);
  1360. midiData[1] = static_cast<uint8_t>(vstMidiEvent.midiData[1]);
  1361. midiData[2] = static_cast<uint8_t>(vstMidiEvent.midiData[2]);
  1362. if (! pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(vstMidiEvent.deltaFrames), 3, midiData))
  1363. break;
  1364. }
  1365. } // End of MIDI Output
  1366. fFirstActive = false;
  1367. // --------------------------------------------------------------------------------------------------------
  1368. #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1369. return;
  1370. // unused
  1371. (void)cvIn;
  1372. #endif
  1373. }
  1374. bool processSingle(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  1375. {
  1376. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  1377. if (pData->audioIn.count > 0)
  1378. {
  1379. CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
  1380. }
  1381. if (pData->audioOut.count > 0)
  1382. {
  1383. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  1384. CARLA_SAFE_ASSERT_RETURN(fAudioOutBuffers != nullptr, false);
  1385. }
  1386. // --------------------------------------------------------------------------------------------------------
  1387. // Try lock, silence otherwise
  1388. #ifndef STOAT_TEST_BUILD
  1389. if (pData->engine->isOffline())
  1390. {
  1391. pData->singleMutex.lock();
  1392. }
  1393. else
  1394. #endif
  1395. if (! pData->singleMutex.tryLock())
  1396. {
  1397. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1398. {
  1399. for (uint32_t k=0; k < frames; ++k)
  1400. outBuffer[i][k+timeOffset] = 0.0f;
  1401. }
  1402. return false;
  1403. }
  1404. // --------------------------------------------------------------------------------------------------------
  1405. // Set audio buffers
  1406. float* vstInBuffer[64]; // pData->audioIn.count
  1407. for (uint32_t i=0; i < pData->audioIn.count; ++i)
  1408. vstInBuffer[i] = const_cast<float*>(inBuffer[i]+timeOffset);
  1409. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1410. carla_zeroFloats(fAudioOutBuffers[i], frames);
  1411. // --------------------------------------------------------------------------------------------------------
  1412. // Set MIDI events
  1413. fIsProcessing = true;
  1414. if (fMidiEventCount > 0)
  1415. {
  1416. fEvents.numEvents = static_cast<int32_t>(fMidiEventCount);
  1417. fEvents.reserved = 0;
  1418. dispatcher(effProcessEvents, 0, 0, &fEvents, 0.0f);
  1419. }
  1420. // --------------------------------------------------------------------------------------------------------
  1421. // Run plugin
  1422. if (pData->hints & PLUGIN_CAN_PROCESS_REPLACING)
  1423. {
  1424. fEffect->processReplacing(fEffect,
  1425. (pData->audioIn.count > 0) ? vstInBuffer : nullptr,
  1426. (pData->audioOut.count > 0) ? fAudioOutBuffers : nullptr,
  1427. static_cast<int32_t>(frames));
  1428. }
  1429. else
  1430. {
  1431. #if ! VST_FORCE_DEPRECATED
  1432. fEffect->process(fEffect,
  1433. (pData->audioIn.count > 0) ? vstInBuffer : nullptr,
  1434. (pData->audioOut.count > 0) ? fAudioOutBuffers : nullptr,
  1435. static_cast<int32_t>(frames));
  1436. #endif
  1437. }
  1438. fIsProcessing = false;
  1439. fTimeInfo.samplePos += frames;
  1440. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1441. // --------------------------------------------------------------------------------------------------------
  1442. // Post-processing (dry/wet, volume and balance)
  1443. {
  1444. const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
  1445. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  1446. const bool isMono = (pData->audioIn.count == 1);
  1447. bool isPair;
  1448. float bufValue;
  1449. float* const oldBufLeft = pData->postProc.extraBuffer;
  1450. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1451. {
  1452. // Dry/Wet
  1453. if (doDryWet)
  1454. {
  1455. const uint32_t c = isMono ? 0 : i;
  1456. for (uint32_t k=0; k < frames; ++k)
  1457. {
  1458. bufValue = inBuffer[c][k+timeOffset];
  1459. fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
  1460. }
  1461. }
  1462. // Balance
  1463. if (doBalance)
  1464. {
  1465. isPair = (i % 2 == 0);
  1466. if (isPair)
  1467. {
  1468. CARLA_ASSERT(i+1 < pData->audioOut.count);
  1469. carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames);
  1470. }
  1471. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  1472. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  1473. for (uint32_t k=0; k < frames; ++k)
  1474. {
  1475. if (isPair)
  1476. {
  1477. // left
  1478. fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  1479. fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
  1480. }
  1481. else
  1482. {
  1483. // right
  1484. fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
  1485. fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
  1486. }
  1487. }
  1488. }
  1489. // Volume (and buffer copy)
  1490. {
  1491. for (uint32_t k=0; k < frames; ++k)
  1492. outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume;
  1493. }
  1494. }
  1495. } // End of Post-processing
  1496. #else // BUILD_BRIDGE_ALTERNATIVE_ARCH
  1497. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1498. {
  1499. for (uint32_t k=0; k < frames; ++k)
  1500. outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k];
  1501. }
  1502. #endif
  1503. // --------------------------------------------------------------------------------------------------------
  1504. pData->singleMutex.unlock();
  1505. return true;
  1506. }
  1507. void bufferSizeChanged(const uint32_t newBufferSize) override
  1508. {
  1509. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  1510. carla_debug("CarlaPluginVST2::bufferSizeChanged(%i)", newBufferSize);
  1511. fBufferSize = pData->engine->getBufferSize();
  1512. if (pData->active)
  1513. deactivate();
  1514. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1515. {
  1516. if (fAudioOutBuffers[i] != nullptr)
  1517. delete[] fAudioOutBuffers[i];
  1518. fAudioOutBuffers[i] = new float[newBufferSize];
  1519. }
  1520. #if ! VST_FORCE_DEPRECATED
  1521. dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast<int32_t>(newBufferSize), nullptr, static_cast<float>(pData->engine->getSampleRate()));
  1522. #endif
  1523. dispatcher(effSetBlockSize, 0, static_cast<int32_t>(newBufferSize), nullptr, 0.0f);
  1524. if (pData->active)
  1525. activate();
  1526. CarlaPlugin::bufferSizeChanged(newBufferSize);
  1527. }
  1528. void sampleRateChanged(const double newSampleRate) override
  1529. {
  1530. CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
  1531. carla_debug("CarlaPluginVST2::sampleRateChanged(%g)", newSampleRate);
  1532. if (pData->active)
  1533. deactivate();
  1534. #if ! VST_FORCE_DEPRECATED
  1535. dispatcher(effSetBlockSizeAndSampleRate, 0, static_cast<int32_t>(pData->engine->getBufferSize()), nullptr, static_cast<float>(newSampleRate));
  1536. #endif
  1537. dispatcher(effSetSampleRate, 0, 0, nullptr, static_cast<float>(newSampleRate));
  1538. if (pData->active)
  1539. activate();
  1540. }
  1541. // -------------------------------------------------------------------
  1542. // Plugin buffers
  1543. void clearBuffers() noexcept override
  1544. {
  1545. carla_debug("CarlaPluginVST2::clearBuffers() - start");
  1546. if (fAudioOutBuffers != nullptr)
  1547. {
  1548. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1549. {
  1550. if (fAudioOutBuffers[i] != nullptr)
  1551. {
  1552. delete[] fAudioOutBuffers[i];
  1553. fAudioOutBuffers[i] = nullptr;
  1554. }
  1555. }
  1556. delete[] fAudioOutBuffers;
  1557. fAudioOutBuffers = nullptr;
  1558. }
  1559. CarlaPlugin::clearBuffers();
  1560. carla_debug("CarlaPluginVST2::clearBuffers() - end");
  1561. }
  1562. // -------------------------------------------------------------------
  1563. // Post-poned UI Stuff
  1564. // nothing
  1565. // -------------------------------------------------------------------
  1566. protected:
  1567. void handlePluginUIClosed() override
  1568. {
  1569. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  1570. carla_debug("CarlaPluginVST2::handlePluginUIClosed()");
  1571. showCustomUI(false);
  1572. pData->engine->callback(true, true,
  1573. ENGINE_CALLBACK_UI_STATE_CHANGED,
  1574. pData->id,
  1575. 0,
  1576. 0, 0, 0.0f, nullptr);
  1577. }
  1578. void handlePluginUIResized(const uint width, const uint height) override
  1579. {
  1580. CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
  1581. carla_debug("CarlaPluginVST2::handlePluginUIResized(%u, %u)", width, height);
  1582. return; // unused
  1583. (void)width; (void)height;
  1584. }
  1585. // -------------------------------------------------------------------
  1586. intptr_t dispatcher(int32_t opcode, int32_t index = 0, intptr_t value = 0, void* ptr = nullptr, float opt = 0.0f) const noexcept
  1587. {
  1588. CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
  1589. #ifdef DEBUG
  1590. if (opcode != effIdle && opcode != effEditIdle && opcode != effProcessEvents)
  1591. carla_debug("CarlaPluginVST2::dispatcher(%02i:%s, %i, " P_INTPTR ", %p, %f)",
  1592. opcode, vstEffectOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  1593. #endif
  1594. try {
  1595. return fEffect->dispatcher(fEffect, opcode, index, value, ptr, opt);
  1596. } CARLA_SAFE_EXCEPTION_RETURN("Vst dispatcher", 0);
  1597. }
  1598. intptr_t handleAudioMasterCallback(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  1599. {
  1600. #ifdef DEBUG
  1601. if (opcode != audioMasterGetTime)
  1602. carla_debug("CarlaPluginVST2::handleAudioMasterCallback(%02i:%s, %i, " P_INTPTR ", %p, %f)",
  1603. opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  1604. #endif
  1605. intptr_t ret = 0;
  1606. switch (opcode)
  1607. {
  1608. case audioMasterAutomate: {
  1609. if (fIsInitializing) {
  1610. // some plugins can be stupid...
  1611. if (pData->param.count == 0)
  1612. break;
  1613. } else {
  1614. CARLA_CUSTOM_SAFE_ASSERT_BREAK("audioMasterAutomate while disabled", pData->enabled);
  1615. }
  1616. // plugins should never do this:
  1617. CARLA_SAFE_ASSERT_INT2_BREAK(index >= 0 && index < static_cast<int32_t>(pData->param.count),
  1618. index,
  1619. static_cast<int32_t>(pData->param.count));
  1620. const uint32_t uindex(static_cast<uint32_t>(index));
  1621. const float fixedValue(pData->param.getFixedValue(uindex, opt));
  1622. const pthread_t thisThread = pthread_self();
  1623. if (pthread_equal(thisThread, kNullThread))
  1624. {
  1625. carla_stderr("audioMasterAutomate called with null thread!?");
  1626. setParameterValue(uindex, fixedValue, false, true, true);
  1627. }
  1628. // Called from plugin process thread, nasty! (likely MIDI learn)
  1629. else if (pthread_equal(thisThread, fProcThread))
  1630. {
  1631. CARLA_SAFE_ASSERT(fIsProcessing);
  1632. pData->postponeParameterChangeRtEvent(true, index, fixedValue);
  1633. }
  1634. // Called from effSetChunk or effSetProgram
  1635. else if (pthread_equal(thisThread, fChangingValuesThread))
  1636. {
  1637. carla_debug("audioMasterAutomate called while setting state");
  1638. pData->postponeParameterChangeRtEvent(true, index, fixedValue);
  1639. }
  1640. // Called from effIdle
  1641. else if (pthread_equal(thisThread, fIdleThread))
  1642. {
  1643. carla_debug("audioMasterAutomate called from idle thread");
  1644. pData->postponeParameterChangeRtEvent(true, index, fixedValue);
  1645. }
  1646. // Called from main thread, why?
  1647. else if (pthread_equal(thisThread, fMainThread))
  1648. {
  1649. if (fFirstActive) {
  1650. carla_stdout("audioMasterAutomate called while loading, nasty!");
  1651. } else {
  1652. carla_debug("audioMasterAutomate called from main thread");
  1653. }
  1654. CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true);
  1655. }
  1656. // Called from UI?
  1657. else if (fUI.isVisible)
  1658. {
  1659. carla_debug("audioMasterAutomate called while UI visible");
  1660. CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true);
  1661. }
  1662. // Unknown
  1663. else
  1664. {
  1665. carla_stdout("audioMasterAutomate called from unknown source");
  1666. CarlaPlugin::setParameterValue(uindex, fixedValue, false, true, true);
  1667. }
  1668. break;
  1669. }
  1670. case audioMasterCurrentId:
  1671. if (fEffect != nullptr)
  1672. ret = fEffect->uniqueID;
  1673. break;
  1674. case audioMasterIdle:
  1675. CARLA_SAFE_ASSERT_BREAK(pthread_equal(pthread_self(), fMainThread));
  1676. pData->engine->callback(true, false, ENGINE_CALLBACK_IDLE, 0, 0, 0, 0, 0.0f, nullptr);
  1677. if (pData->engine->getType() != kEngineTypePlugin)
  1678. pData->engine->idle();
  1679. break;
  1680. #if ! VST_FORCE_DEPRECATED
  1681. case audioMasterPinConnected:
  1682. // Deprecated in VST SDK 2.4
  1683. // TODO
  1684. break;
  1685. case audioMasterWantMidi:
  1686. // Deprecated in VST SDK 2.4
  1687. pData->hints |= PLUGIN_WANTS_MIDI_INPUT;
  1688. break;
  1689. #endif
  1690. case audioMasterGetTime:
  1691. ret = (intptr_t)&fTimeInfo;
  1692. break;
  1693. case audioMasterProcessEvents:
  1694. CARLA_SAFE_ASSERT_RETURN(pData->enabled, 0);
  1695. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, 0);
  1696. CARLA_SAFE_ASSERT_RETURN(pData->event.portOut != nullptr, 0);
  1697. if (fMidiEventCount >= kPluginMaxMidiEvents*2-1)
  1698. return 0;
  1699. if (const VstEvents* const vstEvents = (const VstEvents*)ptr)
  1700. {
  1701. for (int32_t i=0; i < vstEvents->numEvents && i < kPluginMaxMidiEvents*2; ++i)
  1702. {
  1703. if (vstEvents->events[i] == nullptr)
  1704. break;
  1705. const VstMidiEvent* const vstMidiEvent((const VstMidiEvent*)vstEvents->events[i]);
  1706. if (vstMidiEvent->type != kVstMidiType)
  1707. continue;
  1708. // reverse-find first free event, and put it there
  1709. for (uint32_t j=(kPluginMaxMidiEvents*2)-1; j >= fMidiEventCount; --j)
  1710. {
  1711. if (fMidiEvents[j].type == 0)
  1712. {
  1713. std::memcpy(&fMidiEvents[j], vstMidiEvent, sizeof(VstMidiEvent));
  1714. break;
  1715. }
  1716. }
  1717. }
  1718. }
  1719. ret = 1;
  1720. break;
  1721. #if ! VST_FORCE_DEPRECATED
  1722. case audioMasterSetTime:
  1723. // Deprecated in VST SDK 2.4
  1724. break;
  1725. case audioMasterTempoAt:
  1726. // Deprecated in VST SDK 2.4
  1727. ret = static_cast<intptr_t>(fTimeInfo.tempo * 10000);
  1728. break;
  1729. case audioMasterGetNumAutomatableParameters:
  1730. // Deprecated in VST SDK 2.4
  1731. ret = static_cast<intptr_t>(pData->engine->getOptions().maxParameters);
  1732. ret = carla_minPositive<intptr_t>(ret, fEffect->numParams);
  1733. break;
  1734. case audioMasterGetParameterQuantization:
  1735. // Deprecated in VST SDK 2.4
  1736. ret = 1; // full single float precision
  1737. break;
  1738. #endif
  1739. #if 0
  1740. case audioMasterIOChanged:
  1741. CARLA_ASSERT(pData->enabled);
  1742. // TESTING
  1743. if (! pData->enabled)
  1744. {
  1745. ret = 1;
  1746. break;
  1747. }
  1748. if (x_engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK)
  1749. {
  1750. carla_stderr2("CarlaPluginVST2::handleAudioMasterIOChanged() - plugin asked IO change, but it's not supported in rack mode");
  1751. return 0;
  1752. }
  1753. engineProcessLock();
  1754. m_enabled = false;
  1755. engineProcessUnlock();
  1756. if (m_active)
  1757. {
  1758. effect->dispatcher(effect, effStopProcess);
  1759. effect->dispatcher(effect, effMainsChanged, 0, 0);
  1760. }
  1761. reload();
  1762. if (m_active)
  1763. {
  1764. effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
  1765. effect->dispatcher(effect, effStartProcess);
  1766. }
  1767. x_engine->callback(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0, 0.0, nullptr);
  1768. ret = 1;
  1769. break;
  1770. #endif
  1771. #if ! VST_FORCE_DEPRECATED
  1772. case audioMasterNeedIdle:
  1773. // Deprecated in VST SDK 2.4
  1774. fNeedIdle = true;
  1775. ret = 1;
  1776. break;
  1777. #endif
  1778. case audioMasterSizeWindow:
  1779. CARLA_SAFE_ASSERT_BREAK(index > 0);
  1780. CARLA_SAFE_ASSERT_BREAK(value > 0);
  1781. if (fUI.isEmbed)
  1782. {
  1783. pData->engine->callback(true, true,
  1784. ENGINE_CALLBACK_EMBED_UI_RESIZED,
  1785. pData->id, index, static_cast<int>(value),
  1786. 0, 0.0f, nullptr);
  1787. }
  1788. else
  1789. {
  1790. CARLA_SAFE_ASSERT_BREAK(fUI.window != nullptr);
  1791. fUI.window->setSize(static_cast<uint>(index), static_cast<uint>(value), true, false);
  1792. }
  1793. ret = 1;
  1794. break;
  1795. case audioMasterGetSampleRate:
  1796. ret = static_cast<intptr_t>(pData->engine->getSampleRate());
  1797. break;
  1798. case audioMasterGetBlockSize:
  1799. ret = static_cast<intptr_t>(pData->engine->getBufferSize());
  1800. break;
  1801. case audioMasterGetInputLatency:
  1802. ret = 0;
  1803. break;
  1804. case audioMasterGetOutputLatency:
  1805. ret = 0;
  1806. break;
  1807. #if ! VST_FORCE_DEPRECATED
  1808. case audioMasterGetPreviousPlug:
  1809. // Deprecated in VST SDK 2.4
  1810. // TODO
  1811. break;
  1812. case audioMasterGetNextPlug:
  1813. // Deprecated in VST SDK 2.4
  1814. // TODO
  1815. break;
  1816. case audioMasterWillReplaceOrAccumulate:
  1817. // Deprecated in VST SDK 2.4
  1818. ret = 1; // replace
  1819. break;
  1820. #endif
  1821. case audioMasterGetCurrentProcessLevel:
  1822. if (pthread_equal(pthread_self(), fProcThread))
  1823. {
  1824. CARLA_SAFE_ASSERT(fIsProcessing);
  1825. if (pData->engine->isOffline())
  1826. ret = kVstProcessLevelOffline;
  1827. else
  1828. ret = kVstProcessLevelRealtime;
  1829. }
  1830. else
  1831. {
  1832. ret = kVstProcessLevelUser;
  1833. }
  1834. break;
  1835. case audioMasterGetAutomationState:
  1836. ret = pData->active ? kVstAutomationReadWrite : kVstAutomationOff;
  1837. break;
  1838. case audioMasterOfflineStart:
  1839. case audioMasterOfflineRead:
  1840. case audioMasterOfflineWrite:
  1841. case audioMasterOfflineGetCurrentPass:
  1842. case audioMasterOfflineGetCurrentMetaPass:
  1843. // TODO
  1844. break;
  1845. #if ! VST_FORCE_DEPRECATED
  1846. case audioMasterSetOutputSampleRate:
  1847. // Deprecated in VST SDK 2.4
  1848. break;
  1849. case audioMasterGetOutputSpeakerArrangement:
  1850. // Deprecated in VST SDK 2.4
  1851. // TODO
  1852. break;
  1853. #endif
  1854. case audioMasterVendorSpecific:
  1855. // TODO - cockos extensions
  1856. break;
  1857. #if ! VST_FORCE_DEPRECATED
  1858. case audioMasterSetIcon:
  1859. // Deprecated in VST SDK 2.4
  1860. break;
  1861. #endif
  1862. #if ! VST_FORCE_DEPRECATED
  1863. case audioMasterOpenWindow:
  1864. case audioMasterCloseWindow:
  1865. // Deprecated in VST SDK 2.4
  1866. // TODO
  1867. break;
  1868. #endif
  1869. case audioMasterGetDirectory:
  1870. // TODO
  1871. break;
  1872. case audioMasterUpdateDisplay: {
  1873. bool programNamesUpdated = false;
  1874. // Update current program
  1875. if (pData->prog.count > 1)
  1876. {
  1877. const int32_t current = static_cast<int32_t>(dispatcher(effGetProgram));
  1878. if (current >= 0 && current < static_cast<int32_t>(pData->prog.count))
  1879. {
  1880. char strBuf[STR_MAX+1] = { '\0' };
  1881. dispatcher(effGetProgramName, 0, 0, strBuf);
  1882. if (pData->prog.names[current] != nullptr)
  1883. delete[] pData->prog.names[current];
  1884. pData->prog.names[current] = carla_strdup(strBuf);
  1885. if (pData->prog.current != current)
  1886. {
  1887. pData->prog.current = current;
  1888. pData->engine->callback(true, true,
  1889. ENGINE_CALLBACK_PROGRAM_CHANGED,
  1890. pData->id,
  1891. current,
  1892. 0, 0, 0.0f, nullptr);
  1893. }
  1894. }
  1895. // Check for updated program names
  1896. char strBuf[STR_MAX+1];
  1897. for (int32_t i=0; i < fEffect->numPrograms && i < static_cast<int32_t>(pData->prog.count); ++i)
  1898. {
  1899. carla_zeroStruct(strBuf);
  1900. if (dispatcher(effGetProgramNameIndexed, i, 0, strBuf) != 1)
  1901. {
  1902. // stop here if plugin does not support indexed names
  1903. break;
  1904. }
  1905. if (std::strcmp(pData->prog.names[i], strBuf) != 0)
  1906. {
  1907. const char* const old = pData->prog.names[i];
  1908. pData->prog.names[i] = carla_strdup(strBuf);
  1909. delete[] old;
  1910. programNamesUpdated = true;
  1911. }
  1912. }
  1913. }
  1914. if (! fIsInitializing)
  1915. {
  1916. if (programNamesUpdated)
  1917. pData->engine->callback(true, true,
  1918. ENGINE_CALLBACK_RELOAD_PROGRAMS,
  1919. pData->id, 0, 0, 0, 0.0f, nullptr);
  1920. pData->engine->callback(true, true,
  1921. ENGINE_CALLBACK_RELOAD_PARAMETERS,
  1922. pData->id, 0, 0, 0, 0.0f, nullptr);
  1923. }
  1924. ret = 1;
  1925. break;
  1926. }
  1927. case audioMasterBeginEdit:
  1928. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1929. pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), true);
  1930. break;
  1931. case audioMasterEndEdit:
  1932. CARLA_SAFE_ASSERT_BREAK(index >= 0);
  1933. pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), false);
  1934. break;
  1935. case audioMasterOpenFileSelector:
  1936. case audioMasterCloseFileSelector:
  1937. // TODO
  1938. break;
  1939. #if ! VST_FORCE_DEPRECATED
  1940. case audioMasterEditFile:
  1941. // Deprecated in VST SDK 2.4
  1942. // TODO
  1943. break;
  1944. case audioMasterGetChunkFile:
  1945. // Deprecated in VST SDK 2.4
  1946. // TODO
  1947. break;
  1948. case audioMasterGetInputSpeakerArrangement:
  1949. // Deprecated in VST SDK 2.4
  1950. // TODO
  1951. break;
  1952. #endif
  1953. default:
  1954. carla_debug("CarlaPluginVST2::handleAudioMasterCallback(%02i:%s, %i, " P_INTPTR ", %p, %f) UNDEF",
  1955. opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  1956. break;
  1957. }
  1958. return ret;
  1959. // unused
  1960. (void)opt;
  1961. }
  1962. bool canDo(const char* const feature) const noexcept
  1963. {
  1964. try {
  1965. return (dispatcher(effCanDo, 0, 0, const_cast<char*>(feature)) == 1);
  1966. } CARLA_SAFE_EXCEPTION_RETURN("vstPluginCanDo", false);
  1967. }
  1968. bool hasMidiInput() const noexcept
  1969. {
  1970. return pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_IN ||
  1971. pData->hints & PLUGIN_WANTS_MIDI_INPUT ||
  1972. fEffect->flags & effFlagsIsSynth ||
  1973. canDo("receiveVstEvents") ||
  1974. canDo("receiveVstMidiEvent");
  1975. }
  1976. bool hasMidiOutput() const noexcept
  1977. {
  1978. return pData->extraHints & PLUGIN_EXTRA_HINT_HAS_MIDI_OUT ||
  1979. canDo("sendVstEvents") ||
  1980. canDo("sendVstMidiEvent");
  1981. }
  1982. // -------------------------------------------------------------------
  1983. const void* getNativeDescriptor() const noexcept override
  1984. {
  1985. return fEffect;
  1986. }
  1987. // -------------------------------------------------------------------
  1988. public:
  1989. bool init(const CarlaPluginPtr plugin,
  1990. const char* const filename, const char* const name, const int64_t uniqueId, const uint options)
  1991. {
  1992. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1993. // ---------------------------------------------------------------
  1994. // first checks
  1995. if (pData->client != nullptr)
  1996. {
  1997. pData->engine->setLastError("Plugin client is already registered");
  1998. return false;
  1999. }
  2000. if (filename == nullptr || filename[0] == '\0')
  2001. {
  2002. pData->engine->setLastError("null filename");
  2003. return false;
  2004. }
  2005. // ---------------------------------------------------------------
  2006. VST_Function vstFn;
  2007. #ifdef CARLA_OS_MAC
  2008. CarlaString filenameCheck(filename);
  2009. filenameCheck.toLower();
  2010. if (filenameCheck.endsWith(".vst") || filenameCheck.endsWith(".vst/"))
  2011. {
  2012. if (! fBundleLoader.load(filename))
  2013. {
  2014. pData->engine->setLastError("Failed to load VST2 bundle executable");
  2015. return false;
  2016. }
  2017. vstFn = fBundleLoader.getSymbol<VST_Function>(CFSTR("VSTPluginMain"));
  2018. if (vstFn == nullptr)
  2019. vstFn = fBundleLoader.getSymbol<VST_Function>(CFSTR("main_macho"));
  2020. if (vstFn == nullptr)
  2021. {
  2022. pData->engine->setLastError("Not a VST2 plugin");
  2023. return false;
  2024. }
  2025. }
  2026. else
  2027. #endif
  2028. {
  2029. // -----------------------------------------------------------
  2030. // open DLL
  2031. if (! pData->libOpen(filename))
  2032. {
  2033. pData->engine->setLastError(pData->libError(filename));
  2034. return false;
  2035. }
  2036. // -----------------------------------------------------------
  2037. // get DLL main entry
  2038. vstFn = pData->libSymbol<VST_Function>("VSTPluginMain");
  2039. if (vstFn == nullptr)
  2040. {
  2041. vstFn = pData->libSymbol<VST_Function>("main");
  2042. if (vstFn == nullptr)
  2043. {
  2044. pData->engine->setLastError("Could not find the VST2 main entry in the plugin library");
  2045. return false;
  2046. }
  2047. }
  2048. }
  2049. // ---------------------------------------------------------------
  2050. // initialize plugin (part 1)
  2051. sCurrentUniqueId = static_cast<intptr_t>(uniqueId);
  2052. sLastCarlaPluginVST2 = this;
  2053. bool wasTriggered, wasThrown = false;
  2054. {
  2055. #if !(defined(CARLA_OS_WASM) || defined(CARLA_OS_WIN))
  2056. const ScopedAbortCatcher sac;
  2057. #endif
  2058. try {
  2059. fEffect = vstFn(carla_vst_audioMasterCallback);
  2060. } CARLA_CATCH_UNWIND catch(...) {
  2061. wasThrown = true;
  2062. }
  2063. #if !(defined(CARLA_OS_WASM) || defined(CARLA_OS_WIN))
  2064. wasTriggered = sac.wasTriggered();
  2065. #else
  2066. wasTriggered = false;
  2067. #endif
  2068. }
  2069. // try again if plugin blows
  2070. if (wasTriggered || wasThrown)
  2071. {
  2072. #if !(defined(CARLA_OS_WASM) || defined(CARLA_OS_WIN))
  2073. const ScopedAbortCatcher sac;
  2074. #endif
  2075. try {
  2076. fEffect = vstFn(carla_vst_audioMasterCallback);
  2077. } CARLA_SAFE_EXCEPTION_RETURN("VST init 2nd attempt", false);
  2078. }
  2079. sLastCarlaPluginVST2 = nullptr;
  2080. sCurrentUniqueId = 0;
  2081. if (fEffect == nullptr)
  2082. {
  2083. pData->engine->setLastError("Plugin failed to initialize");
  2084. return false;
  2085. }
  2086. if (fEffect->magic != kEffectMagic)
  2087. {
  2088. pData->engine->setLastError("Plugin is not valid (wrong vst effect magic code)");
  2089. return false;
  2090. }
  2091. fEffect->ptr1 = this;
  2092. const int32_t iBufferSize = static_cast<int32_t>(fBufferSize);
  2093. const float fSampleRate = static_cast<float>(pData->engine->getSampleRate());
  2094. dispatcher(effIdentify);
  2095. dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32);
  2096. dispatcher(effSetBlockSizeAndSampleRate, 0, iBufferSize, nullptr, fSampleRate);
  2097. dispatcher(effSetSampleRate, 0, 0, nullptr, fSampleRate);
  2098. dispatcher(effSetBlockSize, 0, iBufferSize);
  2099. dispatcher(effOpen);
  2100. const bool isShell = (dispatcher(effGetPlugCategory) == kPlugCategShell);
  2101. if (uniqueId == 0 && isShell)
  2102. {
  2103. char strBuf[STR_MAX+1];
  2104. carla_zeroChars(strBuf, STR_MAX+1);
  2105. sCurrentUniqueId = dispatcher(effShellGetNextPlugin, 0, 0, strBuf);
  2106. dispatcher(effClose);
  2107. fEffect = nullptr;
  2108. sLastCarlaPluginVST2 = this;
  2109. try {
  2110. fEffect = vstFn(carla_vst_audioMasterCallback);
  2111. } CARLA_SAFE_EXCEPTION_RETURN("Vst init", false);
  2112. sLastCarlaPluginVST2 = nullptr;
  2113. sCurrentUniqueId = 0;
  2114. dispatcher(effIdentify);
  2115. dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32);
  2116. dispatcher(effSetBlockSizeAndSampleRate, 0, iBufferSize, nullptr, fSampleRate);
  2117. dispatcher(effSetSampleRate, 0, 0, nullptr, fSampleRate);
  2118. dispatcher(effSetBlockSize, 0, iBufferSize);
  2119. dispatcher(effOpen);
  2120. }
  2121. if (fEffect->uniqueID == 0 && !isShell)
  2122. {
  2123. dispatcher(effClose);
  2124. fEffect = nullptr;
  2125. pData->engine->setLastError("Plugin is not valid (no unique ID after being open)");
  2126. return false;
  2127. }
  2128. // ---------------------------------------------------------------
  2129. // get info
  2130. if (name != nullptr && name[0] != '\0')
  2131. {
  2132. pData->name = pData->engine->getUniquePluginName(name);
  2133. }
  2134. else
  2135. {
  2136. char strBuf[STR_MAX+1];
  2137. carla_zeroChars(strBuf, STR_MAX+1);
  2138. dispatcher(effGetEffectName, 0, 0, strBuf);
  2139. if (strBuf[0] != '\0')
  2140. pData->name = pData->engine->getUniquePluginName(strBuf);
  2141. else if (const char* const shortname = std::strrchr(filename, CARLA_OS_SEP))
  2142. pData->name = pData->engine->getUniquePluginName(shortname+1);
  2143. else
  2144. pData->name = pData->engine->getUniquePluginName("unknown");
  2145. }
  2146. pData->filename = carla_strdup(filename);
  2147. // ---------------------------------------------------------------
  2148. // register client
  2149. pData->client = pData->engine->addClient(plugin);
  2150. if (pData->client == nullptr || ! pData->client->isOk())
  2151. {
  2152. pData->engine->setLastError("Failed to register plugin client");
  2153. return false;
  2154. }
  2155. // ---------------------------------------------------------------
  2156. // initialize plugin (part 2)
  2157. for (int i = fEffect->numInputs; --i >= 0;) dispatcher(effConnectInput, i, 1);
  2158. for (int i = fEffect->numOutputs; --i >= 0;) dispatcher(effConnectOutput, i, 1);
  2159. if (dispatcher(effGetVstVersion) < kVstVersion)
  2160. pData->hints |= PLUGIN_USES_OLD_VSTSDK;
  2161. static const char kHasCockosExtensions[] = "hasCockosExtensions";
  2162. if (static_cast<uintptr_t>(dispatcher(effCanDo, 0, 0, const_cast<char*>(kHasCockosExtensions))) == 0xbeef0000)
  2163. pData->hints |= PLUGIN_HAS_COCKOS_EXTENSIONS;
  2164. // ---------------------------------------------------------------
  2165. // set default options
  2166. pData->options = 0x0;
  2167. if (fEffect->initialDelay > 0 || hasMidiOutput() || isPluginOptionEnabled(options, PLUGIN_OPTION_FIXED_BUFFERS))
  2168. pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
  2169. if (fEffect->flags & effFlagsProgramChunks)
  2170. if (isPluginOptionEnabled(options, PLUGIN_OPTION_USE_CHUNKS))
  2171. pData->options |= PLUGIN_OPTION_USE_CHUNKS;
  2172. if (hasMidiInput())
  2173. {
  2174. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
  2175. pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  2176. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
  2177. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  2178. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
  2179. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  2180. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
  2181. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  2182. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
  2183. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  2184. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PROGRAM_CHANGES))
  2185. pData->options |= PLUGIN_OPTION_SEND_PROGRAM_CHANGES;
  2186. if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
  2187. pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  2188. }
  2189. if (fEffect->numPrograms > 1 && (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES) == 0)
  2190. if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
  2191. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  2192. return true;
  2193. }
  2194. private:
  2195. int fUnique1;
  2196. AEffect* fEffect;
  2197. uint32_t fMidiEventCount;
  2198. VstMidiEvent fMidiEvents[kPluginMaxMidiEvents*2];
  2199. VstTimeInfo fTimeInfo;
  2200. bool fNeedIdle;
  2201. void* fLastChunk;
  2202. bool fIsInitializing;
  2203. bool fIsProcessing;
  2204. pthread_t fChangingValuesThread;
  2205. pthread_t fIdleThread;
  2206. pthread_t fMainThread;
  2207. pthread_t fProcThread;
  2208. #ifdef CARLA_OS_MAC
  2209. BundleLoader fBundleLoader;
  2210. #endif
  2211. bool fFirstActive; // first process() call after activate()
  2212. uint32_t fBufferSize;
  2213. float** fAudioOutBuffers;
  2214. EngineTimeInfo fLastTimeInfo;
  2215. struct FixedVstEvents {
  2216. int32_t numEvents;
  2217. intptr_t reserved;
  2218. VstEvent* data[kPluginMaxMidiEvents*2];
  2219. FixedVstEvents() noexcept
  2220. : numEvents(0),
  2221. reserved(0)
  2222. {
  2223. carla_zeroPointers(data, kPluginMaxMidiEvents*2);
  2224. }
  2225. CARLA_DECLARE_NON_COPYABLE(FixedVstEvents);
  2226. } fEvents;
  2227. struct UI {
  2228. bool isEmbed;
  2229. bool isOpen;
  2230. bool isVisible;
  2231. CarlaPluginUI* window;
  2232. UI() noexcept
  2233. : isEmbed(false),
  2234. isOpen(false),
  2235. isVisible(false),
  2236. window(nullptr) {}
  2237. ~UI()
  2238. {
  2239. CARLA_ASSERT(isEmbed || ! isVisible);
  2240. if (window != nullptr)
  2241. {
  2242. delete window;
  2243. window = nullptr;
  2244. }
  2245. }
  2246. CARLA_DECLARE_NON_COPYABLE(UI);
  2247. } fUI;
  2248. int fUnique2;
  2249. static intptr_t sCurrentUniqueId;
  2250. static CarlaPluginVST2* sLastCarlaPluginVST2;
  2251. // -------------------------------------------------------------------
  2252. static bool compareMagic(int32_t magic, const char* name) noexcept
  2253. {
  2254. return magic == (int32_t)ByteOrder::littleEndianInt (name)
  2255. || magic == (int32_t)ByteOrder::bigEndianInt (name);
  2256. }
  2257. static int32_t fxbSwap(const int32_t x) noexcept
  2258. {
  2259. return (int32_t)ByteOrder::swapIfLittleEndian ((uint32_t) x);
  2260. }
  2261. bool loadJuceSaveFormat(const void* const data, const std::size_t dataSize)
  2262. {
  2263. if (dataSize < 28)
  2264. return false;
  2265. const int32_t* const set = (const int32_t*)data;
  2266. if (set[1] != 0)
  2267. return false;
  2268. if (! compareMagic(set[0], "CcnK"))
  2269. return false;
  2270. if (! compareMagic(set[2], "FBCh") && ! compareMagic(set[2], "FJuc"))
  2271. return false;
  2272. if (fxbSwap(set[3]) > 1)
  2273. return false;
  2274. const int32_t chunkSize = fxbSwap(set[39]);
  2275. CARLA_SAFE_ASSERT_RETURN(chunkSize > 0, false);
  2276. if (static_cast<std::size_t>(chunkSize + 160) > dataSize)
  2277. return false;
  2278. carla_stdout("NOTE: Loading plugin state in VST2/JUCE compatibility mode");
  2279. setChunkData(&set[40], static_cast<std::size_t>(chunkSize));
  2280. return true;
  2281. }
  2282. static intptr_t carla_vst_hostCanDo(const char* const feature)
  2283. {
  2284. carla_debug("carla_vst_hostCanDo(\"%s\")", feature);
  2285. if (std::strcmp(feature, "supplyIdle") == 0)
  2286. return 1;
  2287. if (std::strcmp(feature, "sendVstEvents") == 0)
  2288. return 1;
  2289. if (std::strcmp(feature, "sendVstMidiEvent") == 0)
  2290. return 1;
  2291. if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
  2292. return 1;
  2293. if (std::strcmp(feature, "sendVstTimeInfo") == 0)
  2294. return 1;
  2295. if (std::strcmp(feature, "receiveVstEvents") == 0)
  2296. return 1;
  2297. if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
  2298. return 1;
  2299. if (std::strcmp(feature, "receiveVstTimeInfo") == 0)
  2300. return -1;
  2301. if (std::strcmp(feature, "reportConnectionChanges") == 0)
  2302. return -1;
  2303. if (std::strcmp(feature, "acceptIOChanges") == 0)
  2304. return 1;
  2305. if (std::strcmp(feature, "sizeWindow") == 0)
  2306. return 1;
  2307. if (std::strcmp(feature, "offline") == 0)
  2308. return -1;
  2309. if (std::strcmp(feature, "openFileSelector") == 0)
  2310. return -1;
  2311. if (std::strcmp(feature, "closeFileSelector") == 0)
  2312. return -1;
  2313. if (std::strcmp(feature, "startStopProcess") == 0)
  2314. return 1;
  2315. if (std::strcmp(feature, "supportShell") == 0)
  2316. return 1;
  2317. if (std::strcmp(feature, "shellCategory") == 0)
  2318. return 1;
  2319. if (std::strcmp(feature, "NIMKPIVendorSpecificCallbacks") == 0)
  2320. return -1;
  2321. // unimplemented
  2322. carla_stderr("carla_vst_hostCanDo(\"%s\") - unknown feature", feature);
  2323. return 0;
  2324. }
  2325. static intptr_t VSTCALLBACK carla_vst_audioMasterCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
  2326. {
  2327. #if defined(DEBUG) && ! defined(CARLA_OS_WIN)
  2328. if (opcode != audioMasterGetTime && opcode != audioMasterProcessEvents && opcode != audioMasterGetCurrentProcessLevel && opcode != audioMasterGetOutputLatency)
  2329. carla_debug("carla_vst_audioMasterCallback(%p, %02i:%s, %i, " P_INTPTR ", %p, %f)",
  2330. effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  2331. #endif
  2332. switch (opcode)
  2333. {
  2334. case audioMasterVersion:
  2335. return kVstVersion;
  2336. case audioMasterCurrentId:
  2337. if (sCurrentUniqueId != 0)
  2338. return sCurrentUniqueId;
  2339. break;
  2340. case audioMasterGetVendorString:
  2341. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  2342. std::strcpy((char*)ptr, "falkTX");
  2343. return 1;
  2344. case audioMasterGetProductString:
  2345. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  2346. std::strcpy((char*)ptr, "Carla");
  2347. return 1;
  2348. case audioMasterGetVendorVersion:
  2349. return CARLA_VERSION_HEX;
  2350. case audioMasterCanDo:
  2351. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr, 0);
  2352. return carla_vst_hostCanDo((const char*)ptr);
  2353. case audioMasterGetLanguage:
  2354. return kVstLangEnglish;
  2355. }
  2356. // Check if 'resvd1' points to us, otherwise register ourselves if possible
  2357. CarlaPluginVST2* self = nullptr;
  2358. if (effect != nullptr)
  2359. {
  2360. if (effect->ptr1 != nullptr)
  2361. {
  2362. self = (CarlaPluginVST2*)effect->ptr1;
  2363. if (self->fUnique1 != self->fUnique2)
  2364. self = nullptr;
  2365. }
  2366. if (self != nullptr)
  2367. {
  2368. if (self->fEffect == nullptr)
  2369. self->fEffect = effect;
  2370. if (self->fEffect != effect)
  2371. {
  2372. carla_stderr2("carla_vst_audioMasterCallback() - host pointer mismatch: %p != %p", self->fEffect, effect);
  2373. self = nullptr;
  2374. }
  2375. }
  2376. else if (sLastCarlaPluginVST2 != nullptr)
  2377. {
  2378. effect->ptr1 = sLastCarlaPluginVST2;
  2379. self = sLastCarlaPluginVST2;
  2380. }
  2381. }
  2382. return (self != nullptr) ? self->handleAudioMasterCallback(opcode, index, value, ptr, opt) : 0;
  2383. }
  2384. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginVST2)
  2385. };
  2386. intptr_t CarlaPluginVST2::sCurrentUniqueId = 0;
  2387. CarlaPluginVST2* CarlaPluginVST2::sLastCarlaPluginVST2 = nullptr;
  2388. CARLA_BACKEND_END_NAMESPACE
  2389. // --------------------------------------------------------------------------------------------------------------------
  2390. CARLA_BACKEND_START_NAMESPACE
  2391. CarlaPluginPtr CarlaPlugin::newVST2(const Initializer& init)
  2392. {
  2393. carla_debug("CarlaPlugin::newVST2({%p, \"%s\", \"%s\", " P_INT64 "})",
  2394. init.engine, init.filename, init.name, init.uniqueId);
  2395. #ifdef USE_JUCE_FOR_VST2
  2396. if (std::getenv("CARLA_DO_NOT_USE_JUCE_FOR_VST2") == nullptr)
  2397. return newJuce(init, "VST2");
  2398. #endif
  2399. std::shared_ptr<CarlaPluginVST2> plugin(new CarlaPluginVST2(init.engine, init.id));
  2400. if (! plugin->init(plugin, init.filename, init.name, init.uniqueId, init.options))
  2401. return nullptr;
  2402. return plugin;
  2403. }
  2404. // --------------------------------------------------------------------------------------------------------------------
  2405. CARLA_BACKEND_END_NAMESPACE