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

12 years ago
11 years ago
11 years ago
12 years ago
12 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
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
12 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
12 years ago
11 years ago
12 years ago
11 years ago
12 years ago
11 years ago
11 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
11 years ago
12 years ago
12 years ago
12 years ago
12 years ago
12 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
11 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558
  1. /*
  2. * Carla Plugin discovery
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #include "CarlaBackend.hpp"
  18. #include "CarlaJuceUtils.hpp"
  19. #include "CarlaLibUtils.hpp"
  20. #include "CarlaString.hpp"
  21. #include "CarlaMIDI.h"
  22. #ifdef WANT_LADSPA
  23. # include "CarlaLadspaUtils.hpp"
  24. #endif
  25. #ifdef WANT_DSSI
  26. # include "CarlaLadspaUtils.hpp"
  27. # include "dssi/dssi.h"
  28. #endif
  29. #ifdef WANT_LV2
  30. # include <QtCore/QDir>
  31. # include <QtCore/QUrl>
  32. # include "CarlaLv2Utils.hpp"
  33. #endif
  34. #ifdef WANT_VST
  35. # include "CarlaVstUtils.hpp"
  36. #endif
  37. #ifdef WANT_FLUIDSYNTH
  38. # include <fluidsynth.h>
  39. #endif
  40. #ifdef WANT_LINUXSAMPLER
  41. # include <QtCore/QFileInfo>
  42. # include "linuxsampler/EngineFactory.h"
  43. #endif
  44. #include <iostream>
  45. #define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl;
  46. CARLA_BACKEND_USE_NAMESPACE
  47. #ifdef WANT_LV2
  48. // --------------------------------------------------------------------------
  49. // Our LV2 World class object
  50. Lv2WorldClass lv2World;
  51. #endif
  52. // --------------------------------------------------------------------------
  53. // Dummy values to test plugins with
  54. const uint32_t bufferSize = 512;
  55. const double sampleRate = 44100.0;
  56. // --------------------------------------------------------------------------
  57. // Don't print ELF/EXE related errors since discovery can find multi-architecture binaries
  58. void print_lib_error(const char* const filename)
  59. {
  60. const char* const error = lib_error(filename);
  61. if (error && strstr(error, "wrong ELF class") == nullptr && strstr(error, "Bad EXE format") == nullptr)
  62. DISCOVERY_OUT("error", error);
  63. }
  64. // --------------------------------------------------------------------------
  65. // VST stuff
  66. #ifdef WANT_VST
  67. // Check if plugin wants midi
  68. bool vstWantsMidi = false;
  69. // Check if plugin is processing
  70. bool vstIsProcessing = false;
  71. // Current uniqueId for vst shell plugins
  72. intptr_t vstCurrentUniqueId = 0;
  73. // Supported Carla features
  74. intptr_t vstHostCanDo(const char* const feature)
  75. {
  76. #if DEBUG
  77. qDebug("vstHostCanDo(\"%s\")", feature);
  78. #endif
  79. if (std::strcmp(feature, "supplyIdle") == 0)
  80. return 1;
  81. if (std::strcmp(feature, "sendVstEvents") == 0)
  82. return 1;
  83. if (std::strcmp(feature, "sendVstMidiEvent") == 0)
  84. return 1;
  85. if (std::strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
  86. return 1;
  87. if (std::strcmp(feature, "sendVstTimeInfo") == 0)
  88. return 1;
  89. if (std::strcmp(feature, "receiveVstEvents") == 0)
  90. return 1;
  91. if (std::strcmp(feature, "receiveVstMidiEvent") == 0)
  92. return 1;
  93. if (std::strcmp(feature, "receiveVstTimeInfo") == 0)
  94. return -1;
  95. if (std::strcmp(feature, "reportConnectionChanges") == 0)
  96. return -1;
  97. if (std::strcmp(feature, "acceptIOChanges") == 0)
  98. return 1;
  99. if (std::strcmp(feature, "sizeWindow") == 0)
  100. return 1;
  101. if (std::strcmp(feature, "offline") == 0)
  102. return -1;
  103. if (std::strcmp(feature, "openFileSelector") == 0)
  104. return -1;
  105. if (std::strcmp(feature, "closeFileSelector") == 0)
  106. return -1;
  107. if (std::strcmp(feature, "startStopProcess") == 0)
  108. return 1;
  109. if (std::strcmp(feature, "supportShell") == 0)
  110. return 1;
  111. if (std::strcmp(feature, "shellCategory") == 0)
  112. return 1;
  113. // unimplemented
  114. qWarning("vstHostCanDo(\"%s\") - unknown feature", feature);
  115. return 0;
  116. }
  117. // Host-side callback
  118. 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)
  119. {
  120. #if DEBUG
  121. qDebug("vstHostCallback(%p, %s, %i, " P_INTPTR ", %p, %f)", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
  122. #endif
  123. intptr_t ret = 0;
  124. switch (opcode)
  125. {
  126. case audioMasterAutomate:
  127. if (effect)
  128. {
  129. effect->setParameter(effect, index, opt);
  130. ret = 1;
  131. }
  132. break;
  133. case audioMasterVersion:
  134. ret = kVstVersion;
  135. break;
  136. case audioMasterCurrentId:
  137. ret = vstCurrentUniqueId;
  138. break;
  139. #if ! VST_FORCE_DEPRECATED
  140. case audioMasterWantMidi:
  141. vstWantsMidi = true;
  142. ret = 1;
  143. break;
  144. #endif
  145. case audioMasterGetTime:
  146. static VstTimeInfo_R timeInfo;
  147. memset(&timeInfo, 0, sizeof(VstTimeInfo_R)); //FIXME
  148. timeInfo.sampleRate = sampleRate;
  149. // Tempo
  150. timeInfo.tempo = 120.0;
  151. timeInfo.flags |= kVstTempoValid;
  152. // Time Signature
  153. timeInfo.timeSigNumerator = 4;
  154. timeInfo.timeSigDenominator = 4;
  155. timeInfo.flags |= kVstTimeSigValid;
  156. ret = (intptr_t)&timeInfo;
  157. break;
  158. #if ! VST_FORCE_DEPRECATED
  159. case audioMasterTempoAt:
  160. ret = 120 * 10000;
  161. break;
  162. case audioMasterGetNumAutomatableParameters:
  163. ret = carla_min<int32_t>(effect->numParams, MAX_DEFAULT_PARAMETERS, 0);
  164. break;
  165. case audioMasterGetParameterQuantization:
  166. ret = 1; // full single float precision
  167. break;
  168. #endif
  169. case audioMasterGetSampleRate:
  170. ret = sampleRate;
  171. break;
  172. case audioMasterGetBlockSize:
  173. ret = bufferSize;
  174. break;
  175. #if ! VST_FORCE_DEPRECATED
  176. case audioMasterWillReplaceOrAccumulate:
  177. ret = 1; // replace
  178. break;
  179. #endif
  180. case audioMasterGetCurrentProcessLevel:
  181. ret = vstIsProcessing ? kVstProcessLevelRealtime : kVstProcessLevelUser;
  182. break;
  183. case audioMasterGetAutomationState:
  184. ret = kVstAutomationOff;
  185. break;
  186. case audioMasterGetVendorString:
  187. if (ptr)
  188. {
  189. std::strcpy((char*)ptr, "falkTX");
  190. ret = 1;
  191. }
  192. break;
  193. case audioMasterGetProductString:
  194. if (ptr)
  195. {
  196. std::strcpy((char*)ptr, "Carla-Discovery");
  197. ret = 1;
  198. }
  199. break;
  200. case audioMasterGetVendorVersion:
  201. ret = 0x050; // 0.5.0
  202. break;
  203. case audioMasterCanDo:
  204. if (ptr)
  205. ret = vstHostCanDo((const char*)ptr);
  206. break;
  207. case audioMasterGetLanguage:
  208. ret = kVstLangEnglish;
  209. break;
  210. default:
  211. qDebug("vstHostCallback(%p, %s, %i, " P_INTPTR ", %p, %f)", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
  212. break;
  213. }
  214. return ret;
  215. }
  216. #endif
  217. // --------------------------------------------------------------------------
  218. // LinuxSampler stuff
  219. #ifdef WANT_LINUXSAMPLER
  220. class LinuxSamplerScopedEngine
  221. {
  222. public:
  223. LinuxSamplerScopedEngine(const char* const filename, const char* const stype)
  224. : engine(nullptr),
  225. ins(nullptr)
  226. {
  227. using namespace LinuxSampler;
  228. try {
  229. engine = EngineFactory::Create(stype);
  230. }
  231. catch (const Exception& e)
  232. {
  233. DISCOVERY_OUT("error", e.what());
  234. return;
  235. }
  236. if (engine == nullptr)
  237. return;
  238. ins = engine->GetInstrumentManager();
  239. if (ins == nullptr)
  240. {
  241. DISCOVERY_OUT("error", "Failed to get LinuxSampler instrument manager");
  242. return;
  243. }
  244. std::vector<InstrumentManager::instrument_id_t> ids;
  245. try {
  246. ids = ins->GetInstrumentFileContent(filename);
  247. }
  248. catch (const Exception& e)
  249. {
  250. DISCOVERY_OUT("error", e.what());
  251. return;
  252. }
  253. if (ids.size() > 0)
  254. {
  255. InstrumentManager::instrument_info_t info = ins->GetInstrumentInfo(ids[0]);
  256. outputInfo(&info, ids.size());
  257. }
  258. }
  259. ~LinuxSamplerScopedEngine()
  260. {
  261. if (engine != nullptr)
  262. LinuxSampler::EngineFactory::Destroy(engine);
  263. }
  264. static void outputInfo(LinuxSampler::InstrumentManager::instrument_info_t* const info, const int programs, const char* const basename = nullptr)
  265. {
  266. DISCOVERY_OUT("init", "-----------");
  267. if (info != nullptr)
  268. {
  269. DISCOVERY_OUT("name", info->InstrumentName);
  270. DISCOVERY_OUT("label", info->Product);
  271. DISCOVERY_OUT("maker", info->Artists);
  272. DISCOVERY_OUT("copyright", info->Artists);
  273. }
  274. else
  275. {
  276. DISCOVERY_OUT("name", basename);
  277. DISCOVERY_OUT("label", basename);
  278. }
  279. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  280. DISCOVERY_OUT("audio.outs", 2);
  281. DISCOVERY_OUT("audio.total", 2);
  282. DISCOVERY_OUT("midi.ins", 1);
  283. DISCOVERY_OUT("midi.total", 1);
  284. DISCOVERY_OUT("programs.total", programs);
  285. //DISCOVERY_OUT("parameters.ins", 13); // defined in Carla - TODO
  286. //DISCOVERY_OUT("parameters.outs", 1);
  287. //DISCOVERY_OUT("parameters.total", 14);
  288. DISCOVERY_OUT("build", BINARY_NATIVE);
  289. DISCOVERY_OUT("end", "------------");
  290. }
  291. private:
  292. LinuxSampler::Engine* engine;
  293. LinuxSampler::InstrumentManager* ins;
  294. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LinuxSamplerScopedEngine)
  295. };
  296. #endif
  297. // ------------------------------ Plugin Checks -----------------------------
  298. void do_ladspa_check(void* const libHandle, const bool init)
  299. {
  300. #ifdef WANT_LADSPA
  301. const LADSPA_Descriptor_Function descFn = (LADSPA_Descriptor_Function)lib_symbol(libHandle, "ladspa_descriptor");
  302. if (! descFn)
  303. {
  304. DISCOVERY_OUT("error", "Not a LADSPA plugin");
  305. return;
  306. }
  307. unsigned long i = 0;
  308. const LADSPA_Descriptor* descriptor;
  309. while ((descriptor = descFn(i++)))
  310. {
  311. if (! descriptor->instantiate)
  312. {
  313. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no instantiate()");
  314. continue;
  315. }
  316. if (! descriptor->cleanup)
  317. {
  318. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no cleanup()");
  319. continue;
  320. }
  321. if (! descriptor->run)
  322. {
  323. DISCOVERY_OUT("error", "Plugin '" << descriptor->Name << "' has no run()");
  324. continue;
  325. }
  326. if (! LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  327. {
  328. DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable");
  329. }
  330. int hints = 0;
  331. int audioIns = 0;
  332. int audioOuts = 0;
  333. int audioTotal = 0;
  334. int parametersIns = 0;
  335. int parametersOuts = 0;
  336. int parametersTotal = 0;
  337. if (LADSPA_IS_HARD_RT_CAPABLE(descriptor->Properties))
  338. hints |= PLUGIN_IS_RTSAFE;
  339. for (unsigned long j=0; j < descriptor->PortCount; j++)
  340. {
  341. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  342. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  343. {
  344. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  345. audioIns += 1;
  346. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  347. audioOuts += 1;
  348. audioTotal += 1;
  349. }
  350. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  351. {
  352. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  353. parametersIns += 1;
  354. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(descriptor->PortNames[j], "latency") && std::strcmp(descriptor->PortNames[j], "_latency"))
  355. parametersOuts += 1;
  356. parametersTotal += 1;
  357. }
  358. }
  359. if (init)
  360. {
  361. // -----------------------------------------------------------------------
  362. // start crash-free plugin test
  363. const LADSPA_Handle handle = descriptor->instantiate(descriptor, sampleRate);
  364. if (! handle)
  365. {
  366. DISCOVERY_OUT("error", "Failed to init LADSPA plugin");
  367. continue;
  368. }
  369. LADSPA_Data bufferAudio[bufferSize][audioTotal];
  370. LADSPA_Data bufferParams[parametersTotal];
  371. LADSPA_Data min, max, def;
  372. for (unsigned long j=0, iA=0, iC=0; j < descriptor->PortCount; j++)
  373. {
  374. const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
  375. const LADSPA_PortRangeHint portRangeHints = descriptor->PortRangeHints[j];
  376. const char* const portName = descriptor->PortNames[j];
  377. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  378. {
  379. carla_zeroFloat(bufferAudio[iA], bufferSize);
  380. descriptor->connect_port(handle, j, bufferAudio[iA++]);
  381. }
  382. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  383. {
  384. // min value
  385. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  386. min = portRangeHints.LowerBound;
  387. else
  388. min = 0.0f;
  389. // max value
  390. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  391. max = portRangeHints.UpperBound;
  392. else
  393. max = 1.0f;
  394. if (min > max)
  395. {
  396. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  397. max = min + 0.1f;
  398. }
  399. else if (max - min == 0.0f)
  400. {
  401. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max - min == 0");
  402. max = min + 0.1f;
  403. }
  404. // default value
  405. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  406. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  407. {
  408. min *= sampleRate;
  409. max *= sampleRate;
  410. def *= sampleRate;
  411. }
  412. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  413. {
  414. // latency parameter
  415. def = 0.0f;
  416. }
  417. else
  418. {
  419. if (def < min)
  420. def = min;
  421. else if (def > max)
  422. def = max;
  423. }
  424. bufferParams[iC] = def;
  425. descriptor->connect_port(handle, j, &bufferParams[iC++]);
  426. }
  427. }
  428. if (descriptor->activate)
  429. descriptor->activate(handle);
  430. descriptor->run(handle, bufferSize);
  431. if (descriptor->deactivate)
  432. descriptor->deactivate(handle);
  433. descriptor->cleanup(handle);
  434. // end crash-free plugin test
  435. // -----------------------------------------------------------------------
  436. }
  437. DISCOVERY_OUT("init", "-----------");
  438. DISCOVERY_OUT("name", descriptor->Name);
  439. DISCOVERY_OUT("label", descriptor->Label);
  440. DISCOVERY_OUT("maker", descriptor->Maker);
  441. DISCOVERY_OUT("copyright", descriptor->Copyright);
  442. DISCOVERY_OUT("uniqueId", descriptor->UniqueID);
  443. DISCOVERY_OUT("hints", hints);
  444. DISCOVERY_OUT("audio.ins", audioIns);
  445. DISCOVERY_OUT("audio.outs", audioOuts);
  446. DISCOVERY_OUT("audio.total", audioTotal);
  447. DISCOVERY_OUT("parameters.ins", parametersIns);
  448. DISCOVERY_OUT("parameters.outs", parametersOuts);
  449. DISCOVERY_OUT("parameters.total", parametersTotal);
  450. DISCOVERY_OUT("build", BINARY_NATIVE);
  451. DISCOVERY_OUT("end", "------------");
  452. }
  453. #else
  454. DISCOVERY_OUT("error", "LADSPA support not available");
  455. Q_UNUSED(libHandle);
  456. Q_UNUSED(init);
  457. #endif
  458. }
  459. void do_dssi_check(void* const libHandle, const bool init)
  460. {
  461. #ifdef WANT_DSSI
  462. const DSSI_Descriptor_Function descFn = (DSSI_Descriptor_Function)lib_symbol(libHandle, "dssi_descriptor");
  463. if (! descFn)
  464. {
  465. DISCOVERY_OUT("error", "Not a DSSI plugin");
  466. return;
  467. }
  468. unsigned long i = 0;
  469. const DSSI_Descriptor* descriptor;
  470. while ((descriptor = descFn(i++)))
  471. {
  472. const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin;
  473. if (! ldescriptor)
  474. {
  475. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no LADSPA interface");
  476. continue;
  477. }
  478. if (! ldescriptor->instantiate)
  479. {
  480. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no instantiate()");
  481. continue;
  482. }
  483. if (! ldescriptor->cleanup)
  484. {
  485. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no cleanup()");
  486. continue;
  487. }
  488. if (! (ldescriptor->run || descriptor->run_synth || descriptor->run_multiple_synths))
  489. {
  490. DISCOVERY_OUT("error", "Plugin '" << ldescriptor->Name << "' has no run(), run_synth() or run_multiple_synths()");
  491. continue;
  492. }
  493. if (! LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  494. {
  495. DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable");
  496. }
  497. int hints = 0;
  498. int audioIns = 0;
  499. int audioOuts = 0;
  500. int audioTotal = 0;
  501. int midiIns = 0;
  502. int midiTotal = 0;
  503. int parametersIns = 0;
  504. int parametersOuts = 0;
  505. int parametersTotal = 0;
  506. int programsTotal = 0;
  507. if (LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties))
  508. hints |= PLUGIN_IS_RTSAFE;
  509. for (unsigned long j=0; j < ldescriptor->PortCount; j++)
  510. {
  511. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  512. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  513. {
  514. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  515. audioIns += 1;
  516. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
  517. audioOuts += 1;
  518. audioTotal += 1;
  519. }
  520. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  521. {
  522. if (LADSPA_IS_PORT_INPUT(portDescriptor))
  523. parametersIns += 1;
  524. else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && std::strcmp(ldescriptor->PortNames[j], "latency") && std::strcmp(ldescriptor->PortNames[j], "_latency"))
  525. parametersOuts += 1;
  526. parametersTotal += 1;
  527. }
  528. }
  529. if (descriptor->run_synth || descriptor->run_multiple_synths)
  530. midiIns = midiTotal = 1;
  531. if (midiIns > 0 && audioIns == 0 && audioOuts > 0)
  532. hints |= PLUGIN_IS_SYNTH;
  533. if (init)
  534. {
  535. // -----------------------------------------------------------------------
  536. // start crash-free plugin test
  537. const LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, sampleRate);
  538. if (! handle)
  539. {
  540. DISCOVERY_OUT("error", "Failed to init DSSI plugin");
  541. continue;
  542. }
  543. if (descriptor->get_program && descriptor->select_program)
  544. {
  545. while (descriptor->get_program(handle, programsTotal++))
  546. continue;
  547. }
  548. LADSPA_Data bufferAudio[bufferSize][audioTotal];
  549. LADSPA_Data bufferParams[parametersTotal];
  550. LADSPA_Data min, max, def;
  551. for (unsigned long j=0, iA=0, iC=0; j < ldescriptor->PortCount; j++)
  552. {
  553. const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
  554. const LADSPA_PortRangeHint portRangeHints = ldescriptor->PortRangeHints[j];
  555. const char* const portName = ldescriptor->PortNames[j];
  556. if (LADSPA_IS_PORT_AUDIO(portDescriptor))
  557. {
  558. carla_zeroFloat(bufferAudio[iA], bufferSize);
  559. ldescriptor->connect_port(handle, j, bufferAudio[iA++]);
  560. }
  561. else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
  562. {
  563. // min value
  564. if (LADSPA_IS_HINT_BOUNDED_BELOW(portRangeHints.HintDescriptor))
  565. min = portRangeHints.LowerBound;
  566. else
  567. min = 0.0f;
  568. // max value
  569. if (LADSPA_IS_HINT_BOUNDED_ABOVE(portRangeHints.HintDescriptor))
  570. max = portRangeHints.UpperBound;
  571. else
  572. max = 1.0f;
  573. if (min > max)
  574. {
  575. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: min > max");
  576. max = min + 0.1f;
  577. }
  578. else if (max - min == 0.0f)
  579. {
  580. DISCOVERY_OUT("warning", "Parameter '" << portName << "' is broken: max - min == 0");
  581. max = min + 0.1f;
  582. }
  583. // default value
  584. def = get_default_ladspa_port_value(portRangeHints.HintDescriptor, min, max);
  585. if (LADSPA_IS_HINT_SAMPLE_RATE(portRangeHints.HintDescriptor))
  586. {
  587. min *= sampleRate;
  588. max *= sampleRate;
  589. def *= sampleRate;
  590. }
  591. if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && (std::strcmp(portName, "latency") == 0 || std::strcmp(portName, "_latency") == 0))
  592. {
  593. // latency parameter
  594. def = 0.0f;
  595. }
  596. else
  597. {
  598. if (def < min)
  599. def = min;
  600. else if (def > max)
  601. def = max;
  602. }
  603. bufferParams[iC] = def;
  604. ldescriptor->connect_port(handle, j, &bufferParams[iC++]);
  605. }
  606. }
  607. // select first midi-program if available
  608. if (programsTotal > 0)
  609. {
  610. if (const DSSI_Program_Descriptor* const pDesc = descriptor->get_program(handle, 0))
  611. descriptor->select_program(handle, pDesc->Bank, pDesc->Program);
  612. }
  613. if (ldescriptor->activate)
  614. ldescriptor->activate(handle);
  615. if (descriptor->run_synth || descriptor->run_multiple_synths)
  616. {
  617. snd_seq_event_t midiEvents[2];
  618. memset(midiEvents, 0, sizeof(snd_seq_event_t)*2); //FIXME
  619. const unsigned long midiEventCount = 2;
  620. midiEvents[0].type = SND_SEQ_EVENT_NOTEON;
  621. midiEvents[0].data.note.note = 64;
  622. midiEvents[0].data.note.velocity = 100;
  623. midiEvents[1].type = SND_SEQ_EVENT_NOTEOFF;
  624. midiEvents[1].data.note.note = 64;
  625. midiEvents[1].data.note.velocity = 0;
  626. midiEvents[1].time.tick = bufferSize/2;
  627. if (descriptor->run_multiple_synths && ! descriptor->run_synth)
  628. {
  629. LADSPA_Handle handlePtr[1] = { handle };
  630. snd_seq_event_t* midiEventsPtr[1] = { midiEvents };
  631. unsigned long midiEventCountPtr[1] = { midiEventCount };
  632. descriptor->run_multiple_synths(1, handlePtr, bufferSize, midiEventsPtr, midiEventCountPtr);
  633. }
  634. else
  635. descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount);
  636. }
  637. else
  638. ldescriptor->run(handle, bufferSize);
  639. if (ldescriptor->deactivate)
  640. ldescriptor->deactivate(handle);
  641. ldescriptor->cleanup(handle);
  642. // end crash-free plugin test
  643. // -----------------------------------------------------------------------
  644. }
  645. DISCOVERY_OUT("init", "-----------");
  646. DISCOVERY_OUT("name", ldescriptor->Name);
  647. DISCOVERY_OUT("label", ldescriptor->Label);
  648. DISCOVERY_OUT("maker", ldescriptor->Maker);
  649. DISCOVERY_OUT("copyright", ldescriptor->Copyright);
  650. DISCOVERY_OUT("unique_id", ldescriptor->UniqueID);
  651. DISCOVERY_OUT("hints", hints);
  652. DISCOVERY_OUT("audio.ins", audioIns);
  653. DISCOVERY_OUT("audio.outs", audioOuts);
  654. DISCOVERY_OUT("audio.total", audioTotal);
  655. DISCOVERY_OUT("midi.ins", midiIns);
  656. DISCOVERY_OUT("midi.total", midiTotal);
  657. DISCOVERY_OUT("parameters.ins", parametersIns);
  658. DISCOVERY_OUT("parameters.outs", parametersOuts);
  659. DISCOVERY_OUT("parameters.total", parametersTotal);
  660. DISCOVERY_OUT("programs.total", programsTotal);
  661. DISCOVERY_OUT("build", BINARY_NATIVE);
  662. DISCOVERY_OUT("end", "------------");
  663. }
  664. #else
  665. DISCOVERY_OUT("error", "DSSI support not available");
  666. Q_UNUSED(libHandle);
  667. Q_UNUSED(init);
  668. #endif
  669. }
  670. void do_lv2_check(const char* const bundle, const bool init)
  671. {
  672. #ifdef WANT_LV2
  673. // Convert bundle filename to URI
  674. QString qBundle(QUrl::fromLocalFile(bundle).toString());
  675. if (! qBundle.endsWith(QDir::separator()))
  676. qBundle += QDir::separator();
  677. // Load bundle
  678. Lilv::Node lilvBundle(lv2World.new_uri(qBundle.toUtf8().constData()));
  679. lv2World.load_bundle(lilvBundle);
  680. // Load plugins in this bundle
  681. const Lilv::Plugins lilvPlugins = lv2World.get_all_plugins();
  682. // Get all plugin URIs in this bundle
  683. QStringList URIs;
  684. LILV_FOREACH(plugins, i, lilvPlugins)
  685. {
  686. Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, i));
  687. if (const char* const uri = lilvPlugin.get_uri().as_string())
  688. URIs.append(QString(uri));
  689. }
  690. if (URIs.count() == 0)
  691. {
  692. DISCOVERY_OUT("warning", "LV2 Bundle doesn't provide any plugins");
  693. return;
  694. }
  695. // Get & check every plugin-instance
  696. for (int i=0; i < URIs.count(); i++)
  697. {
  698. const LV2_RDF_Descriptor* const rdfDescriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData());
  699. CARLA_ASSERT(rdfDescriptor && rdfDescriptor->URI);
  700. if (! (rdfDescriptor && rdfDescriptor->URI))
  701. {
  702. DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URIs.at(i).toUtf8().constData() << "'");
  703. continue;
  704. }
  705. if (init)
  706. {
  707. // test if DLL is loadable, twice
  708. bool isLoadable = true;
  709. for (int j=0; j < 2; j++)
  710. {
  711. void* const libHandle = lib_open(rdfDescriptor->Binary);
  712. if (! libHandle)
  713. {
  714. isLoadable = false;
  715. print_lib_error(rdfDescriptor->Binary);
  716. delete rdfDescriptor;
  717. break;
  718. }
  719. lib_close(libHandle);
  720. }
  721. if (! isLoadable)
  722. continue;
  723. }
  724. // test if we support all required ports and features
  725. {
  726. bool supported = true;
  727. for (uint32_t j=0; j < rdfDescriptor->PortCount && supported; j++)
  728. {
  729. const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j];
  730. if (is_lv2_port_supported(rdfPort->Types))
  731. {
  732. pass();
  733. }
  734. else if (! LV2_IS_PORT_OPTIONAL(rdfPort->Properties))
  735. {
  736. DISCOVERY_OUT("error", "Plugin '" << rdfDescriptor->URI << "' requires a non-supported port type (portName: '" << rdfPort->Name << "')");
  737. supported = false;
  738. break;
  739. }
  740. }
  741. for (uint32_t j=0; j < rdfDescriptor->FeatureCount && supported; j++)
  742. {
  743. const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j];
  744. if (is_lv2_feature_supported(rdfFeature->URI))
  745. {
  746. pass();
  747. }
  748. else if (LV2_IS_FEATURE_REQUIRED(rdfFeature->Type))
  749. {
  750. DISCOVERY_OUT("error", "Plugin '" << rdfDescriptor->URI << "' requires a non-supported feature '" << rdfFeature->URI << "'");
  751. supported = false;
  752. break;
  753. }
  754. }
  755. if (! supported)
  756. {
  757. delete rdfDescriptor;
  758. continue;
  759. }
  760. }
  761. int hints = 0;
  762. int audioIns = 0;
  763. int audioOuts = 0;
  764. int audioTotal = 0;
  765. int midiIns = 0;
  766. int midiOuts = 0;
  767. int midiTotal = 0;
  768. int parametersIns = 0;
  769. int parametersOuts = 0;
  770. int parametersTotal = 0;
  771. int programsTotal = rdfDescriptor->PresetCount;
  772. for (uint32_t j=0; j < rdfDescriptor->FeatureCount; j++)
  773. {
  774. const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j];
  775. if (std::strcmp(rdfFeature->URI, LV2_CORE__hardRTCapable) == 0)
  776. hints |= PLUGIN_IS_RTSAFE;
  777. }
  778. for (uint32_t j=0; j < rdfDescriptor->PortCount; j++)
  779. {
  780. const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j];
  781. if (LV2_IS_PORT_AUDIO(rdfPort->Types))
  782. {
  783. if (LV2_IS_PORT_INPUT(rdfPort->Types))
  784. audioIns += 1;
  785. else if (LV2_IS_PORT_OUTPUT(rdfPort->Types))
  786. audioOuts += 1;
  787. audioTotal += 1;
  788. }
  789. else if (LV2_IS_PORT_CONTROL(rdfPort->Types))
  790. {
  791. if (LV2_IS_PORT_DESIGNATION_LATENCY(rdfPort->Designation))
  792. {
  793. pass();
  794. }
  795. else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(rdfPort->Designation))
  796. {
  797. pass();
  798. }
  799. else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(rdfPort->Designation))
  800. {
  801. pass();
  802. }
  803. else if (LV2_IS_PORT_DESIGNATION_TIME(rdfPort->Designation))
  804. {
  805. pass();
  806. }
  807. else
  808. {
  809. if (LV2_IS_PORT_INPUT(rdfPort->Types))
  810. parametersIns += 1;
  811. else if (LV2_IS_PORT_OUTPUT(rdfPort->Types))
  812. parametersOuts += 1;
  813. parametersTotal += 1;
  814. }
  815. }
  816. else if (LV2_PORT_SUPPORTS_MIDI_EVENT(rdfPort->Types))
  817. {
  818. if (LV2_IS_PORT_INPUT(rdfPort->Types))
  819. midiIns += 1;
  820. else if (LV2_IS_PORT_OUTPUT(rdfPort->Types))
  821. midiOuts += 1;
  822. midiTotal += 1;
  823. }
  824. }
  825. if (rdfDescriptor->Type[1] & LV2_PLUGIN_INSTRUMENT)
  826. hints |= PLUGIN_IS_SYNTH;
  827. if (rdfDescriptor->UICount > 0)
  828. hints |= PLUGIN_HAS_GUI;
  829. DISCOVERY_OUT("init", "-----------");
  830. DISCOVERY_OUT("label", rdfDescriptor->URI);
  831. if (rdfDescriptor->Name)
  832. DISCOVERY_OUT("name", rdfDescriptor->Name);
  833. if (rdfDescriptor->Author)
  834. DISCOVERY_OUT("maker", rdfDescriptor->Author);
  835. if (rdfDescriptor->License)
  836. DISCOVERY_OUT("copyright", rdfDescriptor->License);
  837. DISCOVERY_OUT("unique_id", rdfDescriptor->UniqueID);
  838. DISCOVERY_OUT("hints", hints);
  839. DISCOVERY_OUT("audio.ins", audioIns);
  840. DISCOVERY_OUT("audio.outs", audioOuts);
  841. DISCOVERY_OUT("audio.total", audioTotal);
  842. DISCOVERY_OUT("midi.ins", midiIns);
  843. DISCOVERY_OUT("midi.outs", midiOuts);
  844. DISCOVERY_OUT("midi.total", midiTotal);
  845. DISCOVERY_OUT("parameters.ins", parametersIns);
  846. DISCOVERY_OUT("parameters.outs", parametersOuts);
  847. DISCOVERY_OUT("parameters.total", parametersTotal);
  848. DISCOVERY_OUT("programs.total", programsTotal);
  849. DISCOVERY_OUT("build", BINARY_NATIVE);
  850. DISCOVERY_OUT("end", "------------");
  851. delete rdfDescriptor;
  852. }
  853. #else
  854. DISCOVERY_OUT("error", "LV2 support not available");
  855. Q_UNUSED(bundle);
  856. Q_UNUSED(init);
  857. #endif
  858. }
  859. void do_vst_check(void* const libHandle, const bool init)
  860. {
  861. #ifdef WANT_VST
  862. VST_Function vstFn = (VST_Function)lib_symbol(libHandle, "VSTPluginMain");
  863. if (! vstFn)
  864. {
  865. vstFn = (VST_Function)lib_symbol(libHandle, "main");
  866. if (! vstFn)
  867. {
  868. DISCOVERY_OUT("error", "Not a VST plugin");
  869. return;
  870. }
  871. }
  872. AEffect* const effect = vstFn(vstHostCallback);
  873. if (! (effect && effect->magic == kEffectMagic))
  874. {
  875. DISCOVERY_OUT("error", "Failed to init VST plugin, or VST magic failed");
  876. return;
  877. }
  878. char strBuf[STR_MAX] = { 0 };
  879. CarlaString cName;
  880. CarlaString cProduct;
  881. CarlaString cVendor;
  882. effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
  883. intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f);
  884. if (vstCategory == kPlugCategShell && effect->uniqueID == 0)
  885. {
  886. if ((vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0)
  887. cName = strBuf;
  888. }
  889. else
  890. {
  891. vstCurrentUniqueId = effect->uniqueID;
  892. if (effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f) == 1)
  893. cName = strBuf;
  894. }
  895. memset(strBuf, 0, sizeof(char)*STR_MAX); //FIXME
  896. if (effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f) == 1)
  897. cVendor = strBuf;
  898. // FIXME: Waves crash during processing
  899. if (cVendor == "Waves")
  900. memset((void*)&init, 0, sizeof(bool)); //FIXME
  901. if (vstCurrentUniqueId == 0)
  902. {
  903. DISCOVERY_OUT("error", "Plugin doesn't have an Unique ID");
  904. return;
  905. }
  906. while (vstCurrentUniqueId != 0)
  907. {
  908. memset(strBuf, 0, sizeof(char)*STR_MAX); //FIXME
  909. if (effect->dispatcher(effect, effGetProductString, 0, 0, strBuf, 0.0f) == 1)
  910. cProduct = strBuf;
  911. else
  912. cProduct.clear();
  913. vstWantsMidi = false;
  914. int hints = 0;
  915. int audioIns = effect->numInputs;
  916. int audioOuts = effect->numOutputs;
  917. int audioTotal = audioIns + audioOuts;
  918. int midiIns = 0;
  919. int midiOuts = 0;
  920. int midiTotal = 0;
  921. int parametersIns = effect->numParams;
  922. int parametersTotal = parametersIns;
  923. int programsTotal = effect->numPrograms;
  924. if (effect->flags & effFlagsHasEditor)
  925. hints |= PLUGIN_HAS_GUI;
  926. if (effect->flags & effFlagsIsSynth)
  927. hints |= PLUGIN_IS_SYNTH;
  928. if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || (effect->flags & effFlagsIsSynth) > 0)
  929. midiIns = 1;
  930. if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent"))
  931. midiOuts = 1;
  932. midiTotal = midiIns + midiOuts;
  933. // -----------------------------------------------------------------------
  934. // start crash-free plugin test
  935. if (init)
  936. {
  937. #if ! VST_FORCE_DEPRECATED
  938. effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, bufferSize, nullptr, sampleRate);
  939. #endif
  940. effect->dispatcher(effect, effSetBlockSize, 0, bufferSize, nullptr, 0.0f);
  941. effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, sampleRate);
  942. effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
  943. effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
  944. effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
  945. // Plugin might call wantMidi() during resume
  946. if (midiIns == 0 && vstWantsMidi)
  947. {
  948. midiIns = 1;
  949. midiTotal = midiIns + midiOuts;
  950. }
  951. float* bufferAudioIn[audioIns];
  952. for (int j=0; j < audioIns; j++)
  953. {
  954. bufferAudioIn[j] = new float [bufferSize];
  955. carla_zeroFloat(bufferAudioIn[j], bufferSize);
  956. }
  957. float* bufferAudioOut[audioOuts];
  958. for (int j=0; j < audioOuts; j++)
  959. {
  960. bufferAudioOut[j] = new float [bufferSize];
  961. carla_zeroFloat(bufferAudioOut[j], bufferSize);
  962. }
  963. struct VstEventsFixed {
  964. int32_t numEvents;
  965. intptr_t reserved;
  966. VstEvent* data[2];
  967. };
  968. VstEventsFixed events;
  969. VstMidiEvent midiEvents[2];
  970. memset(&events, 0, sizeof(VstEventsFixed)); //FIXME
  971. memset(midiEvents, 0, sizeof(VstMidiEvent)*2); //FIXME
  972. midiEvents[0].type = kVstMidiType;
  973. midiEvents[0].byteSize = sizeof(VstMidiEvent);
  974. midiEvents[0].midiData[0] = MIDI_STATUS_NOTE_ON;
  975. midiEvents[0].midiData[1] = 64;
  976. midiEvents[0].midiData[2] = 100;
  977. midiEvents[1].type = kVstMidiType;
  978. midiEvents[1].byteSize = sizeof(VstMidiEvent);
  979. midiEvents[1].midiData[0] = MIDI_STATUS_NOTE_OFF;
  980. midiEvents[1].midiData[1] = 64;
  981. midiEvents[1].deltaFrames = bufferSize/2;
  982. events.numEvents = 2;
  983. events.data[0] = (VstEvent*)&midiEvents[0];
  984. events.data[1] = (VstEvent*)&midiEvents[1];
  985. // processing
  986. {
  987. vstIsProcessing = true;
  988. if (midiIns > 0)
  989. effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);
  990. #if ! VST_FORCE_DEPRECATED
  991. if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing && effect->processReplacing != effect->process)
  992. effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
  993. else if (effect->process)
  994. effect->process(effect, bufferAudioIn, bufferAudioOut, bufferSize);
  995. else
  996. DISCOVERY_OUT("error", "Plugin doesn't have a process function");
  997. #else
  998. CARLA_ASSERT(effect->flags & effFlagsCanReplacing);
  999. if (effect->flags & effFlagsCanReplacing)
  1000. {
  1001. if (effect->processReplacing)
  1002. effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
  1003. else
  1004. DISCOVERY_OUT("error", "Plugin doesn't have a process function");
  1005. }
  1006. else
  1007. DISCOVERY_OUT("error", "Plugin doesn't have can't do process replacing");
  1008. #endif
  1009. vstIsProcessing = false;
  1010. }
  1011. effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
  1012. effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
  1013. for (int j=0; j < audioIns; j++)
  1014. delete[] bufferAudioIn[j];
  1015. for (int j=0; j < audioOuts; j++)
  1016. delete[] bufferAudioOut[j];
  1017. }
  1018. // end crash-free plugin test
  1019. // -----------------------------------------------------------------------
  1020. DISCOVERY_OUT("init", "-----------");
  1021. DISCOVERY_OUT("name", (const char*)cName);
  1022. DISCOVERY_OUT("label", (const char*)cProduct);
  1023. DISCOVERY_OUT("maker", (const char*)cVendor);
  1024. DISCOVERY_OUT("copyright", (const char*)cVendor);
  1025. DISCOVERY_OUT("unique_id", vstCurrentUniqueId);
  1026. DISCOVERY_OUT("hints", hints);
  1027. DISCOVERY_OUT("audio.ins", audioIns);
  1028. DISCOVERY_OUT("audio.outs", audioOuts);
  1029. DISCOVERY_OUT("audio.total", audioTotal);
  1030. DISCOVERY_OUT("midi.ins", midiIns);
  1031. DISCOVERY_OUT("midi.outs", midiOuts);
  1032. DISCOVERY_OUT("midi.total", midiTotal);
  1033. DISCOVERY_OUT("parameters.ins", parametersIns);
  1034. DISCOVERY_OUT("parameters.total", parametersTotal);
  1035. DISCOVERY_OUT("programs.total", programsTotal);
  1036. DISCOVERY_OUT("build", BINARY_NATIVE);
  1037. DISCOVERY_OUT("end", "------------");
  1038. if (vstCategory != kPlugCategShell)
  1039. break;
  1040. // request next Unique ID
  1041. intptr_t nextUniqueId = vstCurrentUniqueId;
  1042. // FIXME: Waves sometimes return the same ID
  1043. while (nextUniqueId == vstCurrentUniqueId)
  1044. {
  1045. memset(strBuf, 0, sizeof(char)*STR_MAX); //FIXME
  1046. if ((vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f)) != 0)
  1047. cName = strBuf;
  1048. }
  1049. }
  1050. effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
  1051. #else
  1052. DISCOVERY_OUT("error", "VST support not available");
  1053. Q_UNUSED(libHandle);
  1054. Q_UNUSED(init);
  1055. #endif
  1056. }
  1057. void do_fluidsynth_check(const char* const filename, const bool init)
  1058. {
  1059. #ifdef WANT_FLUIDSYNTH
  1060. if (! fluid_is_soundfont(filename))
  1061. {
  1062. DISCOVERY_OUT("error", "Not a SF2 file");
  1063. return;
  1064. }
  1065. int programs = 0;
  1066. if (init)
  1067. {
  1068. fluid_settings_t* const f_settings = new_fluid_settings();
  1069. fluid_synth_t* const f_synth = new_fluid_synth(f_settings);
  1070. const int f_id = fluid_synth_sfload(f_synth, filename, 0);
  1071. if (f_id < 0)
  1072. {
  1073. DISCOVERY_OUT("error", "Failed to load SF2 file");
  1074. return;
  1075. }
  1076. fluid_sfont_t* f_sfont;
  1077. fluid_preset_t f_preset;
  1078. f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id);
  1079. f_sfont->iteration_start(f_sfont);
  1080. while (f_sfont->iteration_next(f_sfont, &f_preset))
  1081. programs += 1;
  1082. delete_fluid_synth(f_synth);
  1083. delete_fluid_settings(f_settings);
  1084. }
  1085. #if CARLA_OS_WIN
  1086. int sep = '\\';
  1087. #else
  1088. int sep = '/';
  1089. #endif
  1090. CarlaString name(std::strrchr(filename, sep)+1);
  1091. name.truncate(name.rfind('.'));
  1092. CarlaString label(name);
  1093. // 2 channels
  1094. DISCOVERY_OUT("init", "-----------");
  1095. DISCOVERY_OUT("name", (const char*)name);
  1096. DISCOVERY_OUT("label", (const char*)label);
  1097. DISCOVERY_OUT("maker", "");
  1098. DISCOVERY_OUT("copyright", "");
  1099. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1100. DISCOVERY_OUT("audio.outs", 2);
  1101. DISCOVERY_OUT("audio.total", 2);
  1102. DISCOVERY_OUT("midi.ins", 1);
  1103. DISCOVERY_OUT("midi.total", 1);
  1104. DISCOVERY_OUT("programs.total", programs);
  1105. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1106. DISCOVERY_OUT("parameters.outs", 1);
  1107. DISCOVERY_OUT("parameters.total", 14);
  1108. DISCOVERY_OUT("build", BINARY_NATIVE);
  1109. DISCOVERY_OUT("end", "------------");
  1110. // 16 channels
  1111. if (name.isNotEmpty())
  1112. name += " (16 outputs)";
  1113. DISCOVERY_OUT("init", "-----------");
  1114. DISCOVERY_OUT("name", "");
  1115. DISCOVERY_OUT("name", (const char*)name);
  1116. DISCOVERY_OUT("label", (const char*)label);
  1117. DISCOVERY_OUT("copyright", "");
  1118. DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
  1119. DISCOVERY_OUT("audio.outs", 32);
  1120. DISCOVERY_OUT("audio.total", 32);
  1121. DISCOVERY_OUT("midi.ins", 1);
  1122. DISCOVERY_OUT("midi.total", 1);
  1123. DISCOVERY_OUT("programs.total", programs);
  1124. DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
  1125. DISCOVERY_OUT("parameters.outs", 1);
  1126. DISCOVERY_OUT("parameters.total", 14);
  1127. DISCOVERY_OUT("build", BINARY_NATIVE);
  1128. DISCOVERY_OUT("end", "------------");
  1129. #else
  1130. DISCOVERY_OUT("error", "SF2 support not available");
  1131. Q_UNUSED(filename);
  1132. Q_UNUSED(init);
  1133. #endif
  1134. }
  1135. void do_linuxsampler_check(const char* const filename, const char* const stype, const bool init)
  1136. {
  1137. #ifdef WANT_LINUXSAMPLER
  1138. const QFileInfo file(filename);
  1139. if (! file.exists())
  1140. {
  1141. DISCOVERY_OUT("error", "Requested file does not exist");
  1142. return;
  1143. }
  1144. if (! file.isFile())
  1145. {
  1146. DISCOVERY_OUT("error", "Requested file is not valid");
  1147. return;
  1148. }
  1149. if (! file.isReadable())
  1150. {
  1151. DISCOVERY_OUT("error", "Requested file is not readable");
  1152. return;
  1153. }
  1154. if (init)
  1155. const LinuxSamplerScopedEngine engine(filename, stype);
  1156. else
  1157. LinuxSamplerScopedEngine::outputInfo(nullptr, 0, file.baseName().toUtf8().constData());
  1158. #else
  1159. DISCOVERY_OUT("error", stype << " support not available");
  1160. Q_UNUSED(filename);
  1161. Q_UNUSED(init);
  1162. #endif
  1163. }
  1164. // ------------------------------ main entry point ------------------------------
  1165. int main(int argc, char* argv[])
  1166. {
  1167. if (argc == 2 && std::strcmp(argv[1], "-formats") == 0)
  1168. {
  1169. printf("Available plugin formats:\n");
  1170. printf("LADSPA: ");
  1171. #ifdef WANT_LADSPA
  1172. printf("yes\n");
  1173. #else
  1174. printf("no\n");
  1175. #endif
  1176. printf("DSSI: ");
  1177. #ifdef WANT_DSSI
  1178. printf("yes\n");
  1179. #else
  1180. printf("no\n");
  1181. #endif
  1182. printf("LV2: ");
  1183. #ifdef WANT_LV2
  1184. printf("yes\n");
  1185. #else
  1186. printf("no\n");
  1187. #endif
  1188. printf("VST: ");
  1189. #ifdef WANT_VST
  1190. printf("yes\n");
  1191. #else
  1192. printf("no\n");
  1193. #endif
  1194. printf("\n");
  1195. printf("Available sampler formats:\n");
  1196. printf("GIG (LinuxSampler): ");
  1197. #ifdef WANT_LINUXSAMPLER
  1198. printf("yes\n");
  1199. #else
  1200. printf("no\n");
  1201. #endif
  1202. printf("SF2 (FluidSynth): ");
  1203. #ifdef WANT_FLUIDSYNTH
  1204. printf("yes\n");
  1205. #else
  1206. printf("no\n");
  1207. #endif
  1208. printf("SFZ (LinuxSampler): ");
  1209. #ifdef WANT_LINUXSAMPLER
  1210. printf("yes\n");
  1211. #else
  1212. printf("no\n");
  1213. #endif
  1214. return 0;
  1215. }
  1216. if (argc != 3)
  1217. {
  1218. qWarning("usage: %s <type> </path/to/plugin>", argv[0]);
  1219. return 1;
  1220. }
  1221. const char* const stype = argv[1];
  1222. const char* const filename = argv[2];
  1223. bool openLib;
  1224. PluginType type;
  1225. void* handle = nullptr;
  1226. if (std::strcmp(stype, "LADSPA") == 0)
  1227. {
  1228. openLib = true;
  1229. type = PLUGIN_LADSPA;
  1230. }
  1231. else if (std::strcmp(stype, "DSSI") == 0)
  1232. {
  1233. openLib = true;
  1234. type = PLUGIN_DSSI;
  1235. }
  1236. else if (std::strcmp(stype, "LV2") == 0)
  1237. {
  1238. openLib = false;
  1239. type = PLUGIN_LV2;
  1240. }
  1241. else if (std::strcmp(stype, "VST") == 0)
  1242. {
  1243. openLib = true;
  1244. type = PLUGIN_VST;
  1245. }
  1246. else if (std::strcmp(stype, "GIG") == 0)
  1247. {
  1248. openLib = false;
  1249. type = PLUGIN_GIG;
  1250. }
  1251. else if (std::strcmp(stype, "SF2") == 0)
  1252. {
  1253. openLib = false;
  1254. type = PLUGIN_SF2;
  1255. }
  1256. else if (std::strcmp(stype, "SFZ") == 0)
  1257. {
  1258. openLib = false;
  1259. type = PLUGIN_SFZ;
  1260. }
  1261. else
  1262. {
  1263. DISCOVERY_OUT("error", "Invalid plugin type");
  1264. return 1;
  1265. }
  1266. if (openLib)
  1267. {
  1268. handle = lib_open(filename);
  1269. if (! handle)
  1270. {
  1271. print_lib_error(filename);
  1272. return 1;
  1273. }
  1274. }
  1275. bool doInit = ! QString(filename).endsWith("dssi-vst.so", Qt::CaseInsensitive);
  1276. if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"))
  1277. doInit = false;
  1278. if (doInit && handle)
  1279. {
  1280. // test fast loading & unloading DLL without initializing the plugin(s)
  1281. if (! lib_close(handle))
  1282. {
  1283. print_lib_error(filename);
  1284. return 1;
  1285. }
  1286. handle = lib_open(filename);
  1287. if (! handle)
  1288. {
  1289. print_lib_error(filename);
  1290. return 1;
  1291. }
  1292. }
  1293. switch (type)
  1294. {
  1295. case PLUGIN_LADSPA:
  1296. do_ladspa_check(handle, doInit);
  1297. break;
  1298. case PLUGIN_DSSI:
  1299. do_dssi_check(handle, doInit);
  1300. break;
  1301. case PLUGIN_LV2:
  1302. do_lv2_check(filename, doInit);
  1303. break;
  1304. case PLUGIN_VST:
  1305. do_vst_check(handle, doInit);
  1306. break;
  1307. case PLUGIN_GIG:
  1308. do_linuxsampler_check(filename, "gig", doInit);
  1309. break;
  1310. case PLUGIN_SF2:
  1311. do_fluidsynth_check(filename, doInit);
  1312. break;
  1313. case PLUGIN_SFZ:
  1314. do_linuxsampler_check(filename, "sfz", doInit);
  1315. break;
  1316. default:
  1317. break;
  1318. }
  1319. if (openLib && handle)
  1320. lib_close(handle);
  1321. return 0;
  1322. }