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

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