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

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
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
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
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
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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688
  1. /*
  2. * Carla Plugin discovery
  3. * Copyright (C) 2011-2019 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 "CarlaMIDI.h"
  21. #include "LinkedList.hpp"
  22. #ifdef BUILD_BRIDGE
  23. # undef HAVE_FLUIDSYNTH
  24. #endif
  25. #if defined(USING_JUCE) && (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
  26. # include "AppConfig.h"
  27. # include "juce_audio_processors/juce_audio_processors.h"
  28. # define USE_JUCE_PROCESSORS
  29. #endif
  30. #include "CarlaLadspaUtils.hpp"
  31. #include "CarlaLv2Utils.hpp"
  32. #include "CarlaVstUtils.hpp"
  33. #ifdef CARLA_OS_MAC
  34. # import <Foundation/Foundation.h>
  35. #endif
  36. #ifdef CARLA_OS_WIN
  37. # include <pthread.h>
  38. # include <objbase.h>
  39. #endif
  40. #ifdef HAVE_FLUIDSYNTH
  41. # include <fluidsynth.h>
  42. #endif
  43. #include <iostream>
  44. #ifndef BUILD_BRIDGE
  45. # include "water/files/File.h"
  46. # include "water/text/StringArray.h"
  47. # include "CarlaDssiUtils.cpp"
  48. # include "../backend/utils/CachedPlugins.cpp"
  49. #else
  50. # include "CarlaDssiUtils.hpp"
  51. #endif
  52. #define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl;
  53. using water::CharPointer_UTF8;
  54. using water::File;
  55. using water::StringArray;
  56. CARLA_BACKEND_USE_NAMESPACE
  57. // --------------------------------------------------------------------------
  58. // Dummy values to test plugins with
  59. static const uint32_t kBufferSize = 512;
  60. static const double kSampleRate = 44100.0;
  61. static const int32_t kSampleRatei = 44100;
  62. static const float kSampleRatef = 44100.0f;
  63. // --------------------------------------------------------------------------
  64. // Don't print ELF/EXE related errors since discovery can find multi-architecture binaries
  65. static void print_lib_error(const char* const filename)
  66. {
  67. const char* const error(lib_error(filename));
  68. if (error != nullptr &&
  69. std::strstr(error, "wrong ELF class") == nullptr &&
  70. std::strstr(error, "Bad EXE format") == nullptr &&
  71. std::strstr(error, "no suitable image found") == nullptr &&
  72. std::strstr(error, "not a valid Win32 application") == nullptr)
  73. {
  74. DISCOVERY_OUT("error", error);
  75. }
  76. }
  77. // ------------------------------ Plugin Checks -----------------------------
  78. #ifndef BUILD_BRIDGE
  79. static void print_cached_plugin(const CarlaCachedPluginInfo* const pinfo)
  80. {
  81. if (! pinfo->valid)
  82. return;
  83. DISCOVERY_OUT("init", "-----------");
  84. DISCOVERY_OUT("build", BINARY_NATIVE);
  85. DISCOVERY_OUT("hints", pinfo->hints);
  86. DISCOVERY_OUT("name", pinfo->name);
  87. DISCOVERY_OUT("maker", pinfo->maker);
  88. DISCOVERY_OUT("label", pinfo->label);
  89. DISCOVERY_OUT("audio.ins", pinfo->audioIns);
  90. DISCOVERY_OUT("audio.outs", pinfo->audioOuts);
  91. DISCOVERY_OUT("cv.ins", pinfo->cvIns);
  92. DISCOVERY_OUT("cv.outs", pinfo->cvOuts);
  93. DISCOVERY_OUT("midi.ins", pinfo->midiIns);
  94. DISCOVERY_OUT("midi.outs", pinfo->midiOuts);
  95. DISCOVERY_OUT("parameters.ins", pinfo->parameterIns);
  96. DISCOVERY_OUT("parameters.outs", pinfo->parameterOuts);
  97. DISCOVERY_OUT("end", "------------");
  98. }
  99. static void do_cached_check(const PluginType type)
  100. {
  101. const char* plugPath;
  102. switch (type)
  103. {
  104. case PLUGIN_LV2:
  105. plugPath = std::getenv("LV2_PATH");
  106. break;
  107. case PLUGIN_SFZ:
  108. plugPath = std::getenv("SFZ_PATH");
  109. break;
  110. default:
  111. plugPath = nullptr;
  112. break;
  113. }
  114. const uint count = carla_get_cached_plugin_count(type, plugPath);
  115. for (uint i=0; i<count; ++i)
  116. {
  117. const CarlaCachedPluginInfo* pinfo(carla_get_cached_plugin_info(type, i));
  118. CARLA_SAFE_ASSERT_CONTINUE(pinfo != nullptr);
  119. print_cached_plugin(pinfo);
  120. }
  121. }
  122. #endif
  123. static void do_ladspa_check(lib_t& libHandle, const char* const filename, const bool doInit)
  124. {
  125. LADSPA_Descriptor_Function descFn = lib_symbol<LADSPA_Descriptor_Function>(libHandle, "ladspa_descriptor");
  126. if (descFn == nullptr)
  127. {
  128. DISCOVERY_OUT("error", "Not a LADSPA plugin");
  129. return;
  130. }
  131. const LADSPA_Descriptor* descriptor;
  132. {
  133. descriptor = descFn(0);
  134. if (descriptor == nullptr)
  135. {
  136. DISCOVERY_OUT("error", "Binary doesn't contain any plugins");
  137. return;
  138. }
  139. if (doInit && descriptor->instantiate != nullptr && descriptor->cleanup != nullptr)
  140. {
  141. LADSPA_Handle handle = descriptor->instantiate(descriptor, kSampleRatei);
  142. if (handle == nullptr)
  143. {
  144. DISCOVERY_OUT("error", "Failed to init first LADSPA plugin");
  145. return;
  146. }
  147. descriptor->cleanup(handle);
  148. lib_close(libHandle);
  149. libHandle = lib_open(filename);
  150. if (libHandle == nullptr)
  151. {
  152. print_lib_error(filename);
  153. return;
  154. }
  155. descFn = lib_symbol<LADSPA_Descriptor_Function>(libHandle, "ladspa_descriptor");
  156. if (descFn == nullptr)
  157. {
  158. DISCOVERY_OUT("error", "Not a LADSPA plugin (#2)");
  159. return;
  160. }
  161. }
  162. }
  163. unsigned long i = 0;
  164. while ((descriptor = descFn(i++)) != nullptr)
  165. {
  166. if (descriptor->instantiate == nullptr)
  167. {
  168. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no instantiate()");
  169. continue;
  170. }
  171. if (descriptor->cleanup == nullptr)
  172. {
  173. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no cleanup()");
  174. continue;
  175. }
  176. if (descriptor->run == nullptr)
  177. {
  178. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no run()");
  179. continue;
  180. }
  181. if (! LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  182. {
  183. DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable");
  184. }
  185. uint hints = 0x0;
  186. uint audioIns = 0;
  187. uint audioOuts = 0;
  188. uint audioTotal = 0;
  189. uint parametersIns = 0;
  190. uint parametersOuts = 0;
  191. uint parametersTotal = 0;
  192. if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  193. hints |= PLUGIN_IS_RTSAFE;
  194. for (unsigned long j=0; j < descriptor->PortCount; ++j)
  195. {
  196. CARLA_ASSERT(descriptor->PortNames[j] != nullptr);
  197. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  198. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  199. {
  200. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  201. audioIns += 1;
  202. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  203. audioOuts += 1;
  204. audioTotal += 1;
  205. }
  206. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  207. {
  208. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  209. parametersIns += 1;
  210. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(descriptor->PortNames[j], "latency") != 0 && std::strcmp(descriptor->PortNames[j], "_latency") != 0)
  211. parametersOuts += 1;
  212. parametersTotal += 1;
  213. }
  214. }
  215. if (doInit)
  216. {
  217. // -----------------------------------------------------------------------
  218. // start crash-free plugin test
  219. LADSPA_Handle handle = descriptor->instantiate(descriptor, kSampleRatei);
  220. if (handle == nullptr)
  221. {
  222. DISCOVERY_OUT("error", "Failed to init LADSPA plugin");
  223. continue;
  224. }
  225. // Test quick init and cleanup
  226. descriptor->cleanup(handle);
  227. handle = descriptor->instantiate(descriptor, kSampleRatei);
  228. if (handle == nullptr)
  229. {
  230. DISCOVERY_OUT("error", "Failed to init LADSPA plugin (#2)");
  231. continue;
  232. }
  233. LADSPA_Data bufferAudio[kBufferSize][audioTotal];
  234. LADSPA_Data bufferParams[parametersTotal];
  235. LADSPA_Data min, max, def;
  236. for (unsigned long j=0, iA=0, iC=0; j < descriptor->PortCount; ++j)
  237. {
  238. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  239. const LADSPA_PortRangeHint portRangeHints = descriptor->PortRangeHints[j];
  240. const char* const portName = descriptor->PortNames[j];
  241. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  242. {
  243. carla_zeroFloats(bufferAudio[iA], kBufferSize);
  244. descriptor->connect_port(handle, j, bufferAudio[iA++]);
  245. }
  246. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  247. {
  248. // min value
  249. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  250. min = portRangeHints.LowerBound;
  251. else
  252. min = 0.0f;
  253. // max value
  254. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  255. max = portRangeHints.UpperBound;
  256. else
  257. max = 1.0f;
  258. if (min > max)
  259. {
  260. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  261. max = min + 0.1f;
  262. }
  263. else if (carla_isEqual(min, max))
  264. {
  265. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max == min");
  266. max = min + 0.1f;
  267. }
  268. // default value
  269. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  270. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  271. {
  272. min *= kSampleRatef;
  273. max *= kSampleRatef;
  274. def *= kSampleRatef;
  275. }
  276. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  277. {
  278. // latency parameter
  279. def = 0.0f;
  280. }
  281. else
  282. {
  283. if (def < min)
  284. def = min;
  285. else if (def > max)
  286. def = max;
  287. }
  288. bufferParams[iC] = def;
  289. descriptor->connect_port(handle, j, &bufferParams[iC++]);
  290. }
  291. }
  292. if (descriptor->activate != nullptr)
  293. descriptor->activate(handle);
  294. descriptor->run(handle, kBufferSize);
  295. if (descriptor->deactivate != nullptr)
  296. descriptor->deactivate(handle);
  297. descriptor->cleanup(handle);
  298. // end crash-free plugin test
  299. // -----------------------------------------------------------------------
  300. }
  301. DISCOVERY_OUT("init", "-----------");
  302. DISCOVERY_OUT("build", BINARY_NATIVE);
  303. DISCOVERY_OUT("hints", hints);
  304. DISCOVERY_OUT("name", descriptor->Name);
  305. DISCOVERY_OUT("label", descriptor->Label);
  306. DISCOVERY_OUT("maker", descriptor->Maker);
  307. DISCOVERY_OUT("uniqueId", descriptor->UniqueID);
  308. DISCOVERY_OUT("audio.ins", audioIns);
  309. DISCOVERY_OUT("audio.outs", audioOuts);
  310. DISCOVERY_OUT("parameters.ins", parametersIns);
  311. DISCOVERY_OUT("parameters.outs", parametersOuts);
  312. DISCOVERY_OUT("end", "------------");
  313. }
  314. }
  315. static void do_dssi_check(lib_t& libHandle, const char* const filename, const bool doInit)
  316. {
  317. DSSI_Descriptor_Function descFn = lib_symbol<DSSI_Descriptor_Function>(libHandle, "dssi_descriptor");
  318. if (descFn == nullptr)
  319. {
  320. DISCOVERY_OUT("error", "Not a DSSI plugin");
  321. return;
  322. }
  323. const DSSI_Descriptor* descriptor;
  324. {
  325. descriptor = descFn(0);
  326. if (descriptor == nullptr)
  327. {
  328. DISCOVERY_OUT("error", "Binary doesn't contain any plugins");
  329. return;
  330. }
  331. const LADSPA_Descriptor* const ldescriptor(descriptor->LADSPA_Plugin);
  332. if (ldescriptor == nullptr)
  333. {
  334. DISCOVERY_OUT("error", "DSSI plugin doesn't provide the LADSPA interface");
  335. return;
  336. }
  337. if (doInit && ldescriptor->instantiate != nullptr && ldescriptor->cleanup != nullptr)
  338. {
  339. LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  340. if (handle == nullptr)
  341. {
  342. DISCOVERY_OUT("error", "Failed to init first LADSPA plugin");
  343. return;
  344. }
  345. ldescriptor->cleanup(handle);
  346. lib_close(libHandle);
  347. libHandle = lib_open(filename);
  348. if (libHandle == nullptr)
  349. {
  350. print_lib_error(filename);
  351. return;
  352. }
  353. descFn = lib_symbol<DSSI_Descriptor_Function>(libHandle, "dssi_descriptor");
  354. if (descFn == nullptr)
  355. {
  356. DISCOVERY_OUT("error", "Not a DSSI plugin (#2)");
  357. return;
  358. }
  359. }
  360. }
  361. unsigned long i = 0;
  362. while ((descriptor = descFn(i++)) != nullptr)
  363. {
  364. const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin;
  365. if (ldescriptor == nullptr)
  366. {
  367. DISCOVERY_OUT("error", "Plugin has no LADSPA interface");
  368. continue;
  369. }
  370. if (descriptor->DSSI_API_Version != DSSI_VERSION_MAJOR)
  371. {
  372. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' uses an unsupported DSSI spec version " << descriptor->DSSI_API_Version);
  373. continue;
  374. }
  375. if (ldescriptor->instantiate == nullptr)
  376. {
  377. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no instantiate()");
  378. continue;
  379. }
  380. if (ldescriptor->cleanup == nullptr)
  381. {
  382. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no cleanup()");
  383. continue;
  384. }
  385. if (ldescriptor->run == nullptr && descriptor->run_synth == nullptr)
  386. {
  387. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no run() or run_synth()");
  388. continue;
  389. }
  390. if (descriptor->run_synth == nullptr && descriptor->run_multiple_synths != nullptr)
  391. {
  392. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' requires run_multiple_synths which is not supported");
  393. continue;
  394. }
  395. if (! LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  396. {
  397. DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable");
  398. }
  399. uint hints = 0x0;
  400. uint audioIns = 0;
  401. uint audioOuts = 0;
  402. uint audioTotal = 0;
  403. uint midiIns = 0;
  404. uint parametersIns = 0;
  405. uint parametersOuts = 0;
  406. uint parametersTotal = 0;
  407. if (LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  408. hints |= PLUGIN_IS_RTSAFE;
  409. for (unsigned long j=0; j < ldescriptor->PortCount; ++j)
  410. {
  411. CARLA_ASSERT(ldescriptor->PortNames[j] != nullptr);
  412. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  413. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  414. {
  415. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  416. audioIns += 1;
  417. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  418. audioOuts += 1;
  419. audioTotal += 1;
  420. }
  421. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  422. {
  423. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  424. parametersIns += 1;
  425. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(ldescriptor->PortNames[j], "latency") != 0 && std::strcmp(ldescriptor->PortNames[j], "_latency") != 0)
  426. parametersOuts += 1;
  427. parametersTotal += 1;
  428. }
  429. }
  430. if (descriptor->run_synth != nullptr)
  431. midiIns = 1;
  432. if (midiIns > 0 && audioIns == 0 && audioOuts > 0)
  433. hints |= PLUGIN_IS_SYNTH;
  434. #ifndef BUILD_BRIDGE
  435. if (const char* const ui = find_dssi_ui(filename, ldescriptor->Label))
  436. {
  437. hints |= PLUGIN_HAS_CUSTOM_UI;
  438. delete[] ui;
  439. }
  440. #endif
  441. if (doInit)
  442. {
  443. // -----------------------------------------------------------------------
  444. // start crash-free plugin test
  445. LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  446. if (handle == nullptr)
  447. {
  448. DISCOVERY_OUT("error", "Failed to init DSSI plugin");
  449. continue;
  450. }
  451. // Test quick init and cleanup
  452. ldescriptor->cleanup(handle);
  453. handle = ldescriptor->instantiate(ldescriptor, kSampleRatei);
  454. if (handle == nullptr)
  455. {
  456. DISCOVERY_OUT("error", "Failed to init DSSI plugin (#2)");
  457. continue;
  458. }
  459. LADSPA_Data bufferAudio[kBufferSize][audioTotal];
  460. LADSPA_Data bufferParams[parametersTotal];
  461. LADSPA_Data min, max, def;
  462. for (unsigned long j=0, iA=0, iC=0; j < ldescriptor->PortCount; ++j)
  463. {
  464. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  465. const LADSPA_PortRangeHint portRangeHints = ldescriptor->PortRangeHints[j];
  466. const char* const portName = ldescriptor->PortNames[j];
  467. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  468. {
  469. carla_zeroFloats(bufferAudio[iA], kBufferSize);
  470. ldescriptor->connect_port(handle, j, bufferAudio[iA++]);
  471. }
  472. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  473. {
  474. // min value
  475. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  476. min = portRangeHints.LowerBound;
  477. else
  478. min = 0.0f;
  479. // max value
  480. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  481. max = portRangeHints.UpperBound;
  482. else
  483. max = 1.0f;
  484. if (min > max)
  485. {
  486. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  487. max = min + 0.1f;
  488. }
  489. else if (carla_isEqual(min, max))
  490. {
  491. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max == min");
  492. max = min + 0.1f;
  493. }
  494. // default value
  495. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  496. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  497. {
  498. min *= kSampleRatef;
  499. max *= kSampleRatef;
  500. def *= kSampleRatef;
  501. }
  502. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  503. {
  504. // latency parameter
  505. def = 0.0f;
  506. }
  507. else
  508. {
  509. if (def < min)
  510. def = min;
  511. else if (def > max)
  512. def = max;
  513. }
  514. bufferParams[iC] = def;
  515. ldescriptor->connect_port(handle, j, &bufferParams[iC++]);
  516. }
  517. }
  518. // select first midi-program if available
  519. if (descriptor->get_program != nullptr && descriptor->select_program != nullptr)
  520. {
  521. if (const DSSI_Program_Descriptor* const pDesc = descriptor->get_program(handle, 0))
  522. descriptor->select_program(handle, pDesc->Bank, pDesc->Program);
  523. }
  524. if (ldescriptor->activate != nullptr)
  525. ldescriptor->activate(handle);
  526. if (descriptor->run_synth != nullptr)
  527. {
  528. snd_seq_event_t midiEvents[2];
  529. carla_zeroStructs(midiEvents, 2);
  530. const unsigned long midiEventCount = 2;
  531. midiEvents[0].type = SND_SEQ_EVENT_NOTEON;
  532. midiEvents[0].data.note.note = 64;
  533. midiEvents[0].data.note.velocity = 100;
  534. midiEvents[1].type = SND_SEQ_EVENT_NOTEOFF;
  535. midiEvents[1].data.note.note = 64;
  536. midiEvents[1].data.note.velocity = 0;
  537. midiEvents[1].time.tick = kBufferSize/2;
  538. descriptor->run_synth(handle, kBufferSize, midiEvents, midiEventCount);
  539. }
  540. else
  541. ldescriptor->run(handle, kBufferSize);
  542. if (ldescriptor->deactivate != nullptr)
  543. ldescriptor->deactivate(handle);
  544. ldescriptor->cleanup(handle);
  545. // end crash-free plugin test
  546. // -----------------------------------------------------------------------
  547. }
  548. DISCOVERY_OUT("init", "-----------");
  549. DISCOVERY_OUT("build", BINARY_NATIVE);
  550. DISCOVERY_OUT("hints", hints);
  551. DISCOVERY_OUT("name", ldescriptor->Name);
  552. DISCOVERY_OUT("label", ldescriptor->Label);
  553. DISCOVERY_OUT("maker", ldescriptor->Maker);
  554. DISCOVERY_OUT("uniqueId", ldescriptor->UniqueID);
  555. DISCOVERY_OUT("audio.ins", audioIns);
  556. DISCOVERY_OUT("audio.outs", audioOuts);
  557. DISCOVERY_OUT("midi.ins", midiIns);
  558. DISCOVERY_OUT("parameters.ins", parametersIns);
  559. DISCOVERY_OUT("parameters.outs", parametersOuts);
  560. DISCOVERY_OUT("end", "------------");
  561. }
  562. }
  563. #ifndef BUILD_BRIDGE
  564. static void do_lv2_check(const char* const bundle, const bool doInit)
  565. {
  566. Lv2WorldClass& lv2World(Lv2WorldClass::getInstance());
  567. Lilv::Node bundleNode(lv2World.new_file_uri(nullptr, bundle));
  568. CARLA_SAFE_ASSERT_RETURN(bundleNode.is_uri(),);
  569. CarlaString sBundle(bundleNode.as_uri());
  570. if (! sBundle.endsWith("/"))
  571. sBundle += "/";
  572. // Load bundle
  573. lv2World.load_bundle(sBundle);
  574. // Load plugins in this bundle
  575. const Lilv::Plugins lilvPlugins(lv2World.get_all_plugins());
  576. // Get all plugin URIs in this bundle
  577. StringArray URIs;
  578. LILV_FOREACH(plugins, it, lilvPlugins)
  579. {
  580. Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, it));
  581. if (const char* const uri = lilvPlugin.get_uri().as_string())
  582. URIs.addIfNotAlreadyThere(water::String(uri));
  583. }
  584. if (URIs.size() == 0)
  585. {
  586. DISCOVERY_OUT("warning", "LV2 Bundle doesn't provide any plugins");
  587. return;
  588. }
  589. // Get & check every plugin-instance
  590. for (int i=0, count=URIs.size(); i < count; ++i)
  591. {
  592. const char* const URI = URIs[i].toRawUTF8();
  593. CarlaScopedPointer<const LV2_RDF_Descriptor> rdfDescriptor(lv2_rdf_new(URI, false));
  594. if (rdfDescriptor == nullptr || rdfDescriptor->URI == nullptr)
  595. {
  596. DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URI << "'");
  597. continue;
  598. }
  599. if (doInit)
  600. {
  601. // test if lib is loadable, twice
  602. const lib_t libHandle1 = lib_open(rdfDescriptor->Binary);
  603. if (libHandle1 == nullptr)
  604. {
  605. print_lib_error(rdfDescriptor->Binary);
  606. delete rdfDescriptor;
  607. continue;
  608. }
  609. lib_close(libHandle1);
  610. const lib_t libHandle2 = lib_open(rdfDescriptor->Binary);
  611. if (libHandle2 == nullptr)
  612. {
  613. print_lib_error(rdfDescriptor->Binary);
  614. delete rdfDescriptor;
  615. continue;
  616. }
  617. lib_close(libHandle2);
  618. }
  619. const LilvPlugin* const cPlugin(lv2World.getPluginFromURI(URI));
  620. CARLA_SAFE_ASSERT_CONTINUE(cPlugin != nullptr);
  621. Lilv::Plugin lilvPlugin(cPlugin);
  622. CARLA_SAFE_ASSERT_CONTINUE(lilvPlugin.get_uri().is_uri());
  623. print_cached_plugin(get_cached_plugin_lv2(lv2World, lilvPlugin));
  624. }
  625. }
  626. #endif
  627. #ifndef USE_JUCE_PROCESSORS
  628. // --------------------------------------------------------------------------
  629. // VST stuff
  630. // Check if plugin is currently processing
  631. static bool gVstIsProcessing = false;
  632. // Check if plugin needs idle
  633. static bool gVstNeedsIdle = false;
  634. // Check if plugin wants midi
  635. static bool gVstWantsMidi = false;
  636. // Check if plugin wants time
  637. static bool gVstWantsTime = false;
  638. // Current uniqueId for VST shell plugins
  639. static intptr_t gVstCurrentUniqueId = 0;
  640. // Supported Carla features
  641. static intptr_t vstHostCanDo(const char* const feature)
  642. {
  643. carla_debug("vstHostCanDo(\"%s\")", feature);
  644. if (std::strcmp(feature, "supplyIdle") == 0)
  645. return 1;
  646. if (std::strcmp(feature, "sendVstEvents") == 0)
  647. return 1;
  648. if (std::strcmp(feature, "sendVstMidiEvent") == 0)
  649. return 1;
  650. if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
  651. return 1;
  652. if (std::strcmp(feature, "sendVstTimeInfo") == 0)
  653. {
  654. gVstWantsTime = true;
  655. return 1;
  656. }
  657. if (std::strcmp(feature, "receiveVstEvents") == 0)
  658. return 1;
  659. if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
  660. return 1;
  661. if (std::strcmp(feature, "receiveVstTimeInfo") == 0)
  662. return -1;
  663. if (std::strcmp(feature, "reportConnectionChanges") == 0)
  664. return -1;
  665. if (std::strcmp(feature, "acceptIOChanges") == 0)
  666. return 1;
  667. if (std::strcmp(feature, "sizeWindow") == 0)
  668. return 1;
  669. if (std::strcmp(feature, "offline") == 0)
  670. return -1;
  671. if (std::strcmp(feature, "openFileSelector") == 0)
  672. return -1;
  673. if (std::strcmp(feature, "closeFileSelector") == 0)
  674. return -1;
  675. if (std::strcmp(feature, "startStopProcess") == 0)
  676. return 1;
  677. if (std::strcmp(feature, "supportShell") == 0)
  678. return 1;
  679. if (std::strcmp(feature, "shellCategory") == 0)
  680. return 1;
  681. if (std::strcmp(feature, "NIMKPIVendorSpecificCallbacks") == 0)
  682. return -1;
  683. // non-official features found in some plugins:
  684. // "asyncProcessing"
  685. // "editFile"
  686. // unimplemented
  687. carla_stderr("vstHostCanDo(\"%s\") - unknown feature", feature);
  688. return 0;
  689. }
  690. // Host-side callback
  691. 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)
  692. {
  693. carla_debug("vstHostCallback(%p, %i:%s, %i, " P_INTPTR ", %p, %f)",
  694. effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  695. static VstTimeInfo timeInfo;
  696. intptr_t ret = 0;
  697. switch (opcode)
  698. {
  699. case audioMasterAutomate:
  700. ret = 1;
  701. break;
  702. case audioMasterVersion:
  703. ret = kVstVersion;
  704. break;
  705. case audioMasterCurrentId:
  706. ret = gVstCurrentUniqueId;
  707. break;
  708. case DECLARE_VST_DEPRECATED(audioMasterWantMidi):
  709. if (gVstWantsMidi) { DISCOVERY_OUT("warning", "Plugin requested MIDI more than once"); }
  710. gVstWantsMidi = true;
  711. ret = 1;
  712. break;
  713. case audioMasterGetTime:
  714. if (! gVstIsProcessing) { DISCOVERY_OUT("warning", "Plugin requested timeInfo out of process"); }
  715. if (! gVstWantsTime) { DISCOVERY_OUT("warning", "Plugin requested timeInfo but didn't ask if host could do \"sendVstTimeInfo\""); }
  716. carla_zeroStruct(timeInfo);
  717. timeInfo.sampleRate = kSampleRate;
  718. // Tempo
  719. timeInfo.tempo = 120.0;
  720. timeInfo.flags |= kVstTempoValid;
  721. // Time Signature
  722. timeInfo.timeSigNumerator = 4;
  723. timeInfo.timeSigDenominator = 4;
  724. timeInfo.flags |= kVstTimeSigValid;
  725. ret = (intptr_t)&timeInfo;
  726. break;
  727. case DECLARE_VST_DEPRECATED(audioMasterTempoAt):
  728. ret = 120 * 10000;
  729. break;
  730. case DECLARE_VST_DEPRECATED(audioMasterGetNumAutomatableParameters):
  731. ret = carla_minPositive(effect->numParams, static_cast<int>(MAX_DEFAULT_PARAMETERS));
  732. break;
  733. case DECLARE_VST_DEPRECATED(audioMasterGetParameterQuantization):
  734. ret = 1; // full single float precision
  735. break;
  736. case DECLARE_VST_DEPRECATED(audioMasterNeedIdle):
  737. if (gVstNeedsIdle) { DISCOVERY_OUT("warning", "Plugin requested idle more than once"); }
  738. gVstNeedsIdle = true;
  739. ret = 1;
  740. break;
  741. case audioMasterGetSampleRate:
  742. ret = kSampleRatei;
  743. break;
  744. case audioMasterGetBlockSize:
  745. ret = kBufferSize;
  746. break;
  747. case DECLARE_VST_DEPRECATED(audioMasterWillReplaceOrAccumulate):
  748. ret = 1; // replace
  749. break;
  750. case audioMasterGetCurrentProcessLevel:
  751. ret = gVstIsProcessing ? kVstProcessLevelRealtime : kVstProcessLevelUser;
  752. break;
  753. case audioMasterGetAutomationState:
  754. ret = kVstAutomationOff;
  755. break;
  756. case audioMasterGetVendorString:
  757. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  758. std::strcpy((char*)ptr, "falkTX");
  759. ret = 1;
  760. break;
  761. case audioMasterGetProductString:
  762. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  763. std::strcpy((char*)ptr, "Carla-Discovery");
  764. ret = 1;
  765. break;
  766. case audioMasterGetVendorVersion:
  767. ret = CARLA_VERSION_HEX;
  768. break;
  769. case audioMasterCanDo:
  770. CARLA_SAFE_ASSERT_BREAK(ptr != nullptr);
  771. ret = vstHostCanDo((const char*)ptr);
  772. break;
  773. case audioMasterGetLanguage:
  774. ret = kVstLangEnglish;
  775. break;
  776. default:
  777. carla_stdout("vstHostCallback(%p, %i:%s, %i, " P_INTPTR ", %p, %f)",
  778. effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, static_cast<double>(opt));
  779. break;
  780. }
  781. return ret;
  782. }
  783. static void do_vst_check(lib_t& libHandle, const char* const filename, const bool doInit)
  784. {
  785. VST_Function vstFn = nullptr;
  786. #ifdef CARLA_OS_MAC
  787. CFBundleRef bundleRef = nullptr;
  788. CFBundleRefNum resFileId = 0;
  789. if (libHandle == nullptr)
  790. {
  791. const CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)filename, (CFIndex)strlen(filename), true);
  792. CARLA_SAFE_ASSERT_RETURN(urlRef != nullptr,);
  793. bundleRef = CFBundleCreate(kCFAllocatorDefault, urlRef);
  794. CFRelease(urlRef);
  795. CARLA_SAFE_ASSERT_RETURN(bundleRef != nullptr,);
  796. if (! CFBundleLoadExecutable(bundleRef))
  797. {
  798. CFRelease(bundleRef);
  799. DISCOVERY_OUT("error", "Failed to load VST bundle executable");
  800. return;
  801. }
  802. vstFn = (VST_Function)CFBundleGetFunctionPointerForName(bundleRef, CFSTR("main_macho"));
  803. if (vstFn == nullptr)
  804. vstFn = (VST_Function)CFBundleGetFunctionPointerForName(bundleRef, CFSTR("VSTPluginMain"));
  805. if (vstFn == nullptr)
  806. {
  807. CFBundleUnloadExecutable(bundleRef);
  808. CFRelease(bundleRef);
  809. DISCOVERY_OUT("error", "Not a VST plugin");
  810. return;
  811. }
  812. resFileId = CFBundleOpenBundleResourceMap(bundleRef);
  813. }
  814. else
  815. #endif
  816. {
  817. vstFn = lib_symbol<VST_Function>(libHandle, "VSTPluginMain");
  818. if (vstFn == nullptr)
  819. {
  820. vstFn = lib_symbol<VST_Function>(libHandle, "main");
  821. if (vstFn == nullptr)
  822. {
  823. DISCOVERY_OUT("error", "Not a VST plugin");
  824. return;
  825. }
  826. }
  827. }
  828. AEffect* effect = vstFn(vstHostCallback);
  829. if (effect == nullptr || effect->magic != kEffectMagic)
  830. {
  831. DISCOVERY_OUT("error", "Failed to init VST plugin, or VST magic failed");
  832. return;
  833. }
  834. if (effect->uniqueID == 0)
  835. {
  836. DISCOVERY_OUT("warning", "Plugin doesn't have an Unique ID when first loaded");
  837. }
  838. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdentify), 0, 0, nullptr, 0.0f);
  839. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effSetBlockSizeAndSampleRate), 0, kBufferSize, nullptr, kSampleRatef);
  840. effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRatef);
  841. effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
  842. effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  843. effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
  844. if (effect->numPrograms > 0)
  845. effect->dispatcher(effect, effSetProgram, 0, 0, nullptr, 0.0f);
  846. const bool isShell = (effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f) == kPlugCategShell);
  847. if (effect->uniqueID == 0 && !isShell)
  848. {
  849. DISCOVERY_OUT("error", "Plugin doesn't have an Unique ID after being open");
  850. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  851. return;
  852. }
  853. gVstCurrentUniqueId = effect->uniqueID;
  854. char strBuf[STR_MAX+1];
  855. CarlaString cName;
  856. CarlaString cProduct;
  857. CarlaString cVendor;
  858. LinkedList<intptr_t> uniqueIds;
  859. if (isShell)
  860. {
  861. for (;;)
  862. {
  863. carla_zeroChars(strBuf, STR_MAX+1);
  864. gVstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);
  865. if (gVstCurrentUniqueId == 0)
  866. break;
  867. uniqueIds.append(gVstCurrentUniqueId);
  868. }
  869. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  870. effect = nullptr;
  871. }
  872. else
  873. {
  874. uniqueIds.append(gVstCurrentUniqueId);
  875. }
  876. for (LinkedList<intptr_t>::Itenerator it = uniqueIds.begin2(); it.valid(); it.next())
  877. {
  878. gVstCurrentUniqueId = it.getValue(0);
  879. if (effect == nullptr)
  880. {
  881. effect = vstFn(vstHostCallback);
  882. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdentify), 0, 0, nullptr, 0.0f);
  883. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effSetBlockSizeAndSampleRate), 0, kBufferSize, nullptr, kSampleRatef);
  884. effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, kSampleRatef);
  885. effect->dispatcher(effect, effSetBlockSize, 0, kBufferSize, nullptr, 0.0f);
  886. effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  887. effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
  888. if (effect->numPrograms > 0)
  889. effect->dispatcher(effect, effSetProgram, 0, 0, nullptr, 0.0f);
  890. }
  891. // get name
  892. carla_zeroChars(strBuf, STR_MAX+1);
  893. if (effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f) == 1)
  894. cName = strBuf;
  895. else
  896. cName.clear();
  897. // get product
  898. carla_zeroChars(strBuf, STR_MAX+1);
  899. if (effect->dispatcher(effect, effGetProductString, 0, 0, strBuf, 0.0f) == 1)
  900. cProduct = strBuf;
  901. else
  902. cProduct.clear();
  903. // get vendor
  904. carla_zeroChars(strBuf, STR_MAX+1);
  905. if (effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f) == 1)
  906. cVendor = strBuf;
  907. else
  908. cVendor.clear();
  909. // get everything else
  910. uint hints = 0x0;
  911. uint audioIns = static_cast<uint>(std::max(0, effect->numInputs));
  912. uint audioOuts = static_cast<uint>(std::max(0, effect->numOutputs));
  913. uint midiIns = 0;
  914. uint midiOuts = 0;
  915. uint parameters = static_cast<uint>(std::max(0, effect->numParams));
  916. if (effect->flags & effFlagsHasEditor)
  917. hints |= PLUGIN_HAS_CUSTOM_UI;
  918. if (effect->flags & effFlagsIsSynth)
  919. hints |= PLUGIN_IS_SYNTH;
  920. if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || (effect->flags & effFlagsIsSynth) != 0)
  921. midiIns = 1;
  922. if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent"))
  923. midiOuts = 1;
  924. // -----------------------------------------------------------------------
  925. // start crash-free plugin test
  926. if (doInit)
  927. {
  928. if (gVstNeedsIdle)
  929. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  930. effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
  931. effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
  932. if (gVstNeedsIdle)
  933. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  934. // Plugin might call wantMidi() during resume
  935. if (midiIns == 0 && gVstWantsMidi)
  936. {
  937. midiIns = 1;
  938. }
  939. float* bufferAudioIn[std::max(1U, audioIns)];
  940. float* bufferAudioOut[std::max(1U, audioOuts)];
  941. if (audioIns == 0)
  942. {
  943. bufferAudioIn[0] = nullptr;
  944. }
  945. else
  946. {
  947. for (uint j=0; j < audioIns; ++j)
  948. {
  949. bufferAudioIn[j] = new float[kBufferSize];
  950. carla_zeroFloats(bufferAudioIn[j], kBufferSize);
  951. }
  952. }
  953. if (audioOuts == 0)
  954. {
  955. bufferAudioOut[0] = nullptr;
  956. }
  957. else
  958. {
  959. for (uint j=0; j < audioOuts; ++j)
  960. {
  961. bufferAudioOut[j] = new float[kBufferSize];
  962. carla_zeroFloats(bufferAudioOut[j], kBufferSize);
  963. }
  964. }
  965. struct VstEventsFixed {
  966. int32_t numEvents;
  967. intptr_t reserved;
  968. VstEvent* data[2];
  969. VstEventsFixed()
  970. : numEvents(0),
  971. reserved(0)
  972. {
  973. data[0] = data[1] = nullptr;
  974. }
  975. } events;
  976. VstMidiEvent midiEvents[2];
  977. carla_zeroStructs(midiEvents, 2);
  978. midiEvents[0].type = kVstMidiType;
  979. midiEvents[0].byteSize = sizeof(VstMidiEvent);
  980. midiEvents[0].midiData[0] = char(MIDI_STATUS_NOTE_ON);
  981. midiEvents[0].midiData[1] = 64;
  982. midiEvents[0].midiData[2] = 100;
  983. midiEvents[1].type = kVstMidiType;
  984. midiEvents[1].byteSize = sizeof(VstMidiEvent);
  985. midiEvents[1].midiData[0] = char(MIDI_STATUS_NOTE_OFF);
  986. midiEvents[1].midiData[1] = 64;
  987. midiEvents[1].deltaFrames = kBufferSize/2;
  988. events.numEvents = 2;
  989. events.data[0] = (VstEvent*)&midiEvents[0];
  990. events.data[1] = (VstEvent*)&midiEvents[1];
  991. // processing
  992. gVstIsProcessing = true;
  993. if (midiIns > 0)
  994. effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);
  995. if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing != nullptr && effect->processReplacing != effect->DECLARE_VST_DEPRECATED(process))
  996. effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
  997. else if (effect->DECLARE_VST_DEPRECATED(process) != nullptr)
  998. effect->DECLARE_VST_DEPRECATED(process)(effect, bufferAudioIn, bufferAudioOut, kBufferSize);
  999. else
  1000. DISCOVERY_OUT("error", "Plugin doesn't have a process function");
  1001. gVstIsProcessing = false;
  1002. effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
  1003. effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
  1004. if (gVstNeedsIdle)
  1005. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1006. for (uint j=0; j < audioIns; ++j)
  1007. delete[] bufferAudioIn[j];
  1008. for (uint j=0; j < audioOuts; ++j)
  1009. delete[] bufferAudioOut[j];
  1010. }
  1011. // end crash-free plugin test
  1012. // -----------------------------------------------------------------------
  1013. DISCOVERY_OUT("init", "-----------");
  1014. DISCOVERY_OUT("build", BINARY_NATIVE);
  1015. DISCOVERY_OUT("hints", hints);
  1016. DISCOVERY_OUT("name", cName.buffer());
  1017. DISCOVERY_OUT("label", cProduct.buffer());
  1018. DISCOVERY_OUT("maker", cVendor.buffer());
  1019. DISCOVERY_OUT("uniqueId", gVstCurrentUniqueId);
  1020. DISCOVERY_OUT("audio.ins", audioIns);
  1021. DISCOVERY_OUT("audio.outs", audioOuts);
  1022. DISCOVERY_OUT("midi.ins", midiIns);
  1023. DISCOVERY_OUT("midi.outs", midiOuts);
  1024. DISCOVERY_OUT("parameters.ins", parameters);
  1025. DISCOVERY_OUT("end", "------------");
  1026. gVstWantsMidi = false;
  1027. gVstWantsTime = false;
  1028. if (! isShell)
  1029. break;
  1030. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  1031. effect = nullptr;
  1032. }
  1033. uniqueIds.clear();
  1034. if (effect != nullptr)
  1035. {
  1036. if (gVstNeedsIdle)
  1037. effect->dispatcher(effect, DECLARE_VST_DEPRECATED(effIdle), 0, 0, nullptr, 0.0f);
  1038. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  1039. }
  1040. #ifdef CARLA_OS_MAC
  1041. if (bundleRef != nullptr)
  1042. {
  1043. CFBundleCloseBundleResourceMap(bundleRef, resFileId);
  1044. CFBundleUnloadExecutable(bundleRef);
  1045. CFRelease(bundleRef);
  1046. }
  1047. #else
  1048. return;
  1049. // unused
  1050. (void)filename;
  1051. #endif
  1052. }
  1053. #endif // ! USE_JUCE_PROCESSORS
  1054. #ifdef USE_JUCE_PROCESSORS
  1055. namespace juce {
  1056. extern bool juce_isRunningInWine();
  1057. }
  1058. static void do_juce_check(const char* const filename_, const char* const stype, const bool doInit)
  1059. {
  1060. CARLA_SAFE_ASSERT_RETURN(stype != nullptr && stype[0] != 0,) // FIXME
  1061. carla_debug("do_juce_check(%s, %s, %s)", filename_, stype, bool2str(doInit));
  1062. juce::String filename;
  1063. #ifdef CARLA_OS_WIN
  1064. // Fix for wine usage
  1065. if (juce::juce_isRunningInWine() && filename_[0] == '/')
  1066. {
  1067. filename = filename_;
  1068. filename.replace("/", "\\");
  1069. filename = "Z:" + filename;
  1070. }
  1071. else
  1072. #endif
  1073. filename = juce::File(filename_).getFullPathName();
  1074. juce::ScopedPointer<juce::AudioPluginFormat> pluginFormat;
  1075. /* */ if (std::strcmp(stype, "VST2") == 0)
  1076. {
  1077. #if JUCE_PLUGINHOST_VST
  1078. pluginFormat = new juce::VSTPluginFormat();
  1079. #else
  1080. DISCOVERY_OUT("error", "VST support not available");
  1081. #endif
  1082. }
  1083. else if (std::strcmp(stype, "VST3") == 0)
  1084. {
  1085. #if JUCE_PLUGINHOST_VST3
  1086. pluginFormat = new juce::VST3PluginFormat();
  1087. #else
  1088. DISCOVERY_OUT("error", "VST3 support not available");
  1089. #endif
  1090. }
  1091. else if (std::strcmp(stype, "AU") == 0)
  1092. {
  1093. #if JUCE_PLUGINHOST_AU
  1094. pluginFormat = new juce::AudioUnitPluginFormat();
  1095. #else
  1096. DISCOVERY_OUT("error", "AU support not available");
  1097. #endif
  1098. }
  1099. if (pluginFormat == nullptr)
  1100. {
  1101. DISCOVERY_OUT("error", stype << " support not available");
  1102. return;
  1103. }
  1104. #ifdef CARLA_OS_WIN
  1105. CARLA_SAFE_ASSERT_RETURN(juce::File(filename).existsAsFile(),);
  1106. #endif
  1107. CARLA_SAFE_ASSERT_RETURN(pluginFormat->fileMightContainThisPluginType(filename),);
  1108. juce::OwnedArray<juce::PluginDescription> results;
  1109. pluginFormat->findAllTypesForFile(results, filename);
  1110. if (results.size() == 0)
  1111. {
  1112. DISCOVERY_OUT("error", "No plugins found");
  1113. return;
  1114. }
  1115. for (juce::PluginDescription **it = results.begin(), **end = results.end(); it != end; ++it)
  1116. {
  1117. juce::PluginDescription* const desc(*it);
  1118. uint hints = 0x0;
  1119. int audioIns = desc->numInputChannels;
  1120. int audioOuts = desc->numOutputChannels;
  1121. int midiIns = 0;
  1122. int midiOuts = 0;
  1123. int parameters = 0;
  1124. if (desc->isInstrument)
  1125. hints |= PLUGIN_IS_SYNTH;
  1126. if (doInit)
  1127. {
  1128. if (juce::AudioPluginInstance* const instance = pluginFormat->createInstanceFromDescription(*desc, kSampleRate, kBufferSize))
  1129. {
  1130. instance->refreshParameterList();
  1131. parameters = instance->getNumParameters();
  1132. if (instance->hasEditor())
  1133. hints |= PLUGIN_HAS_CUSTOM_UI;
  1134. if (instance->acceptsMidi())
  1135. midiIns = 1;
  1136. if (instance->producesMidi())
  1137. midiOuts = 1;
  1138. delete instance;
  1139. }
  1140. }
  1141. DISCOVERY_OUT("init", "-----------");
  1142. DISCOVERY_OUT("build", BINARY_NATIVE);
  1143. DISCOVERY_OUT("hints", hints);
  1144. DISCOVERY_OUT("name", desc->descriptiveName);
  1145. DISCOVERY_OUT("label", desc->name);
  1146. DISCOVERY_OUT("maker", desc->manufacturerName);
  1147. DISCOVERY_OUT("uniqueId", desc->uid);
  1148. DISCOVERY_OUT("audio.ins", audioIns);
  1149. DISCOVERY_OUT("audio.outs", audioOuts);
  1150. DISCOVERY_OUT("midi.ins", midiIns);
  1151. DISCOVERY_OUT("midi.outs", midiOuts);
  1152. DISCOVERY_OUT("parameters.ins", parameters);
  1153. DISCOVERY_OUT("end", "------------");
  1154. }
  1155. }
  1156. #endif // USE_JUCE_PROCESSORS
  1157. static void do_fluidsynth_check(const char* const filename, const bool doInit)
  1158. {
  1159. #ifdef HAVE_FLUIDSYNTH
  1160. const water::String jfilename = water::String(CharPointer_UTF8(filename));
  1161. const File file(jfilename);
  1162. if (! file.existsAsFile())
  1163. {
  1164. DISCOVERY_OUT("error", "Requested file is not valid or does not exist");
  1165. return;
  1166. }
  1167. if (! fluid_is_soundfont(filename))
  1168. {
  1169. DISCOVERY_OUT("error", "Not a SF2 file");
  1170. return;
  1171. }
  1172. int programs = 0;
  1173. if (doInit)
  1174. {
  1175. fluid_settings_t* const f_settings = new_fluid_settings();
  1176. CARLA_SAFE_ASSERT_RETURN(f_settings != nullptr,);
  1177. fluid_synth_t* const f_synth = new_fluid_synth(f_settings);
  1178. CARLA_SAFE_ASSERT_RETURN(f_synth != nullptr,);
  1179. const int f_id = fluid_synth_sfload(f_synth, filename, 0);
  1180. if (f_id < 0)
  1181. {
  1182. DISCOVERY_OUT("error", "Failed to load SF2 file");
  1183. return;
  1184. }
  1185. if (fluid_sfont_t* const f_sfont = fluid_synth_get_sfont_by_id(f_synth, static_cast<uint>(f_id)))
  1186. {
  1187. #if FLUIDSYNTH_VERSION_MAJOR < 2
  1188. fluid_preset_t f_preset;
  1189. f_sfont->iteration_start(f_sfont);
  1190. for (; f_sfont->iteration_next(f_sfont, &f_preset);)
  1191. #else
  1192. fluid_sfont_iteration_start(f_sfont);
  1193. for (; fluid_sfont_iteration_next(f_sfont);)
  1194. #endif
  1195. ++programs;
  1196. }
  1197. delete_fluid_synth(f_synth);
  1198. delete_fluid_settings(f_settings);
  1199. }
  1200. CarlaString name(file.getFileNameWithoutExtension().toRawUTF8());
  1201. CarlaString label(name);
  1202. // 2 channels
  1203. DISCOVERY_OUT("init", "-----------");
  1204. DISCOVERY_OUT("build", BINARY_NATIVE);
  1205. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1206. DISCOVERY_OUT("name", name.buffer());
  1207. DISCOVERY_OUT("label", label.buffer());
  1208. DISCOVERY_OUT("audio.outs", 2);
  1209. DISCOVERY_OUT("midi.ins", 1);
  1210. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1211. DISCOVERY_OUT("parameters.outs", 1);
  1212. DISCOVERY_OUT("end", "------------");
  1213. // 16 channels
  1214. if (doInit && (name.isEmpty() || programs <= 1))
  1215. return;
  1216. name += " (16 outputs)";
  1217. DISCOVERY_OUT("init", "-----------");
  1218. DISCOVERY_OUT("build", BINARY_NATIVE);
  1219. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1220. DISCOVERY_OUT("name", name.buffer());
  1221. DISCOVERY_OUT("label", label.buffer());
  1222. DISCOVERY_OUT("audio.outs", 32);
  1223. DISCOVERY_OUT("midi.ins", 1);
  1224. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1225. DISCOVERY_OUT("parameters.outs", 1);
  1226. DISCOVERY_OUT("end", "------------");
  1227. #else // HAVE_FLUIDSYNTH
  1228. DISCOVERY_OUT("error", "SF2 support not available");
  1229. return;
  1230. // unused
  1231. (void)filename;
  1232. (void)doInit;
  1233. #endif
  1234. }
  1235. // ------------------------------ main entry point ------------------------------
  1236. int main(int argc, char* argv[])
  1237. {
  1238. if (argc != 3)
  1239. {
  1240. carla_stdout("usage: %s <type> </path/to/plugin>", argv[0]);
  1241. return 1;
  1242. }
  1243. const char* const stype = argv[1];
  1244. const char* const filename = argv[2];
  1245. const PluginType type = getPluginTypeFromString(stype);
  1246. CarlaString filenameCheck(filename);
  1247. filenameCheck.toLower();
  1248. bool openLib = false;
  1249. lib_t handle = nullptr;
  1250. switch (type)
  1251. {
  1252. case PLUGIN_LADSPA:
  1253. case PLUGIN_DSSI:
  1254. case PLUGIN_VST2:
  1255. openLib = true;
  1256. default:
  1257. break;
  1258. }
  1259. if (type != PLUGIN_SF2 && filenameCheck.contains("fluidsynth", true))
  1260. {
  1261. DISCOVERY_OUT("info", "skipping fluidsynth based plugin");
  1262. return 0;
  1263. }
  1264. #ifdef CARLA_OS_MAC
  1265. if (type == PLUGIN_VST2 && (filenameCheck.endsWith(".vst") || filenameCheck.endsWith(".vst/")))
  1266. openLib = false;
  1267. #endif
  1268. // ---------------------------------------------------------------------
  1269. // Initialize OS features
  1270. #ifdef CARLA_OS_WIN
  1271. OleInitialize(nullptr);
  1272. CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
  1273. # ifndef __WINPTHREADS_VERSION
  1274. // (non-portable) initialization of statically linked pthread library
  1275. pthread_win32_process_attach_np();
  1276. pthread_win32_thread_attach_np();
  1277. # endif
  1278. #endif
  1279. // ---------------------------------------------------------------------
  1280. if (openLib)
  1281. {
  1282. handle = lib_open(filename);
  1283. if (handle == nullptr)
  1284. {
  1285. print_lib_error(filename);
  1286. return 1;
  1287. }
  1288. }
  1289. // never do init for dssi-vst, takes too long and it's crashy
  1290. bool doInit = ! filenameCheck.contains("dssi-vst", true);
  1291. if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") != nullptr)
  1292. doInit = false;
  1293. // ---------------------------------------------------------------------
  1294. if (doInit && openLib && handle != nullptr)
  1295. {
  1296. // test fast loading & unloading DLL without initializing the plugin(s)
  1297. if (! lib_close(handle))
  1298. {
  1299. print_lib_error(filename);
  1300. return 1;
  1301. }
  1302. handle = lib_open(filename);
  1303. if (handle == nullptr)
  1304. {
  1305. print_lib_error(filename);
  1306. return 1;
  1307. }
  1308. }
  1309. #ifndef BUILD_BRIDGE
  1310. if (std::strcmp(filename, ":all") == 0)
  1311. {
  1312. do_cached_check(type);
  1313. return 0;
  1314. }
  1315. #endif
  1316. switch (type)
  1317. {
  1318. case PLUGIN_LADSPA:
  1319. do_ladspa_check(handle, filename, doInit);
  1320. break;
  1321. case PLUGIN_DSSI:
  1322. do_dssi_check(handle, filename, doInit);
  1323. break;
  1324. #ifndef BUILD_BRIDGE
  1325. case PLUGIN_LV2:
  1326. do_lv2_check(filename, doInit);
  1327. break;
  1328. #endif
  1329. case PLUGIN_VST2:
  1330. #ifdef USE_JUCE_PROCESSORS
  1331. do_juce_check(filename, "VST2", doInit);
  1332. #else
  1333. do_vst_check(handle, filename, doInit);
  1334. #endif
  1335. break;
  1336. case PLUGIN_VST3:
  1337. #ifdef USE_JUCE_PROCESSORS
  1338. do_juce_check(filename, "VST3", doInit);
  1339. #else
  1340. DISCOVERY_OUT("error", "VST3 support not available");
  1341. #endif
  1342. break;
  1343. case PLUGIN_AU:
  1344. #ifdef USE_JUCE_PROCESSORS
  1345. do_juce_check(filename, "AU", doInit);
  1346. #else
  1347. DISCOVERY_OUT("error", "AU support not available");
  1348. #endif
  1349. break;
  1350. case PLUGIN_SF2:
  1351. do_fluidsynth_check(filename, doInit);
  1352. break;
  1353. default:
  1354. break;
  1355. }
  1356. if (openLib && handle != nullptr)
  1357. lib_close(handle);
  1358. // ---------------------------------------------------------------------
  1359. #ifdef CARLA_OS_WIN
  1360. #ifndef __WINPTHREADS_VERSION
  1361. pthread_win32_thread_detach_np();
  1362. pthread_win32_process_detach_np();
  1363. #endif
  1364. CoUninitialize();
  1365. OleUninitialize();
  1366. #endif
  1367. return 0;
  1368. }
  1369. // --------------------------------------------------------------------------