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.

VstPlugin.cpp 83KB

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