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

CarlaPluginVST2.cpp 83KB

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