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

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