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

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