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.

1681 lines
51KB

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