Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CarlaPluginVST2.cpp 82KB

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