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.

carla-discovery.cpp 79KB

11 years ago
11 years ago
11 years ago
11 years ago
12 years ago
12 years ago
10 years ago
12 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 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
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
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
2 years ago
2 years ago
10 years ago
10 years ago
11 years ago
10 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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492
  1. /*
  2. * Carla Plugin discovery
  3. * Copyright (C) 2011-2023 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 "CarlaBackendUtils.hpp"
  18. #include "CarlaLibUtils.hpp"
  19. #include "CarlaMathUtils.hpp"
  20. #include "CarlaPipeUtils.cpp"
  21. #include "CarlaScopeUtils.hpp"
  22. #include "CarlaMIDI.h"
  23. #include "LinkedList.hpp"
  24. #include "CarlaLadspaUtils.hpp"
  25. #include "CarlaDssiUtils.hpp"
  26. #include "CarlaLv2Utils.hpp"
  27. #include "CarlaVst2Utils.hpp"
  28. #include "CarlaVst3Utils.hpp"
  29. #ifdef CARLA_OS_MAC
  30. # include "CarlaMacUtils.cpp"
  31. # ifdef __aarch64__
  32. # include <spawn.h>
  33. # endif
  34. #endif
  35. #ifdef CARLA_OS_WIN
  36. # include <pthread.h>
  37. # include <objbase.h>
  38. #endif
  39. #ifdef BUILD_BRIDGE
  40. # undef HAVE_FLUIDSYNTH
  41. #endif
  42. #ifdef HAVE_FLUIDSYNTH
  43. # include <fluidsynth.h>
  44. #endif
  45. #include <iostream>
  46. #include <sstream>
  47. #include "water/files/File.h"
  48. #ifndef BUILD_BRIDGE
  49. # include "CarlaDssiUtils.cpp"
  50. # include "CarlaJsfxUtils.hpp"
  51. # include "../backend/utils/CachedPlugins.cpp"
  52. #endif
  53. #ifdef USING_JUCE
  54. # include "carla_juce/carla_juce.h"
  55. # pragma GCC diagnostic ignored "-Wdouble-promotion"
  56. # pragma GCC diagnostic ignored "-Wduplicated-branches"
  57. # pragma GCC diagnostic ignored "-Weffc++"
  58. # pragma GCC diagnostic ignored "-Wfloat-equal"
  59. # include "juce_audio_processors/juce_audio_processors.h"
  60. # if JUCE_PLUGINHOST_VST
  61. # define USING_JUCE_FOR_VST2
  62. # endif
  63. # if JUCE_PLUGINHOST_VST3
  64. # define USING_JUCE_FOR_VST3
  65. # endif
  66. # pragma GCC diagnostic pop
  67. #endif
  68. #define DISCOVERY_OUT(x, y) \
  69. if (gPipe != nullptr) { std::stringstream s; s << y; gPipe->writeDiscoveryMessage(x, s.str().c_str()); } \
  70. else { std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl; }
  71. using water::File;
  72. CARLA_BACKEND_USE_NAMESPACE
  73. // --------------------------------------------------------------------------------------------------------------------
  74. // Dummy values to test plugins with
  75. static const uint32_t kBufferSize = 512;
  76. static const double kSampleRate = 44100.0;
  77. static const int32_t kSampleRatei = 44100;
  78. static const float kSampleRatef = 44100.0f;
  79. // --------------------------------------------------------------------------------------------------------------------
  80. // Dynamic discovery
  81. class DiscoveryPipe : public CarlaPipeClient
  82. {
  83. public:
  84. DiscoveryPipe() {}
  85. ~DiscoveryPipe()
  86. {
  87. writeExitingMessageAndWait();
  88. }
  89. bool writeDiscoveryMessage(const char* const key, const char* const value) const noexcept
  90. {
  91. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);
  92. CARLA_SAFE_ASSERT_RETURN(value != nullptr, false);
  93. const CarlaMutexLocker cml(pData->writeLock);
  94. if (! writeAndFixMessage(key))
  95. return false;
  96. if (! writeAndFixMessage(value))
  97. return false;
  98. flushMessages();
  99. return true;
  100. }
  101. protected:
  102. bool msgReceived(const char* const msg) noexcept
  103. {
  104. carla_stdout("discovery msgReceived %s", msg);
  105. return true;
  106. }
  107. };
  108. CarlaScopedPointer<DiscoveryPipe> gPipe;
  109. // --------------------------------------------------------------------------------------------------------------------
  110. // Don't print ELF/EXE related errors since discovery can find multi-architecture binaries
  111. static void print_lib_error(const char* const filename)
  112. {
  113. const char* const error(lib_error(filename));
  114. if (error != nullptr &&
  115. std::strstr(error, "wrong ELF class") == nullptr &&
  116. std::strstr(error, "invalid ELF header") == nullptr &&
  117. std::strstr(error, "Bad EXE format") == nullptr &&
  118. std::strstr(error, "no suitable image found") == nullptr &&
  119. std::strstr(error, "not a valid Win32 application") == nullptr)
  120. {
  121. DISCOVERY_OUT("error", error);
  122. }
  123. }
  124. // --------------------------------------------------------------------------------------------------------------------
  125. // Plugin Checks
  126. #ifndef BUILD_BRIDGE
  127. static void print_cached_plugin(const CarlaCachedPluginInfo* const pinfo)
  128. {
  129. if (! pinfo->valid)
  130. return;
  131. DISCOVERY_OUT("init", "-----------");
  132. DISCOVERY_OUT("build", BINARY_NATIVE);
  133. DISCOVERY_OUT("hints", pinfo->hints);
  134. DISCOVERY_OUT("category", getPluginCategoryAsString(pinfo->category));
  135. DISCOVERY_OUT("name", pinfo->name);
  136. DISCOVERY_OUT("maker", pinfo->maker);
  137. DISCOVERY_OUT("label", pinfo->label);
  138. DISCOVERY_OUT("audio.ins", pinfo->audioIns);
  139. DISCOVERY_OUT("audio.outs", pinfo->audioOuts);
  140. DISCOVERY_OUT("cv.ins", pinfo->cvIns);
  141. DISCOVERY_OUT("cv.outs", pinfo->cvOuts);
  142. DISCOVERY_OUT("midi.ins", pinfo->midiIns);
  143. DISCOVERY_OUT("midi.outs", pinfo->midiOuts);
  144. DISCOVERY_OUT("parameters.ins", pinfo->parameterIns);
  145. DISCOVERY_OUT("parameters.outs", pinfo->parameterOuts);
  146. DISCOVERY_OUT("end", "------------");
  147. }
  148. static void do_cached_check(const PluginType type)
  149. {
  150. const char* plugPath = std::getenv("CARLA_DISCOVERY_PATH");
  151. if (plugPath == nullptr)
  152. {
  153. switch (type)
  154. {
  155. case PLUGIN_LV2:
  156. plugPath = std::getenv("LV2_PATH");
  157. break;
  158. case PLUGIN_SFZ:
  159. plugPath = std::getenv("SFZ_PATH");
  160. break;
  161. default:
  162. plugPath = nullptr;
  163. break;
  164. }
  165. }
  166. # ifdef USING_JUCE
  167. if (type == PLUGIN_AU)
  168. CarlaJUCE::initialiseJuce_GUI();
  169. # endif
  170. const uint count = carla_get_cached_plugin_count(type, plugPath);
  171. for (uint i=0; i<count; ++i)
  172. {
  173. const CarlaCachedPluginInfo* pinfo(carla_get_cached_plugin_info(type, i));
  174. CARLA_SAFE_ASSERT_CONTINUE(pinfo != nullptr);
  175. print_cached_plugin(pinfo);
  176. }
  177. # ifdef USING_JUCE
  178. if (type == PLUGIN_AU)
  179. CarlaJUCE::shutdownJuce_GUI();
  180. # endif
  181. }
  182. #endif
  183. static void do_ladspa_check(lib_t& libHandle, const char* const filename, const bool doInit)
  184. {
  185. LADSPA_Descriptor_Function descFn = lib_symbol<LADSPA_Descriptor_Function>(libHandle, "ladspa_descriptor");
  186. if (descFn == nullptr)
  187. {
  188. DISCOVERY_OUT("error", "Not a LADSPA plugin");
  189. return;
  190. }
  191. const LADSPA_Descriptor* descriptor;
  192. {
  193. descriptor = descFn(0);
  194. if (descriptor == nullptr)
  195. {
  196. DISCOVERY_OUT("error", "Binary doesn't contain any plugins");
  197. return;
  198. }
  199. if (doInit && descriptor->instantiate != nullptr && descriptor->cleanup != nullptr)
  200. {
  201. LADSPA_Handle handle = descriptor->instantiate(descriptor, kSampleRatei);
  202. if (handle == nullptr)
  203. {
  204. DISCOVERY_OUT("error", "Failed to init first LADSPA plugin");
  205. return;
  206. }
  207. descriptor->cleanup(handle);
  208. lib_close(libHandle);
  209. libHandle = lib_open(filename);
  210. if (libHandle == nullptr)
  211. {
  212. print_lib_error(filename);
  213. return;
  214. }
  215. descFn = lib_symbol<LADSPA_Descriptor_Function>(libHandle, "ladspa_descriptor");
  216. if (descFn == nullptr)
  217. {
  218. DISCOVERY_OUT("error", "Not a LADSPA plugin (#2)");
  219. return;
  220. }
  221. }
  222. }
  223. unsigned long i = 0;
  224. while ((descriptor = descFn(i++)) != nullptr)
  225. {
  226. if (descriptor->instantiate == nullptr)
  227. {
  228. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no instantiate()");
  229. continue;
  230. }
  231. if (descriptor->cleanup == nullptr)
  232. {
  233. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no cleanup()");
  234. continue;
  235. }
  236. if (descriptor->run == nullptr)
  237. {
  238. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no run()");
  239. continue;
  240. }
  241. if (! LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  242. {
  243. DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable");
  244. }
  245. uint hints = 0x0;
  246. uint audioIns = 0;
  247. uint audioOuts = 0;
  248. uint parametersIns = 0;
  249. uint parametersOuts = 0;
  250. uint parametersTotal = 0;
  251. if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  252. hints |= PLUGIN_IS_RTSAFE;
  253. for (unsigned long j=0; j < descriptor->PortCount; ++j)
  254. {
  255. CARLA_ASSERT(descriptor->PortNames[j] != nullptr);
  256. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  257. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  258. {
  259. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  260. audioIns += 1;
  261. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  262. audioOuts += 1;
  263. }
  264. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  265. {
  266. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  267. parametersIns += 1;
  268. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(descriptor->PortNames[j], "latency") != 0 && std::strcmp(descriptor->PortNames[j], "_latency") != 0)
  269. parametersOuts += 1;
  270. parametersTotal += 1;
  271. }
  272. }
  273. if (doInit)
  274. {
  275. // -----------------------------------------------------------------------
  276. // start crash-free plugin test
  277. LADSPA_Handle handle = descriptor->instantiate(descriptor, kSampleRatei);
  278. if (handle == nullptr)
  279. {
  280. DISCOVERY_OUT("error", "Failed to init LADSPA plugin");
  281. continue;
  282. }
  283. // Test quick init and cleanup
  284. descriptor->cleanup(handle);
  285. handle = descriptor->instantiate(descriptor, kSampleRatei);
  286. if (handle == nullptr)
  287. {
  288. DISCOVERY_OUT("error", "Failed to init LADSPA plugin (#2)");
  289. continue;
  290. }
  291. LADSPA_Data bufferAudio[kBufferSize][std::max(1u, audioIns + audioOuts)];
  292. LADSPA_Data bufferParams[parametersTotal];
  293. LADSPA_Data min, max, def;
  294. for (unsigned long j=0, iA=0, iC=0; j < descriptor->PortCount; ++j)
  295. {
  296. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  297. const LADSPA_PortRangeHint portRangeHints = descriptor->PortRangeHints[j];
  298. const char* const portName = descriptor->PortNames[j];
  299. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  300. {
  301. carla_zeroFloats(bufferAudio[iA], kBufferSize);
  302. descriptor->connect_port(handle, j, bufferAudio[iA++]);
  303. }
  304. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  305. {
  306. // min value
  307. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  308. min = portRangeHints.LowerBound;
  309. else
  310. min = 0.0f;
  311. // max value
  312. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  313. max = portRangeHints.UpperBound;
  314. else
  315. max = 1.0f;
  316. if (min > max)
  317. {
  318. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  319. max = min + 0.1f;
  320. }
  321. else if (carla_isEqual(min, max))
  322. {
  323. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max == min");
  324. max = min + 0.1f;
  325. }
  326. // default value
  327. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  328. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  329. {
  330. min *= kSampleRatef;
  331. max *= kSampleRatef;
  332. def *= kSampleRatef;
  333. }
  334. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  335. {
  336. // latency parameter
  337. def = 0.0f;
  338. }
  339. else
  340. {
  341. if (def < min)
  342. def = min;
  343. else if (def > max)
  344. def = max;
  345. }
  346. bufferParams[iC] = def;
  347. descriptor->connect_port(handle, j, &bufferParams[iC++]);
  348. }
  349. }
  350. if (descriptor->activate != nullptr)
  351. descriptor->activate(handle);
  352. descriptor->run(handle, kBufferSize);
  353. if (descriptor->deactivate != nullptr)
  354. descriptor->deactivate(handle);
  355. descriptor->cleanup(handle);
  356. // end crash-free plugin test
  357. // -----------------------------------------------------------------------
  358. }
  359. DISCOVERY_OUT("init", "-----------");
  360. DISCOVERY_OUT("build", BINARY_NATIVE);
  361. DISCOVERY_OUT("hints", hints);
  362. DISCOVERY_OUT("category", getPluginCategoryAsString(getPluginCategoryFromName(descriptor->Name)));
  363. DISCOVERY_OUT("name", descriptor->Name);
  364. DISCOVERY_OUT("label", descriptor->Label);
  365. DISCOVERY_OUT("maker", descriptor->Maker);
  366. DISCOVERY_OUT("uniqueId", descriptor->UniqueID);
  367. DISCOVERY_OUT("audio.ins", audioIns);
  368. DISCOVERY_OUT("audio.outs", audioOuts);
  369. DISCOVERY_OUT("parameters.ins", parametersIns);
  370. DISCOVERY_OUT("parameters.outs", parametersOuts);
  371. DISCOVERY_OUT("end", "------------");
  372. }
  373. }
  374. static void do_dssi_check(lib_t& libHandle, const char* const filename, const bool doInit)
  375. {
  376. DSSI_Descriptor_Function descFn = lib_symbol<DSSI_Descriptor_Function>(libHandle, "dssi_descriptor");
  377. if (descFn == nullptr)
  378. {
  379. DISCOVERY_OUT("error", "Not a DSSI plugin");
  380. return;
  381. }
  382. const DSSI_Descriptor* descriptor;
  383. {
  384. descriptor = descFn(0);
  385. if (descriptor == nullptr)
  386. {
  387. DISCOVERY_OUT("error", "Binary doesn't contain any plugins");
  388. return;
  389. }
  390. const LADSPA_Descriptor* const ldescriptor(descriptor->LADSPA_Plugin);
  391. if (ldescriptor == nullptr)
  392. {
  393. DISCOVERY_OUT("error", "DSSI plugin doesn't provide the LADSPA interface");
  394. return;
  395. }
  396. if (doInit && ldescriptor->instantiate != nullptr && ldescriptor->cleanup != nullptr)
  397. {
  398. LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  399. if (handle == nullptr)
  400. {
  401. DISCOVERY_OUT("error", "Failed to init first LADSPA plugin");
  402. return;
  403. }
  404. ldescriptor->cleanup(handle);
  405. lib_close(libHandle);
  406. libHandle = lib_open(filename);
  407. if (libHandle == nullptr)
  408. {
  409. print_lib_error(filename);
  410. return;
  411. }
  412. descFn = lib_symbol<DSSI_Descriptor_Function>(libHandle, "dssi_descriptor");
  413. if (descFn == nullptr)
  414. {
  415. DISCOVERY_OUT("error", "Not a DSSI plugin (#2)");
  416. return;
  417. }
  418. }
  419. }
  420. unsigned long i = 0;
  421. while ((descriptor = descFn(i++)) != nullptr)
  422. {
  423. const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin;
  424. if (ldescriptor == nullptr)
  425. {
  426. DISCOVERY_OUT("error", "Plugin has no LADSPA interface");
  427. continue;
  428. }
  429. if (descriptor->DSSI_API_Version != DSSI_VERSION_MAJOR)
  430. {
  431. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' uses an unsupported DSSI spec version " << descriptor->DSSI_API_Version);
  432. continue;
  433. }
  434. if (ldescriptor->instantiate == nullptr)
  435. {
  436. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no instantiate()");
  437. continue;
  438. }
  439. if (ldescriptor->cleanup == nullptr)
  440. {
  441. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no cleanup()");
  442. continue;
  443. }
  444. if (ldescriptor->run == nullptr && descriptor->run_synth == nullptr)
  445. {
  446. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no run() or run_synth()");
  447. continue;
  448. }
  449. if (descriptor->run_synth == nullptr && descriptor->run_multiple_synths != nullptr)
  450. {
  451. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' requires run_multiple_synths which is not supported");
  452. continue;
  453. }
  454. if (! LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  455. {
  456. DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable");
  457. }
  458. uint hints = 0x0;
  459. uint audioIns = 0;
  460. uint audioOuts = 0;
  461. uint midiIns = 0;
  462. uint parametersIns = 0;
  463. uint parametersOuts = 0;
  464. uint parametersTotal = 0;
  465. if (LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  466. hints |= PLUGIN_IS_RTSAFE;
  467. for (unsigned long j=0; j < ldescriptor->PortCount; ++j)
  468. {
  469. CARLA_ASSERT(ldescriptor->PortNames[j] != nullptr);
  470. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  471. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  472. {
  473. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  474. audioIns += 1;
  475. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  476. audioOuts += 1;
  477. }
  478. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  479. {
  480. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  481. parametersIns += 1;
  482. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(ldescriptor->PortNames[j], "latency") != 0 && std::strcmp(ldescriptor->PortNames[j], "_latency") != 0)
  483. parametersOuts += 1;
  484. parametersTotal += 1;
  485. }
  486. }
  487. if (descriptor->run_synth != nullptr)
  488. midiIns = 1;
  489. if (midiIns > 0 && audioIns == 0 && audioOuts > 0)
  490. hints |= PLUGIN_IS_SYNTH;
  491. #ifndef BUILD_BRIDGE
  492. if (const char* const ui = find_dssi_ui(filename, ldescriptor->Label))
  493. {
  494. hints |= PLUGIN_HAS_CUSTOM_UI;
  495. delete[] ui;
  496. }
  497. #endif
  498. if (doInit)
  499. {
  500. // -----------------------------------------------------------------------
  501. // start crash-free plugin test
  502. LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  503. if (handle == nullptr)
  504. {
  505. DISCOVERY_OUT("error", "Failed to init DSSI plugin");
  506. continue;
  507. }
  508. // Test quick init and cleanup
  509. ldescriptor->cleanup(handle);
  510. handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  511. if (handle == nullptr)
  512. {
  513. DISCOVERY_OUT("error", "Failed to init DSSI plugin (#2)");
  514. continue;
  515. }
  516. LADSPA_Data bufferAudio[kBufferSize][std::max(1u, audioIns + audioOuts)];
  517. LADSPA_Data bufferParams[parametersTotal];
  518. LADSPA_Data min, max, def;
  519. for (unsigned long j=0, iA=0, iC=0; j < ldescriptor->PortCount; ++j)
  520. {
  521. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  522. const LADSPA_PortRangeHint portRangeHints = ldescriptor->PortRangeHints[j];
  523. const char* const portName = ldescriptor->PortNames[j];
  524. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  525. {
  526. carla_zeroFloats(bufferAudio[iA], kBufferSize);
  527. ldescriptor->connect_port(handle, j, bufferAudio[iA++]);
  528. }
  529. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  530. {
  531. // min value
  532. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  533. min = portRangeHints.LowerBound;
  534. else
  535. min = 0.0f;
  536. // max value
  537. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  538. max = portRangeHints.UpperBound;
  539. else
  540. max = 1.0f;
  541. if (min > max)
  542. {
  543. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  544. max = min + 0.1f;
  545. }
  546. else if (carla_isEqual(min, max))
  547. {
  548. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max == min");
  549. max = min + 0.1f;
  550. }
  551. // default value
  552. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  553. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  554. {
  555. min *= kSampleRatef;
  556. max *= kSampleRatef;
  557. def *= kSampleRatef;
  558. }
  559. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  560. {
  561. // latency parameter
  562. def = 0.0f;
  563. }
  564. else
  565. {
  566. if (def < min)
  567. def = min;
  568. else if (def > max)
  569. def = max;
  570. }
  571. bufferParams[iC] = def;
  572. ldescriptor->connect_port(handle, j, &bufferParams[iC++]);
  573. }
  574. }
  575. // select first midi-program if available
  576. if (descriptor->get_program != nullptr && descriptor->select_program != nullptr)
  577. {
  578. if (const DSSI_Program_Descriptor* const pDesc = descriptor->get_program(handle, 0))
  579. descriptor->select_program(handle, pDesc->Bank, pDesc->Program);
  580. }
  581. if (ldescriptor->activate != nullptr)
  582. ldescriptor->activate(handle);
  583. if (descriptor->run_synth != nullptr)
  584. {
  585. snd_seq_event_t midiEvents[2];
  586. carla_zeroStructs(midiEvents, 2);
  587. const unsigned long midiEventCount = 2;
  588. midiEvents[0].type = SND_SEQ_EVENT_NOTEON;
  589. midiEvents[0].data.note.note = 64;
  590. midiEvents[0].data.note.velocity = 100;
  591. midiEvents[1].type = SND_SEQ_EVENT_NOTEOFF;
  592. midiEvents[1].data.note.note = 64;
  593. midiEvents[1].data.note.velocity = 0;
  594. midiEvents[1].time.tick = kBufferSize/2;
  595. descriptor->run_synth(handle, kBufferSize, midiEvents, midiEventCount);
  596. }
  597. else
  598. ldescriptor->run(handle, kBufferSize);
  599. if (ldescriptor->deactivate != nullptr)
  600. ldescriptor->deactivate(handle);
  601. ldescriptor->cleanup(handle);
  602. // end crash-free plugin test
  603. // -----------------------------------------------------------------------
  604. }
  605. DISCOVERY_OUT("init", "-----------");
  606. DISCOVERY_OUT("build", BINARY_NATIVE);
  607. DISCOVERY_OUT("category", ((hints & PLUGIN_IS_SYNTH)
  608. ? "synth"
  609. : getPluginCategoryAsString(getPluginCategoryFromName(ldescriptor->Name))));
  610. DISCOVERY_OUT("hints", hints);
  611. DISCOVERY_OUT("name", ldescriptor->Name);
  612. DISCOVERY_OUT("label", ldescriptor->Label);
  613. DISCOVERY_OUT("maker", ldescriptor->Maker);
  614. DISCOVERY_OUT("uniqueId", ldescriptor->UniqueID);
  615. DISCOVERY_OUT("audio.ins", audioIns);
  616. DISCOVERY_OUT("audio.outs", audioOuts);
  617. DISCOVERY_OUT("midi.ins", midiIns);
  618. DISCOVERY_OUT("parameters.ins", parametersIns);
  619. DISCOVERY_OUT("parameters.outs", parametersOuts);
  620. DISCOVERY_OUT("end", "------------");
  621. }
  622. }
  623. #ifndef BUILD_BRIDGE
  624. static void do_lv2_check(const char* const bundle, const bool doInit)
  625. {
  626. Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
  627. Lilv::Node bundleNode(lv2World.new_file_uri(nullptr, bundle));
  628. CARLA_SAFE_ASSERT_RETURN(bundleNode.is_uri(),);
  629. CarlaString sBundle(bundleNode.as_uri());
  630. if (! sBundle.endsWith("/"))
  631. sBundle += "/";
  632. // Load bundle
  633. lv2World.load_bundle(sBundle);
  634. // Load plugins in this bundle
  635. const Lilv::Plugins lilvPlugins(lv2World.get_all_plugins());
  636. // Get all plugin URIs in this bundle
  637. CarlaStringList URIs;
  638. LILV_FOREACH(plugins, it, lilvPlugins)
  639. {
  640. Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, it));
  641. if (const char* const uri = lilvPlugin.get_uri().as_string())
  642. URIs.appendUnique(uri);
  643. }
  644. if (URIs.isEmpty())
  645. {
  646. DISCOVERY_OUT("warning", "LV2 Bundle doesn't provide any plugins");
  647. return;
  648. }
  649. // Get & check every plugin-instance
  650. for (CarlaStringList::Itenerator it=URIs.begin2(); it.valid(); it.next())
  651. {
  652. const char* const URI = it.getValue(nullptr);
  653. CARLA_SAFE_ASSERT_CONTINUE(URI != nullptr);
  654. CarlaScopedPointer<const LV2_RDF_Descriptor> rdfDescriptor(lv2_rdf_new(URI, false));
  655. if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr)
  656. {
  657. DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URI << "'");
  658. continue;
  659. }
  660. if (doInit)
  661. {
  662. // test if lib is loadable, twice
  663. const lib_t libHandle1 = lib_open(rdfDescriptor->Binary);
  664. if (libHandle1 == nullptr)
  665. {
  666. print_lib_error(rdfDescriptor->Binary);
  667. delete rdfDescriptor;
  668. continue;
  669. }
  670. lib_close(libHandle1);
  671. const lib_t libHandle2 = lib_open(rdfDescriptor->Binary);
  672. if (libHandle2 == nullptr)
  673. {
  674. print_lib_error(rdfDescriptor->Binary);
  675. delete rdfDescriptor;
  676. continue;
  677. }
  678. lib_close(libHandle2);
  679. }
  680. const LilvPlugin* const cPlugin(lv2World.getPluginFromURI(URI));
  681. CARLA_SAFE_ASSERT_CONTINUE(cPlugin != nullptr);
  682. Lilv::Plugin lilvPlugin(cPlugin);
  683. CARLA_SAFE_ASSERT_CONTINUE(lilvPlugin.get_uri().is_uri());
  684. print_cached_plugin(get_cached_plugin_lv2(lv2World, lilvPlugin));
  685. }
  686. }
  687. #endif
  688. #ifndef USING_JUCE_FOR_VST2
  689. // --------------------------------------------------------------------------------------------------------------------
  690. // VST stuff
  691. // Check if plugin is currently processing
  692. static bool gVstIsProcessing = false;
  693. // Check if plugin needs idle
  694. static bool gVstNeedsIdle = false;
  695. // Check if plugin wants midi
  696. static bool gVstWantsMidi = false;
  697. // Check if plugin wants time
  698. static bool gVstWantsTime = false;
  699. // Current uniqueId for VST shell plugins
  700. static intptr_t gVstCurrentUniqueId = 0;
  701. // Supported Carla features
  702. static intptr_t vstHostCanDo(const char* const feature)
  703. {
  704. carla_debug("vstHostCanDo(\"%s\")", feature);
  705. if (std::strcmp(feature, "supplyIdle") == 0)
  706. return 1;
  707. if (std::strcmp(feature, "sendVstEvents") == 0)
  708. return 1;
  709. if (std::strcmp(feature, "sendVstMidiEvent") == 0)
  710. return 1;
  711. if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
  712. return 1;
  713. if (std::strcmp(feature, "sendVstTimeInfo") == 0)
  714. {
  715. gVstWantsTime = true;
  716. return 1;
  717. }
  718. if (std::strcmp(feature, "receiveVstEvents") == 0)
  719. return 1;
  720. if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
  721. return 1;
  722. if (std::strcmp(feature, "receiveVstTimeInfo") == 0)
  723. return -1;
  724. if (std::strcmp(feature, "reportConnectionChanges") == 0)
  725. return -1;
  726. if (std::strcmp(feature, "acceptIOChanges") == 0)
  727. return 1;
  728. if (std::strcmp(feature, "sizeWindow") == 0)
  729. return 1;
  730. if (std::strcmp(feature, "offline") == 0)
  731. return -1;
  732. if (std::strcmp(feature, "openFileSelector") == 0)
  733. return -1;
  734. if (std::strcmp(feature, "closeFileSelector") == 0)
  735. return -1;
  736. if (std::strcmp(feature, "startStopProcess") == 0)
  737. return 1;
  738. if (std::strcmp(feature, "supportShell") == 0)
  739. return 1;
  740. if (std::strcmp(feature, "shellCategory") == 0)
  741. return 1;
  742. if (std::strcmp(feature, "NIMKPIVendorSpecificCallbacks") == 0)
  743. return -1;
  744. // non-official features found in some plugins:
  745. // "asyncProcessing"
  746. // "editFile"
  747. // unimplemented
  748. carla_stderr("vstHostCanDo(\"%s\") - unknown feature", feature);
  749. return 0;
  750. }
  751. // Host-side callback
  752. static intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  753. {
  754. carla_debug("vstHostCallback(%p, %i:%s, %i, " P_INTPTR ", %p, %f)",
  755. effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  756. static VstTimeInfo timeInfo;
  757. intptr_t ret = 0;
  758. switch (opcode)
  759. {
  760. case audioMasterAutomate:
  761. ret = 1;
  762. break;
  763. case audioMasterVersion:
  764. ret = kVstVersion;
  765. break;
  766. case audioMasterCurrentId:
  767. ret = gVstCurrentUniqueId;
  768. break;
  769. case DECLARE_VST_DEPRECATED(audioMasterWantMidi):
  770. if (gVstWantsMidi) { DISCOVERY_OUT("warning", "Plugin requested MIDI more than once"); }
  771. gVstWantsMidi = true;
  772. ret = 1;
  773. break;
  774. case audioMasterGetTime:
  775. if (! gVstIsProcessing) { DISCOVERY_OUT("warning", "Plugin requested timeInfo out of process"); }
  776. if (! gVstWantsTime) { DISCOVERY_OUT("warning", "Plugin requested timeInfo but didn't ask if host could do \"sendVstTimeInfo\""); }
  777. carla_zeroStruct(timeInfo);
  778. timeInfo.sampleRate = kSampleRate;
  779. // Tempo
  780. timeInfo.tempo = 120.0;
  781. timeInfo.flags |= kVstTempoValid;
  782. // Time Signature
  783. timeInfo.timeSigNumerator = 4;
  784. timeInfo.timeSigDenominator = 4;
  785. timeInfo.flags |= kVstTimeSigValid;
  786. ret = (intptr_t)&timeInfo;
  787. break;
  788. case DECLARE_VST_DEPRECATED(audioMasterTempoAt):
  789. ret = 120 * 10000;
  790. break;
  791. case DECLARE_VST_DEPRECATED(audioMasterGetNumAutomatableParameters):
  792. ret = carla_minPositive(effect->numParams, static_cast<int>(MAX_DEFAULT_PARAMETERS));
  793. break;
  794. case DECLARE_VST_DEPRECATED(audioMasterGetParameterQuantization):
  795. ret = 1; // full single float precision
  796. break;
  797. case DECLARE_VST_DEPRECATED(audioMasterNeedIdle):
  798. if (gVstNeedsIdle) { DISCOVERY_OUT("warning", "Plugin requested idle more than once"); }
  799. gVstNeedsIdle = true;
  800. ret = 1;
  801. break;
  802. case audioMasterGetSampleRate:
  803. ret = kSampleRatei;
  804. break;
  805. case audioMasterGetBlockSize:
  806. ret = kBufferSize;
  807. break;
  808. case DECLARE_VST_DEPRECATED(audioMasterWillReplaceOrAccumulate):
  809. ret = 1; // replace
  810. break;
  811. case audioMasterGetCurrentProcessLevel:
  812. ret = gVstIsProcessing ? kVstProcessLevelRealtime : kVstProcessLevelUser;
  813. break;
  814. case audioMasterGetAutomationState:
  815. ret = kVstAutomationOff;
  816. break;
  817. case audioMasterGetVendorString:
  818. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  819. std::strcpy((char*)ptr, "falkTX");
  820. ret = 1;
  821. break;
  822. case audioMasterGetProductString:
  823. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  824. std::strcpy((char*)ptr, "Carla-Discovery");
  825. ret = 1;
  826. break;
  827. case audioMasterGetVendorVersion:
  828. ret = CARLA_VERSION_HEX;
  829. break;
  830. case audioMasterCanDo:
  831. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  832. ret = vstHostCanDo((const char*)ptr);
  833. break;
  834. case audioMasterGetLanguage:
  835. ret = kVstLangEnglish;
  836. break;
  837. default:
  838. carla_stdout("vstHostCallback(%p, %i:%s, %i, " P_INTPTR ", %p, %f)",
  839. effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  840. break;
  841. }
  842. return ret;
  843. }
  844. static bool do_vst2_check(lib_t& libHandle, const char* const filename, const bool doInit)
  845. {
  846. VST_Function vstFn = nullptr;
  847. #ifdef CARLA_OS_MAC
  848. BundleLoader bundleLoader;
  849. if (libHandle == nullptr)
  850. {
  851. if (! bundleLoader.load(filename))
  852. {
  853. #ifdef __aarch64__
  854. return true;
  855. #else
  856. DISCOVERY_OUT("error", "Failed to load VST2 bundle executable");
  857. return false;
  858. #endif
  859. }
  860. vstFn = (VST_Function)CFBundleGetFunctionPointerForName(bundleLoader.getRef(), CFSTR("main_macho"));
  861. if (vstFn == nullptr)
  862. vstFn = (VST_Function)CFBundleGetFunctionPointerForName(bundleLoader.getRef(), CFSTR("VSTPluginMain"));
  863. if (vstFn == nullptr)
  864. {
  865. DISCOVERY_OUT("error", "Not a VST2 plugin");
  866. return false;
  867. }
  868. }
  869. else
  870. #endif
  871. {
  872. vstFn = lib_symbol<VST_Function>(libHandle, "VSTPluginMain");
  873. if (vstFn == nullptr)
  874. {
  875. vstFn = lib_symbol<VST_Function>(libHandle, "main");
  876. if (vstFn == nullptr)
  877. {
  878. DISCOVERY_OUT("error", "Not a VST plugin");
  879. return false;
  880. }
  881. }
  882. }
  883. AEffect* effect = vstFn(vstHostCallback);
  884. if (effect == nullptr || effect->magic != kEffectMagic)
  885. {
  886. DISCOVERY_OUT("error", "Failed to init VST plugin, or VST magic failed");
  887. return false;
  888. }
  889. if (effect->uniqueID == 0)
  890. {
  891. DISCOVERY_OUT("warning", "Plugin doesn't have an Unique ID when first loaded");
  892. }
  893. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdentify), 0, 0, nullptr, 0.0f);
  894. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effSetBlockSizeAndSampleRate), 0, kBufferSize, nullptr, kSampleRatef);
  895. effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRatef);
  896. effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
  897. effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  898. effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
  899. if (effect->numPrograms > 0)
  900. effect->dispatcher(effect, effSetProgram, 0, 0, nullptr, 0.0f);
  901. const bool isShell = (effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f) == kPlugCategShell);
  902. if (effect->uniqueID == 0 && !isShell)
  903. {
  904. DISCOVERY_OUT("error", "Plugin doesn't have an Unique ID after being open");
  905. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  906. return false;
  907. }
  908. gVstCurrentUniqueId = effect->uniqueID;
  909. char strBuf[STR_MAX+1];
  910. CarlaString cName;
  911. CarlaString cProduct;
  912. CarlaString cVendor;
  913. PluginCategory category;
  914. LinkedList<intptr_t> uniqueIds;
  915. if (isShell)
  916. {
  917. for (;;)
  918. {
  919. carla_zeroChars(strBuf, STR_MAX+1);
  920. gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);
  921. if (gVstCurrentUniqueId == 0)
  922. break;
  923. uniqueIds.append(gVstCurrentUniqueId);
  924. }
  925. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  926. effect = nullptr;
  927. }
  928. else
  929. {
  930. uniqueIds.append(gVstCurrentUniqueId);
  931. }
  932. for (LinkedList<intptr_t>::Itenerator it = uniqueIds.begin2(); it.valid(); it.next())
  933. {
  934. gVstCurrentUniqueId = it.getValue(0);
  935. if (effect == nullptr)
  936. {
  937. effect = vstFn(vstHostCallback);
  938. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdentify), 0, 0, nullptr, 0.0f);
  939. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effSetBlockSizeAndSampleRate), 0, kBufferSize, nullptr, kSampleRatef);
  940. effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRatef);
  941. effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
  942. effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  943. effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
  944. if (effect->numPrograms > 0)
  945. effect->dispatcher(effect, effSetProgram, 0, 0, nullptr, 0.0f);
  946. }
  947. // get name
  948. carla_zeroChars(strBuf, STR_MAX+1);
  949. if (effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f) == 1)
  950. cName = strBuf;
  951. else
  952. cName.clear();
  953. // get product
  954. carla_zeroChars(strBuf, STR_MAX+1);
  955. if (effect->dispatcher(effect, effGetProductString, 0, 0, strBuf, 0.0f) == 1)
  956. cProduct = strBuf;
  957. else
  958. cProduct.clear();
  959. // get vendor
  960. carla_zeroChars(strBuf, STR_MAX+1);
  961. if (effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f) == 1)
  962. cVendor = strBuf;
  963. else
  964. cVendor.clear();
  965. // get category
  966. switch (effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f))
  967. {
  968. case kPlugCategSynth:
  969. category = PLUGIN_CATEGORY_SYNTH;
  970. break;
  971. case kPlugCategAnalysis:
  972. category = PLUGIN_CATEGORY_UTILITY;
  973. break;
  974. case kPlugCategMastering:
  975. category = PLUGIN_CATEGORY_DYNAMICS;
  976. break;
  977. case kPlugCategRoomFx:
  978. category = PLUGIN_CATEGORY_DELAY;
  979. break;
  980. case kPlugCategRestoration:
  981. category = PLUGIN_CATEGORY_UTILITY;
  982. break;
  983. case kPlugCategGenerator:
  984. category = PLUGIN_CATEGORY_SYNTH;
  985. break;
  986. default:
  987. if (effect->flags & effFlagsIsSynth)
  988. category = PLUGIN_CATEGORY_SYNTH;
  989. else
  990. category = PLUGIN_CATEGORY_NONE;
  991. break;
  992. }
  993. // get everything else
  994. uint hints = 0x0;
  995. uint audioIns = static_cast<uint>(std::max(0, effect->numInputs));
  996. uint audioOuts = static_cast<uint>(std::max(0, effect->numOutputs));
  997. uint midiIns = 0;
  998. uint midiOuts = 0;
  999. uint parameters = static_cast<uint>(std::max(0, effect->numParams));
  1000. if (effect->flags & effFlagsHasEditor)
  1001. hints |= PLUGIN_HAS_CUSTOM_UI;
  1002. if (effect->flags & effFlagsIsSynth)
  1003. {
  1004. hints |= PLUGIN_IS_SYNTH;
  1005. midiIns = 1;
  1006. }
  1007. if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || (effect->flags & effFlagsIsSynth) != 0)
  1008. midiIns = 1;
  1009. if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent"))
  1010. midiOuts = 1;
  1011. // -----------------------------------------------------------------------
  1012. // start crash-free plugin test
  1013. if (doInit)
  1014. {
  1015. if (gVstNeedsIdle)
  1016. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1017. effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
  1018. effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
  1019. if (gVstNeedsIdle)
  1020. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1021. // Plugin might call wantMidi() during resume
  1022. if (midiIns == 0 && gVstWantsMidi)
  1023. {
  1024. midiIns = 1;
  1025. }
  1026. float* bufferAudioIn[std::max(1U, audioIns)];
  1027. float* bufferAudioOut[std::max(1U, audioOuts)];
  1028. if (audioIns == 0)
  1029. {
  1030. bufferAudioIn[0] = nullptr;
  1031. }
  1032. else
  1033. {
  1034. for (uint j=0; j < audioIns; ++j)
  1035. {
  1036. bufferAudioIn[j] = new float[kBufferSize];
  1037. carla_zeroFloats(bufferAudioIn[j], kBufferSize);
  1038. }
  1039. }
  1040. if (audioOuts == 0)
  1041. {
  1042. bufferAudioOut[0] = nullptr;
  1043. }
  1044. else
  1045. {
  1046. for (uint j=0; j < audioOuts; ++j)
  1047. {
  1048. bufferAudioOut[j] = new float[kBufferSize];
  1049. carla_zeroFloats(bufferAudioOut[j], kBufferSize);
  1050. }
  1051. }
  1052. struct VstEventsFixed {
  1053. int32_t numEvents;
  1054. intptr_t reserved;
  1055. VstEvent* data[2];
  1056. VstEventsFixed()
  1057. : numEvents(0),
  1058. reserved(0)
  1059. {
  1060. data[0] = data[1] = nullptr;
  1061. }
  1062. } events;
  1063. VstMidiEvent midiEvents[2];
  1064. carla_zeroStructs(midiEvents, 2);
  1065. midiEvents[0].type = kVstMidiType;
  1066. midiEvents[0].byteSize = sizeof(VstMidiEvent);
  1067. midiEvents[0].midiData[0] = char(MIDI_STATUS_NOTE_ON);
  1068. midiEvents[0].midiData[1] = 64;
  1069. midiEvents[0].midiData[2] = 100;
  1070. midiEvents[1].type = kVstMidiType;
  1071. midiEvents[1].byteSize = sizeof(VstMidiEvent);
  1072. midiEvents[1].midiData[0] = char(MIDI_STATUS_NOTE_OFF);
  1073. midiEvents[1].midiData[1] = 64;
  1074. midiEvents[1].deltaFrames = kBufferSize/2;
  1075. events.numEvents = 2;
  1076. events.data[0] = (VstEvent*)&midiEvents[0];
  1077. events.data[1] = (VstEvent*)&midiEvents[1];
  1078. // processing
  1079. gVstIsProcessing = true;
  1080. if (midiIns > 0)
  1081. effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);
  1082. if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing != nullptr && effect->processReplacing != effect->DECLARE_VST_DEPRECATED(process))
  1083. effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
  1084. else if (effect->DECLARE_VST_DEPRECATED(process) != nullptr)
  1085. effect->DECLARE_VST_DEPRECATED(process)(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
  1086. else
  1087. DISCOVERY_OUT("error", "Plugin doesn't have a process function");
  1088. gVstIsProcessing = false;
  1089. effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
  1090. effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
  1091. if (gVstNeedsIdle)
  1092. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1093. for (uint j=0; j < audioIns; ++j)
  1094. delete[] bufferAudioIn[j];
  1095. for (uint j=0; j < audioOuts; ++j)
  1096. delete[] bufferAudioOut[j];
  1097. }
  1098. // end crash-free plugin test
  1099. // -----------------------------------------------------------------------
  1100. DISCOVERY_OUT("init", "-----------");
  1101. DISCOVERY_OUT("build", BINARY_NATIVE);
  1102. DISCOVERY_OUT("hints", hints);
  1103. DISCOVERY_OUT("category", getPluginCategoryAsString(category));
  1104. DISCOVERY_OUT("name", cName.buffer());
  1105. DISCOVERY_OUT("label", cProduct.buffer());
  1106. DISCOVERY_OUT("maker", cVendor.buffer());
  1107. DISCOVERY_OUT("uniqueId", gVstCurrentUniqueId);
  1108. DISCOVERY_OUT("audio.ins", audioIns);
  1109. DISCOVERY_OUT("audio.outs", audioOuts);
  1110. DISCOVERY_OUT("midi.ins", midiIns);
  1111. DISCOVERY_OUT("midi.outs", midiOuts);
  1112. DISCOVERY_OUT("parameters.ins", parameters);
  1113. DISCOVERY_OUT("end", "------------");
  1114. gVstWantsMidi = false;
  1115. gVstWantsTime = false;
  1116. if (! isShell)
  1117. break;
  1118. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  1119. effect = nullptr;
  1120. }
  1121. uniqueIds.clear();
  1122. if (effect != nullptr)
  1123. {
  1124. if (gVstNeedsIdle)
  1125. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1126. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  1127. }
  1128. return false;
  1129. #ifndef CARLA_OS_MAC
  1130. // unused
  1131. (void)filename;
  1132. #endif
  1133. }
  1134. #endif // ! USING_JUCE_FOR_VST2
  1135. #ifndef USING_JUCE_FOR_VST3
  1136. static uint32_t V3_API v3_ref_static(void*) { return 1; }
  1137. static uint32_t V3_API v3_unref_static(void*) { return 0; }
  1138. struct carla_v3_host_application : v3_host_application_cpp {
  1139. carla_v3_host_application()
  1140. {
  1141. query_interface = carla_query_interface;
  1142. ref = v3_ref_static;
  1143. unref = v3_unref_static;
  1144. app.get_name = carla_get_name;
  1145. app.create_instance = carla_create_instance;
  1146. }
  1147. static v3_result V3_API carla_query_interface(void* const self, const v3_tuid iid, void** const iface)
  1148. {
  1149. if (v3_tuid_match(iid, v3_funknown_iid) ||
  1150. v3_tuid_match(iid, v3_host_application_iid))
  1151. {
  1152. *iface = self;
  1153. return V3_OK;
  1154. }
  1155. *iface = nullptr;
  1156. return V3_NO_INTERFACE;
  1157. }
  1158. static v3_result V3_API carla_get_name(void*, v3_str_128 name)
  1159. {
  1160. static const char hostname[] = "Carla-Discovery\0";
  1161. for (size_t i=0; i<sizeof(hostname); ++i)
  1162. name[i] = hostname[i];
  1163. return V3_OK;
  1164. }
  1165. static v3_result V3_API carla_create_instance(void*, v3_tuid, v3_tuid, void**) { return V3_NOT_IMPLEMENTED; }
  1166. };
  1167. struct carla_v3_param_changes : v3_param_changes_cpp {
  1168. carla_v3_param_changes()
  1169. {
  1170. query_interface = carla_query_interface;
  1171. ref = v3_ref_static;
  1172. unref = v3_unref_static;
  1173. changes.get_param_count = carla_get_param_count;
  1174. changes.get_param_data = carla_get_param_data;
  1175. changes.add_param_data = carla_add_param_data;
  1176. }
  1177. static v3_result V3_API carla_query_interface(void* const self, const v3_tuid iid, void** const iface)
  1178. {
  1179. if (v3_tuid_match(iid, v3_funknown_iid) ||
  1180. v3_tuid_match(iid, v3_param_changes_iid))
  1181. {
  1182. *iface = self;
  1183. return V3_OK;
  1184. }
  1185. *iface = nullptr;
  1186. return V3_NO_INTERFACE;
  1187. }
  1188. static int32_t V3_API carla_get_param_count(void*) { return 0; }
  1189. static v3_param_value_queue** V3_API carla_get_param_data(void*, int32_t) { return nullptr; }
  1190. static v3_param_value_queue** V3_API carla_add_param_data(void*, v3_param_id*, int32_t*) { return nullptr; }
  1191. };
  1192. struct carla_v3_event_list : v3_event_list_cpp {
  1193. carla_v3_event_list()
  1194. {
  1195. query_interface = carla_query_interface;
  1196. ref = v3_ref_static;
  1197. unref = v3_unref_static;
  1198. list.get_event_count = carla_get_event_count;
  1199. list.get_event = carla_get_event;
  1200. list.add_event = carla_add_event;
  1201. }
  1202. static v3_result V3_API carla_query_interface(void* const self, const v3_tuid iid, void** const iface)
  1203. {
  1204. if (v3_tuid_match(iid, v3_funknown_iid) ||
  1205. v3_tuid_match(iid, v3_event_list_iid))
  1206. {
  1207. *iface = self;
  1208. return V3_OK;
  1209. }
  1210. *iface = nullptr;
  1211. return V3_NO_INTERFACE;
  1212. }
  1213. static uint32_t V3_API carla_get_event_count(void*) { return 0; }
  1214. static v3_result V3_API carla_get_event(void*, int32_t, v3_event*) { return V3_NOT_IMPLEMENTED; }
  1215. static v3_result V3_API carla_add_event(void*, v3_event*) { return V3_NOT_IMPLEMENTED; }
  1216. };
  1217. static bool v3_exit_false(const V3_EXITFN v3_exit)
  1218. {
  1219. v3_exit();
  1220. return false;
  1221. }
  1222. static bool do_vst3_check(lib_t& libHandle, const char* const filename, const bool doInit)
  1223. {
  1224. V3_ENTRYFN v3_entry = nullptr;
  1225. V3_EXITFN v3_exit = nullptr;
  1226. V3_GETFN v3_get = nullptr;
  1227. #ifdef CARLA_OS_MAC
  1228. BundleLoader bundleLoader;
  1229. #endif
  1230. // if passed filename is not a plugin binary directly, inspect bundle and find one
  1231. if (libHandle == nullptr)
  1232. {
  1233. #ifdef CARLA_OS_MAC
  1234. if (! bundleLoader.load(filename))
  1235. {
  1236. #ifdef __aarch64__
  1237. return true;
  1238. #else
  1239. DISCOVERY_OUT("error", "Failed to load VST3 bundle executable");
  1240. return false;
  1241. #endif
  1242. }
  1243. v3_entry = (V3_ENTRYFN)CFBundleGetFunctionPointerForName(bundleLoader.getRef(), CFSTR(V3_ENTRYFNNAME));
  1244. v3_exit = (V3_EXITFN)CFBundleGetFunctionPointerForName(bundleLoader.getRef(), CFSTR(V3_EXITFNNAME));
  1245. v3_get = (V3_GETFN)CFBundleGetFunctionPointerForName(bundleLoader.getRef(), CFSTR(V3_GETFNNAME));
  1246. #else
  1247. water::String binaryfilename = filename;
  1248. if (!binaryfilename.endsWithChar(CARLA_OS_SEP))
  1249. binaryfilename += CARLA_OS_SEP_STR;
  1250. binaryfilename += "Contents" CARLA_OS_SEP_STR V3_CONTENT_DIR CARLA_OS_SEP_STR;
  1251. binaryfilename += water::File(filename).getFileNameWithoutExtension();
  1252. # ifdef CARLA_OS_WIN
  1253. binaryfilename += ".vst3";
  1254. # else
  1255. binaryfilename += ".so";
  1256. # endif
  1257. if (! water::File(binaryfilename).existsAsFile())
  1258. {
  1259. DISCOVERY_OUT("error", "Failed to find a suitable VST3 bundle binary");
  1260. return false;
  1261. }
  1262. libHandle = lib_open(binaryfilename.toRawUTF8());
  1263. if (libHandle == nullptr)
  1264. {
  1265. print_lib_error(filename);
  1266. return false;
  1267. }
  1268. #endif
  1269. }
  1270. #ifndef CARLA_OS_MAC
  1271. v3_entry = lib_symbol<V3_ENTRYFN>(libHandle, V3_ENTRYFNNAME);
  1272. v3_exit = lib_symbol<V3_EXITFN>(libHandle, V3_EXITFNNAME);
  1273. v3_get = lib_symbol<V3_GETFN>(libHandle, V3_GETFNNAME);
  1274. #endif
  1275. // ensure entry and exit points are available
  1276. if (v3_entry == nullptr || v3_exit == nullptr || v3_get == nullptr)
  1277. {
  1278. DISCOVERY_OUT("error", "Not a VST3 plugin");
  1279. return false;
  1280. }
  1281. // call entry point
  1282. #if defined(CARLA_OS_MAC)
  1283. v3_entry(bundleLoader.getRef());
  1284. #elif defined(CARLA_OS_WIN)
  1285. v3_entry();
  1286. #else
  1287. v3_entry(libHandle);
  1288. #endif
  1289. carla_v3_host_application hostApplication;
  1290. carla_v3_host_application* hostApplicationPtr = &hostApplication;
  1291. v3_funknown** const hostContext = (v3_funknown**)&hostApplicationPtr;
  1292. // fetch initial factory
  1293. v3_plugin_factory** factory1 = v3_get();
  1294. CARLA_SAFE_ASSERT_RETURN(factory1 != nullptr, v3_exit_false(v3_exit));
  1295. // get factory info
  1296. v3_factory_info factoryInfo = {};
  1297. CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(factory1)->get_factory_info(factory1, &factoryInfo) == V3_OK, v3_exit_false(v3_exit));
  1298. // get num classes
  1299. const int32_t numClasses = v3_cpp_obj(factory1)->num_classes(factory1);
  1300. CARLA_SAFE_ASSERT_RETURN(numClasses > 0, v3_exit_false(v3_exit));
  1301. // query 2nd factory
  1302. v3_plugin_factory_2** factory2 = nullptr;
  1303. if (v3_cpp_obj_query_interface(factory1, v3_plugin_factory_2_iid, &factory2) == V3_OK)
  1304. {
  1305. CARLA_SAFE_ASSERT_RETURN(factory2 != nullptr, v3_exit_false(v3_exit));
  1306. }
  1307. else
  1308. {
  1309. CARLA_SAFE_ASSERT(factory2 == nullptr);
  1310. factory2 = nullptr;
  1311. }
  1312. // query 3rd factory
  1313. v3_plugin_factory_3** factory3 = nullptr;
  1314. if (factory2 != nullptr && v3_cpp_obj_query_interface(factory2, v3_plugin_factory_3_iid, &factory3) == V3_OK)
  1315. {
  1316. CARLA_SAFE_ASSERT_RETURN(factory3 != nullptr, v3_exit_false(v3_exit));
  1317. }
  1318. else
  1319. {
  1320. CARLA_SAFE_ASSERT(factory3 == nullptr);
  1321. factory3 = nullptr;
  1322. }
  1323. // set host context (application) if 3rd factory provided
  1324. if (factory3 != nullptr)
  1325. v3_cpp_obj(factory3)->set_host_context(factory3, hostContext);
  1326. // go through all relevant classes
  1327. for (int32_t i=0; i<numClasses; ++i)
  1328. {
  1329. // v3_class_info_2 is ABI compatible with v3_class_info
  1330. union {
  1331. v3_class_info v1;
  1332. v3_class_info_2 v2;
  1333. } classInfo = {};
  1334. if (factory2 != nullptr)
  1335. v3_cpp_obj(factory2)->get_class_info_2(factory2, i, &classInfo.v2);
  1336. else
  1337. v3_cpp_obj(factory1)->get_class_info(factory1, i, &classInfo.v1);
  1338. // safety check
  1339. CARLA_SAFE_ASSERT_CONTINUE(classInfo.v1.cardinality == 0x7FFFFFFF);
  1340. // only check for audio plugins
  1341. if (std::strcmp(classInfo.v1.category, "Audio Module Class") != 0)
  1342. continue;
  1343. // create instance
  1344. void* instance = nullptr;
  1345. CARLA_SAFE_ASSERT_CONTINUE(v3_cpp_obj(factory1)->create_instance(factory1, classInfo.v1.class_id, v3_component_iid, &instance) == V3_OK);
  1346. CARLA_SAFE_ASSERT_CONTINUE(instance != nullptr);
  1347. // initialize instance
  1348. v3_component** const component = static_cast<v3_component**>(instance);
  1349. CARLA_SAFE_ASSERT_CONTINUE(v3_cpp_obj_initialize(component, hostContext) == V3_OK);
  1350. // create edit controller
  1351. v3_edit_controller** controller = nullptr;
  1352. bool shouldTerminateController;
  1353. if (v3_cpp_obj_query_interface(component, v3_edit_controller_iid, &controller) != V3_OK)
  1354. controller = nullptr;
  1355. if (controller != nullptr)
  1356. {
  1357. // got edit controller from casting component, assume they belong to the same object
  1358. shouldTerminateController = false;
  1359. }
  1360. else
  1361. {
  1362. // try to create edit controller from factory
  1363. v3_tuid uid = {};
  1364. if (v3_cpp_obj(component)->get_controller_class_id(component, uid) == V3_OK)
  1365. {
  1366. instance = nullptr;
  1367. if (v3_cpp_obj(factory1)->create_instance(factory1, uid, v3_edit_controller_iid, &instance) == V3_OK && instance != nullptr)
  1368. controller = static_cast<v3_edit_controller**>(instance);
  1369. }
  1370. if (controller == nullptr)
  1371. {
  1372. DISCOVERY_OUT("warning", "Plugin '" << classInfo.v1.name << "' does not have an edit controller");
  1373. v3_cpp_obj_terminate(component);
  1374. v3_cpp_obj_unref(component);
  1375. continue;
  1376. }
  1377. // component is separate from controller, needs its dedicated initialize and terminate
  1378. shouldTerminateController = true;
  1379. v3_cpp_obj_initialize(controller, hostContext);
  1380. }
  1381. // fill in all the details
  1382. uint hints = 0x0;
  1383. int audioIns = 0;
  1384. int audioOuts = 0;
  1385. int cvIns = 0;
  1386. int cvOuts = 0;
  1387. int parameterIns = 0;
  1388. int parameterOuts = 0;
  1389. const int32_t numAudioInputBuses = v3_cpp_obj(component)->get_bus_count(component, V3_AUDIO, V3_INPUT);
  1390. const int32_t numEventInputBuses = v3_cpp_obj(component)->get_bus_count(component, V3_EVENT, V3_INPUT);
  1391. const int32_t numAudioOutputBuses = v3_cpp_obj(component)->get_bus_count(component, V3_AUDIO, V3_OUTPUT);
  1392. const int32_t numEventOutputBuses = v3_cpp_obj(component)->get_bus_count(component, V3_EVENT, V3_OUTPUT);
  1393. const int32_t numParameters = v3_cpp_obj(controller)->get_parameter_count(controller);
  1394. CARLA_SAFE_ASSERT(numAudioInputBuses >= 0);
  1395. CARLA_SAFE_ASSERT(numEventInputBuses >= 0);
  1396. CARLA_SAFE_ASSERT(numAudioOutputBuses >= 0);
  1397. CARLA_SAFE_ASSERT(numEventOutputBuses >= 0);
  1398. CARLA_SAFE_ASSERT(numParameters >= 0);
  1399. for (int32_t j=0; j<numAudioInputBuses; ++j)
  1400. {
  1401. v3_bus_info busInfo = {};
  1402. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component, V3_AUDIO, V3_INPUT, j, &busInfo) == V3_OK);
  1403. if (busInfo.flags & V3_IS_CONTROL_VOLTAGE)
  1404. cvIns += busInfo.channel_count;
  1405. else
  1406. audioIns += busInfo.channel_count;
  1407. }
  1408. for (int32_t j=0; j<numAudioOutputBuses; ++j)
  1409. {
  1410. v3_bus_info busInfo = {};
  1411. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component, V3_AUDIO, V3_OUTPUT, j, &busInfo) == V3_OK);
  1412. if (busInfo.flags & V3_IS_CONTROL_VOLTAGE)
  1413. cvOuts += busInfo.channel_count;
  1414. else
  1415. audioOuts += busInfo.channel_count;
  1416. }
  1417. for (int32_t j=0; j<numParameters; ++j)
  1418. {
  1419. v3_param_info paramInfo = {};
  1420. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(controller)->get_parameter_info(controller, j, &paramInfo) == V3_OK);
  1421. if (paramInfo.flags & (V3_PARAM_IS_BYPASS|V3_PARAM_IS_HIDDEN|V3_PARAM_PROGRAM_CHANGE))
  1422. continue;
  1423. if (paramInfo.flags & V3_PARAM_READ_ONLY)
  1424. ++parameterOuts;
  1425. else
  1426. ++parameterIns;
  1427. }
  1428. if (v3_plugin_view** const view = v3_cpp_obj(controller)->create_view(controller, "view"))
  1429. {
  1430. if (v3_cpp_obj(view)->is_platform_type_supported(view, V3_VIEW_PLATFORM_TYPE_NATIVE) == V3_TRUE)
  1431. hints |= PLUGIN_HAS_CUSTOM_UI;
  1432. v3_cpp_obj_unref(view);
  1433. }
  1434. if (factory2 != nullptr && std::strstr(classInfo.v2.sub_categories, "Instrument") != nullptr)
  1435. hints |= PLUGIN_IS_SYNTH;
  1436. if (doInit)
  1437. {
  1438. v3_audio_processor** processor = nullptr;
  1439. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj_query_interface(component, v3_audio_processor_iid, &processor) == V3_OK);
  1440. CARLA_SAFE_ASSERT_BREAK(processor != nullptr);
  1441. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(processor)->can_process_sample_size(processor, V3_SAMPLE_32) == V3_OK);
  1442. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->set_active(component, true) == V3_OK);
  1443. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->set_active(component, false) == V3_OK);
  1444. v3_process_setup setup = { V3_REALTIME, V3_SAMPLE_32, kBufferSize, kSampleRate };
  1445. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(processor)->setup_processing(processor, &setup) == V3_OK);
  1446. for (int32_t j=0; j<numAudioInputBuses; ++j)
  1447. {
  1448. v3_bus_info busInfo = {};
  1449. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component, V3_AUDIO, V3_INPUT, j, &busInfo) == V3_OK);
  1450. if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
  1451. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->activate_bus(component, V3_AUDIO, V3_INPUT, j, true) == V3_OK);
  1452. }
  1453. }
  1454. for (int32_t j=0; j<numAudioOutputBuses; ++j)
  1455. {
  1456. v3_bus_info busInfo = {};
  1457. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component, V3_AUDIO, V3_OUTPUT, j, &busInfo) == V3_OK);
  1458. if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
  1459. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->activate_bus(component, V3_AUDIO, V3_OUTPUT, j, true) == V3_OK);
  1460. }
  1461. }
  1462. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->set_active(component, true) == V3_OK);
  1463. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(processor)->set_processing(processor, true) == V3_OK);
  1464. float* bufferAudioIn[(uint)std::max(1, audioIns + cvIns)];
  1465. float* bufferAudioOut[(uint)std::max(1, audioOuts + cvOuts)];
  1466. if (audioIns + cvIns == 0)
  1467. {
  1468. bufferAudioIn[0] = nullptr;
  1469. }
  1470. else
  1471. {
  1472. for (int j=0; j < audioIns + cvIns; ++j)
  1473. {
  1474. bufferAudioIn[j] = new float[kBufferSize];
  1475. carla_zeroFloats(bufferAudioIn[j], kBufferSize);
  1476. }
  1477. }
  1478. if (audioOuts + cvOuts == 0)
  1479. {
  1480. bufferAudioOut[0] = nullptr;
  1481. }
  1482. else
  1483. {
  1484. for (int j=0; j < audioOuts + cvOuts; ++j)
  1485. {
  1486. bufferAudioOut[j] = new float[kBufferSize];
  1487. carla_zeroFloats(bufferAudioOut[j], kBufferSize);
  1488. }
  1489. }
  1490. carla_v3_event_list eventList;
  1491. carla_v3_event_list* eventListPtr = &eventList;
  1492. carla_v3_param_changes paramChanges;
  1493. carla_v3_param_changes* paramChangesPtr = &paramChanges;
  1494. v3_audio_bus_buffers processInputs = { audioIns + cvIns, 0, { bufferAudioIn } };
  1495. v3_audio_bus_buffers processOutputs = { audioOuts + cvOuts, 0, { bufferAudioOut } };
  1496. v3_process_context processContext = {};
  1497. processContext.sample_rate = kSampleRate;
  1498. v3_process_data processData = {
  1499. V3_REALTIME,
  1500. V3_SAMPLE_32,
  1501. kBufferSize,
  1502. audioIns + cvIns,
  1503. audioOuts + cvOuts,
  1504. &processInputs,
  1505. &processOutputs,
  1506. (v3_param_changes**)&paramChangesPtr,
  1507. (v3_param_changes**)&paramChangesPtr,
  1508. (v3_event_list**)&eventListPtr,
  1509. (v3_event_list**)&eventListPtr,
  1510. &processContext
  1511. };
  1512. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(processor)->process(processor, &processData) == V3_OK);
  1513. for (int j=0; j < audioIns + cvIns; ++j)
  1514. delete[] bufferAudioIn[j];
  1515. for (int j=0; j < audioOuts + cvOuts; ++j)
  1516. delete[] bufferAudioOut[j];
  1517. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(processor)->set_processing(processor, false) == V3_OK);
  1518. CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->set_active(component, false) == V3_OK);
  1519. v3_cpp_obj_unref(processor);
  1520. }
  1521. if (shouldTerminateController)
  1522. v3_cpp_obj_terminate(controller);
  1523. v3_cpp_obj_unref(controller);
  1524. v3_cpp_obj_terminate(component);
  1525. v3_cpp_obj_unref(component);
  1526. DISCOVERY_OUT("init", "-----------");
  1527. DISCOVERY_OUT("build", BINARY_NATIVE);
  1528. DISCOVERY_OUT("hints", hints);
  1529. DISCOVERY_OUT("category", getPluginCategoryAsString(factory2 != nullptr ? getPluginCategoryFromV3SubCategories(classInfo.v2.sub_categories)
  1530. : getPluginCategoryFromName(classInfo.v1.name)));
  1531. DISCOVERY_OUT("name", classInfo.v1.name);
  1532. DISCOVERY_OUT("label", tuid2str(classInfo.v1.class_id));
  1533. DISCOVERY_OUT("maker", (factory2 != nullptr ? classInfo.v2.vendor : factoryInfo.vendor));
  1534. DISCOVERY_OUT("audio.ins", audioIns);
  1535. DISCOVERY_OUT("audio.outs", audioOuts);
  1536. DISCOVERY_OUT("cv.ins", cvIns);
  1537. DISCOVERY_OUT("cv.outs", cvOuts);
  1538. DISCOVERY_OUT("midi.ins", numEventInputBuses);
  1539. DISCOVERY_OUT("midi.outs", numEventOutputBuses);
  1540. DISCOVERY_OUT("parameters.ins", parameterIns);
  1541. DISCOVERY_OUT("parameters.outs", parameterOuts);
  1542. DISCOVERY_OUT("end", "------------");
  1543. }
  1544. // unref interfaces
  1545. if (factory3 != nullptr)
  1546. v3_cpp_obj_unref(factory3);
  1547. if (factory2 != nullptr)
  1548. v3_cpp_obj_unref(factory2);
  1549. v3_cpp_obj_unref(factory1);
  1550. v3_exit();
  1551. return false;
  1552. }
  1553. #endif // ! USING_JUCE_FOR_VST3
  1554. #ifdef USING_JUCE
  1555. // --------------------------------------------------------------------------------------------------------------------
  1556. // find all available plugin audio ports
  1557. static void findMaxTotalChannels(juce::AudioProcessor* const filter, int& maxTotalIns, int& maxTotalOuts)
  1558. {
  1559. filter->enableAllBuses();
  1560. const int numInputBuses = filter->getBusCount(true);
  1561. const int numOutputBuses = filter->getBusCount(false);
  1562. if (numInputBuses > 1 || numOutputBuses > 1)
  1563. {
  1564. maxTotalIns = maxTotalOuts = 0;
  1565. for (int i = 0; i < numInputBuses; ++i)
  1566. maxTotalIns += filter->getChannelCountOfBus(true, i);
  1567. for (int i = 0; i < numOutputBuses; ++i)
  1568. maxTotalOuts += filter->getChannelCountOfBus(false, i);
  1569. }
  1570. else
  1571. {
  1572. maxTotalIns = numInputBuses > 0 ? filter->getBus(true, 0)->getMaxSupportedChannels(64) : 0;
  1573. maxTotalOuts = numOutputBuses > 0 ? filter->getBus(false, 0)->getMaxSupportedChannels(64) : 0;
  1574. }
  1575. }
  1576. // --------------------------------------------------------------------------------------------------------------------
  1577. static bool do_juce_check(const char* const filename_, const char* const stype, const bool doInit)
  1578. {
  1579. CARLA_SAFE_ASSERT_RETURN(stype != nullptr && stype[0] != 0, false) // FIXME
  1580. carla_debug("do_juce_check(%s, %s, %s)", filename_, stype, bool2str(doInit));
  1581. CarlaJUCE::initialiseJuce_GUI();
  1582. juce::String filename;
  1583. #ifdef CARLA_OS_WIN
  1584. // Fix for wine usage
  1585. if (juce::File("Z:\\usr\\").isDirectory() && filename_[0] == '/')
  1586. {
  1587. filename = filename_;
  1588. filename.replace("/", "\\");
  1589. filename = "Z:" + filename;
  1590. }
  1591. else
  1592. #endif
  1593. filename = juce::File(filename_).getFullPathName();
  1594. CarlaScopedPointer<juce::AudioPluginFormat> pluginFormat;
  1595. /* */ if (std::strcmp(stype, "VST2") == 0)
  1596. {
  1597. #if JUCE_PLUGINHOST_VST
  1598. pluginFormat = new juce::VSTPluginFormat();
  1599. #else
  1600. DISCOVERY_OUT("error", "VST2 support not available");
  1601. return false;
  1602. #endif
  1603. }
  1604. else if (std::strcmp(stype, "VST3") == 0)
  1605. {
  1606. #if JUCE_PLUGINHOST_VST3
  1607. pluginFormat = new juce::VST3PluginFormat();
  1608. #else
  1609. DISCOVERY_OUT("error", "VST3 support not available");
  1610. return false;
  1611. #endif
  1612. }
  1613. else if (std::strcmp(stype, "AU") == 0)
  1614. {
  1615. #if JUCE_PLUGINHOST_AU
  1616. pluginFormat = new juce::AudioUnitPluginFormat();
  1617. #else
  1618. DISCOVERY_OUT("error", "AU support not available");
  1619. return false;
  1620. #endif
  1621. }
  1622. if (pluginFormat == nullptr)
  1623. {
  1624. DISCOVERY_OUT("error", stype << " support not available");
  1625. return false;
  1626. }
  1627. #ifdef CARLA_OS_WIN
  1628. CARLA_CUSTOM_SAFE_ASSERT_RETURN("Plugin file/folder does not exist", juce::File(filename).exists(), false);
  1629. #endif
  1630. CARLA_SAFE_ASSERT_RETURN(pluginFormat->fileMightContainThisPluginType(filename), false);
  1631. juce::OwnedArray<juce::PluginDescription> results;
  1632. pluginFormat->findAllTypesForFile(results, filename);
  1633. if (results.size() == 0)
  1634. {
  1635. #if defined(CARLA_OS_MAC) && defined(__aarch64__)
  1636. if (std::strcmp(stype, "VST2") == 0 || std::strcmp(stype, "VST3") == 0)
  1637. return true;
  1638. #endif
  1639. DISCOVERY_OUT("error", "No plugins found");
  1640. return false;
  1641. }
  1642. for (juce::PluginDescription **it = results.begin(), **end = results.end(); it != end; ++it)
  1643. {
  1644. juce::PluginDescription* const desc(*it);
  1645. uint hints = 0x0;
  1646. int audioIns = desc->numInputChannels;
  1647. int audioOuts = desc->numOutputChannels;
  1648. int midiIns = 0;
  1649. int midiOuts = 0;
  1650. int parameters = 0;
  1651. if (desc->isInstrument)
  1652. {
  1653. hints |= PLUGIN_IS_SYNTH;
  1654. midiIns = 1;
  1655. }
  1656. if (doInit)
  1657. {
  1658. if (std::unique_ptr<juce::AudioPluginInstance> instance
  1659. = pluginFormat->createInstanceFromDescription(*desc, kSampleRate, kBufferSize))
  1660. {
  1661. CarlaJUCE::idleJuce_GUI();
  1662. findMaxTotalChannels(instance.get(), audioIns, audioOuts);
  1663. instance->refreshParameterList();
  1664. parameters = instance->getParameters().size();
  1665. if (instance->hasEditor())
  1666. hints |= PLUGIN_HAS_CUSTOM_UI;
  1667. if (instance->acceptsMidi())
  1668. midiIns = 1;
  1669. if (instance->producesMidi())
  1670. midiOuts = 1;
  1671. }
  1672. }
  1673. DISCOVERY_OUT("init", "-----------");
  1674. DISCOVERY_OUT("build", BINARY_NATIVE);
  1675. DISCOVERY_OUT("hints", hints);
  1676. DISCOVERY_OUT("category", getPluginCategoryAsString(getPluginCategoryFromName(desc->category.toRawUTF8())));
  1677. DISCOVERY_OUT("name", desc->descriptiveName);
  1678. DISCOVERY_OUT("label", desc->name);
  1679. DISCOVERY_OUT("maker", desc->manufacturerName);
  1680. DISCOVERY_OUT("uniqueId", desc->uniqueId);
  1681. DISCOVERY_OUT("audio.ins", audioIns);
  1682. DISCOVERY_OUT("audio.outs", audioOuts);
  1683. DISCOVERY_OUT("midi.ins", midiIns);
  1684. DISCOVERY_OUT("midi.outs", midiOuts);
  1685. DISCOVERY_OUT("parameters.ins", parameters);
  1686. DISCOVERY_OUT("end", "------------");
  1687. }
  1688. CarlaJUCE::idleJuce_GUI();
  1689. CarlaJUCE::shutdownJuce_GUI();
  1690. return false;
  1691. }
  1692. #endif // USING_JUCE_FOR_VST2
  1693. static void do_fluidsynth_check(const char* const filename, const PluginType type, const bool doInit)
  1694. {
  1695. #ifdef HAVE_FLUIDSYNTH
  1696. const water::File file(filename);
  1697. if (! file.existsAsFile())
  1698. {
  1699. DISCOVERY_OUT("error", "Requested file is not valid or does not exist");
  1700. return;
  1701. }
  1702. if (type == PLUGIN_SF2 && ! fluid_is_soundfont(filename))
  1703. {
  1704. DISCOVERY_OUT("error", "Not a SF2 file");
  1705. return;
  1706. }
  1707. int programs = 0;
  1708. if (doInit)
  1709. {
  1710. fluid_settings_t* const f_settings = new_fluid_settings();
  1711. CARLA_SAFE_ASSERT_RETURN(f_settings != nullptr,);
  1712. fluid_synth_t* const f_synth = new_fluid_synth(f_settings);
  1713. CARLA_SAFE_ASSERT_RETURN(f_synth != nullptr,);
  1714. const int f_id_test = fluid_synth_sfload(f_synth, filename, 0);
  1715. if (f_id_test < 0)
  1716. {
  1717. DISCOVERY_OUT("error", "Failed to load SF2 file");
  1718. return;
  1719. }
  1720. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1721. const int f_id = f_id_test;
  1722. #else
  1723. const uint f_id = static_cast<uint>(f_id_test);
  1724. #endif
  1725. if (fluid_sfont_t* const f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id))
  1726. {
  1727. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1728. fluid_sfont_iteration_start(f_sfont);
  1729. for (; fluid_sfont_iteration_next(f_sfont);)
  1730. ++programs;
  1731. #else
  1732. fluid_preset_t f_preset;
  1733. f_sfont->iteration_start(f_sfont);
  1734. for (; f_sfont->iteration_next(f_sfont, &f_preset);)
  1735. ++programs;
  1736. #endif
  1737. }
  1738. delete_fluid_synth(f_synth);
  1739. delete_fluid_settings(f_settings);
  1740. }
  1741. CarlaString name(file.getFileNameWithoutExtension().toRawUTF8());
  1742. CarlaString label(name);
  1743. // 2 channels
  1744. DISCOVERY_OUT("init", "-----------");
  1745. DISCOVERY_OUT("build", BINARY_NATIVE);
  1746. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1747. DISCOVERY_OUT("category", "synth");
  1748. DISCOVERY_OUT("name", name.buffer());
  1749. DISCOVERY_OUT("label", label.buffer());
  1750. DISCOVERY_OUT("audio.outs", 2);
  1751. DISCOVERY_OUT("midi.ins", 1);
  1752. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1753. DISCOVERY_OUT("parameters.outs", 1);
  1754. DISCOVERY_OUT("end", "------------");
  1755. // 16 channels
  1756. if (doInit && (name.isEmpty() || programs <= 1))
  1757. return;
  1758. name += " (16 outputs)";
  1759. DISCOVERY_OUT("init", "-----------");
  1760. DISCOVERY_OUT("build", BINARY_NATIVE);
  1761. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1762. DISCOVERY_OUT("category", "synth");
  1763. DISCOVERY_OUT("name", name.buffer());
  1764. DISCOVERY_OUT("label", label.buffer());
  1765. DISCOVERY_OUT("audio.outs", 32);
  1766. DISCOVERY_OUT("midi.ins", 1);
  1767. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1768. DISCOVERY_OUT("parameters.outs", 1);
  1769. DISCOVERY_OUT("end", "------------");
  1770. #else // HAVE_FLUIDSYNTH
  1771. DISCOVERY_OUT("error", "SF2 support not available");
  1772. return;
  1773. // unused
  1774. (void)filename;
  1775. (void)type;
  1776. (void)doInit;
  1777. #endif
  1778. }
  1779. // --------------------------------------------------------------------------------------------------------------------
  1780. #ifndef BUILD_BRIDGE
  1781. static void do_jsfx_check(const char* const filename, bool doInit)
  1782. {
  1783. const water::File file(filename);
  1784. ysfx_config_u config(ysfx_config_new());
  1785. ysfx_register_builtin_audio_formats(config.get());
  1786. ysfx_guess_file_roots(config.get(), filename);
  1787. ysfx_set_log_reporter(config.get(), &CarlaJsfxLogging::logErrorsOnly);
  1788. ysfx_u effect(ysfx_new(config.get()));
  1789. uint hints = 0;
  1790. // do not attempt to compile it, because the import path is not known
  1791. (void)doInit;
  1792. if (! ysfx_load_file(effect.get(), filename, 0))
  1793. {
  1794. DISCOVERY_OUT("error", "Cannot read the JSFX header");
  1795. return;
  1796. }
  1797. const char* const name = ysfx_get_name(effect.get());
  1798. // author and category are extracted from the pseudo-tags
  1799. const char* const author = ysfx_get_author(effect.get());
  1800. const CB::PluginCategory category = CarlaJsfxCategories::getFromEffect(effect.get());
  1801. const uint32_t audioIns = ysfx_get_num_inputs(effect.get());
  1802. const uint32_t audioOuts = ysfx_get_num_outputs(effect.get());
  1803. const uint32_t midiIns = 1;
  1804. const uint32_t midiOuts = 1;
  1805. uint32_t parameters = 0;
  1806. for (uint32_t sliderIndex = 0; sliderIndex < ysfx_max_sliders; ++sliderIndex)
  1807. {
  1808. if (ysfx_slider_exists(effect.get(), sliderIndex))
  1809. ++parameters;
  1810. }
  1811. DISCOVERY_OUT("init", "-----------");
  1812. DISCOVERY_OUT("build", BINARY_NATIVE);
  1813. DISCOVERY_OUT("hints", hints);
  1814. DISCOVERY_OUT("category", getPluginCategoryAsString(category));
  1815. DISCOVERY_OUT("name", name);
  1816. DISCOVERY_OUT("maker", author);
  1817. DISCOVERY_OUT("label", filename);
  1818. DISCOVERY_OUT("audio.ins", audioIns);
  1819. DISCOVERY_OUT("audio.outs", audioOuts);
  1820. DISCOVERY_OUT("midi.ins", midiIns);
  1821. DISCOVERY_OUT("midi.outs", midiOuts);
  1822. DISCOVERY_OUT("parameters.ins", parameters);
  1823. DISCOVERY_OUT("end", "------------");
  1824. }
  1825. #endif
  1826. // ------------------------------ main entry point ------------------------------
  1827. int main(int argc, const char* argv[])
  1828. {
  1829. if (argc != 3 && argc != 7)
  1830. {
  1831. carla_stdout("usage: %s <type> </path/to/plugin>", argv[0]);
  1832. return 1;
  1833. }
  1834. const char* const stype = argv[1];
  1835. const char* const filename = argv[2];
  1836. const PluginType type = getPluginTypeFromString(stype);
  1837. CarlaString filenameCheck(filename);
  1838. filenameCheck.toLower();
  1839. bool openLib;
  1840. lib_t handle = nullptr;
  1841. switch (type)
  1842. {
  1843. case PLUGIN_LADSPA:
  1844. case PLUGIN_DSSI:
  1845. // only available as single binary
  1846. openLib = true;
  1847. break;
  1848. case PLUGIN_VST2:
  1849. #ifdef CARLA_OS_MAC
  1850. // bundle on macOS
  1851. openLib = false;
  1852. #else
  1853. // single binary on all else
  1854. openLib = true;
  1855. #endif
  1856. break;
  1857. case PLUGIN_VST3:
  1858. #ifdef CARLA_OS_WIN
  1859. // either file or bundle on Windows
  1860. openLib = water::File(filename).existsAsFile();
  1861. #else
  1862. // bundle on all else
  1863. openLib = false;
  1864. #endif
  1865. break;
  1866. default:
  1867. openLib = false;
  1868. break;
  1869. }
  1870. if (type != PLUGIN_SF2 && filenameCheck.contains("fluidsynth", true))
  1871. {
  1872. DISCOVERY_OUT("info", "skipping fluidsynth based plugin");
  1873. return 0;
  1874. }
  1875. #ifdef CARLA_OS_MAC
  1876. if (type == PLUGIN_VST2 && (filenameCheck.endsWith(".vst") || filenameCheck.endsWith(".vst/")))
  1877. openLib = false;
  1878. #endif
  1879. // ---------------------------------------------------------------------------------------------------------------
  1880. // Initialize OS features
  1881. // we want stuff in English so we can parse error messages
  1882. ::setlocale(LC_ALL, "C");
  1883. #ifndef CARLA_OS_WIN
  1884. carla_setenv("LC_ALL", "C");
  1885. #endif
  1886. #ifdef CARLA_OS_WIN
  1887. OleInitialize(nullptr);
  1888. CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
  1889. # ifndef __WINPTHREADS_VERSION
  1890. // (non-portable) initialization of statically linked pthread library
  1891. pthread_win32_process_attach_np();
  1892. pthread_win32_thread_attach_np();
  1893. # endif
  1894. #endif
  1895. // ---------------------------------------------------------------------------------------------------------------
  1896. // Initialize pipe
  1897. if (argc == 7)
  1898. {
  1899. gPipe = new DiscoveryPipe;
  1900. if (! gPipe->initPipeClient(argv))
  1901. return 1;
  1902. }
  1903. // ---------------------------------------------------------------------------------------------------------------
  1904. if (openLib)
  1905. {
  1906. handle = lib_open(filename);
  1907. if (handle == nullptr)
  1908. {
  1909. print_lib_error(filename);
  1910. return 1;
  1911. }
  1912. }
  1913. // never do init for dssi-vst, takes too long and it's crashy
  1914. bool doInit = ! filenameCheck.contains("dssi-vst", true);
  1915. if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") != nullptr)
  1916. doInit = false;
  1917. // ---------------------------------------------------------------------------------------------------------------
  1918. if (doInit && openLib && handle != nullptr)
  1919. {
  1920. // test fast loading & unloading DLL without initializing the plugin(s)
  1921. if (! lib_close(handle))
  1922. {
  1923. print_lib_error(filename);
  1924. return 1;
  1925. }
  1926. handle = lib_open(filename);
  1927. if (handle == nullptr)
  1928. {
  1929. print_lib_error(filename);
  1930. return 1;
  1931. }
  1932. }
  1933. #ifndef BUILD_BRIDGE
  1934. if (std::strcmp(filename, ":all") == 0)
  1935. {
  1936. do_cached_check(type);
  1937. gPipe = nullptr;
  1938. return 0;
  1939. }
  1940. #endif
  1941. #ifdef CARLA_OS_MAC
  1942. // Plugin might be in quarentine due to Apple stupid notarization rules, let's remove that if possible
  1943. switch (type)
  1944. {
  1945. case PLUGIN_LADSPA:
  1946. case PLUGIN_DSSI:
  1947. case PLUGIN_VST2:
  1948. case PLUGIN_VST3:
  1949. removeFileFromQuarantine(filename);
  1950. break;
  1951. default:
  1952. break;
  1953. }
  1954. #endif
  1955. // some macOS plugins have not been yet ported to arm64, re-run them in x86_64 mode if discovery fails
  1956. bool retryAsX64lugin = false;
  1957. switch (type)
  1958. {
  1959. case PLUGIN_LADSPA:
  1960. do_ladspa_check(handle, filename, doInit);
  1961. break;
  1962. case PLUGIN_DSSI:
  1963. do_dssi_check(handle, filename, doInit);
  1964. break;
  1965. #ifndef BUILD_BRIDGE
  1966. case PLUGIN_LV2:
  1967. do_lv2_check(filename, doInit);
  1968. break;
  1969. #endif
  1970. case PLUGIN_VST2:
  1971. #if defined(USING_JUCE) && JUCE_PLUGINHOST_VST
  1972. retryAsX64lugin = do_juce_check(filename, "VST2", doInit);
  1973. #else
  1974. retryAsX64lugin = do_vst2_check(handle, filename, doInit);
  1975. #endif
  1976. break;
  1977. case PLUGIN_VST3:
  1978. #if defined(USING_JUCE) && JUCE_PLUGINHOST_VST3
  1979. retryAsX64lugin = do_juce_check(filename, "VST3", doInit);
  1980. #else
  1981. retryAsX64lugin = do_vst3_check(handle, filename, doInit);
  1982. #endif
  1983. break;
  1984. case PLUGIN_AU:
  1985. #if defined(USING_JUCE) && JUCE_PLUGINHOST_AU
  1986. do_juce_check(filename, "AU", doInit);
  1987. #else
  1988. DISCOVERY_OUT("error", "AU support not available");
  1989. #endif
  1990. break;
  1991. #ifndef BUILD_BRIDGE
  1992. case PLUGIN_JSFX:
  1993. do_jsfx_check(filename, doInit);
  1994. break;
  1995. #endif
  1996. case PLUGIN_DLS:
  1997. case PLUGIN_GIG:
  1998. case PLUGIN_SF2:
  1999. do_fluidsynth_check(filename, type, doInit);
  2000. break;
  2001. default:
  2002. break;
  2003. }
  2004. if (openLib && handle != nullptr)
  2005. lib_close(handle);
  2006. if (retryAsX64lugin)
  2007. {
  2008. #if defined(CARLA_OS_MAC) && defined(__aarch64__)
  2009. DISCOVERY_OUT("warning", "No plugins found while scanning in arm64 mode, will try x86_64 now");
  2010. cpu_type_t pref = CPU_TYPE_X86_64;
  2011. pid_t pid = -1;
  2012. posix_spawnattr_t attr;
  2013. posix_spawnattr_init(&attr);
  2014. CARLA_SAFE_ASSERT_RETURN(posix_spawnattr_setbinpref_np(&attr, 1, &pref, nullptr) == 0, 1);
  2015. CARLA_SAFE_ASSERT_RETURN(posix_spawn(&pid, argv[0], nullptr, &attr, (char* const*)argv, nullptr) == 0, 1);
  2016. posix_spawnattr_destroy(&attr);
  2017. if (pid > 0)
  2018. {
  2019. int status;
  2020. waitpid(pid, &status, 0);
  2021. }
  2022. #endif
  2023. }
  2024. gPipe = nullptr;
  2025. // ---------------------------------------------------------------------------------------------------------------
  2026. #ifdef CARLA_OS_WIN
  2027. #ifndef __WINPTHREADS_VERSION
  2028. pthread_win32_thread_detach_np();
  2029. pthread_win32_process_detach_np();
  2030. #endif
  2031. CoUninitialize();
  2032. OleUninitialize();
  2033. #endif
  2034. return 0;
  2035. }
  2036. // --------------------------------------------------------------------------------------------------------------------