Collection of tools useful for audio production
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.

687 lines
21KB

  1. /*
  2. * DISTHRO Plugin Toolkit (DPT)
  3. * Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 license see the GPL.txt file
  16. */
  17. #if defined(DISTRHO_PLUGIN_TARGET_LADSPA) || defined(DISTRHO_PLUGIN_TARGET_DSSI)
  18. #include "DistrhoPluginInternal.h"
  19. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  20. # include "dssi/dssi.h"
  21. #else
  22. # include "ladspa/ladspa.h"
  23. # if DISTRHO_PLUGIN_IS_SYNTH
  24. # error Cannot build synth plugin with LADSPA
  25. # endif
  26. # if DISTRHO_PLUGIN_WANT_STATE
  27. # warning LADSPA cannot handle states
  28. # endif
  29. #endif
  30. #include <vector>
  31. typedef LADSPA_Data* LADSPA_DataPtr;
  32. typedef std::vector<LADSPA_Data> LADSPA_DataVector;
  33. typedef std::vector<LADSPA_DataPtr> LADSPA_DataPtrVector;
  34. // -------------------------------------------------
  35. START_NAMESPACE_DISTRHO
  36. class PluginLadspaDssi
  37. {
  38. public:
  39. PluginLadspaDssi()
  40. : lastBufferSize(d_lastBufferSize),
  41. lastSampleRate(d_lastSampleRate)
  42. {
  43. for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; i++)
  44. portAudioIns[i] = nullptr;
  45. for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; i++)
  46. portAudioOuts[i] = nullptr;
  47. for (uint32_t i=0; i < plugin.parameterCount(); i++)
  48. {
  49. portControls.push_back(nullptr);
  50. lastControlValues.push_back(plugin.parameterValue(i));
  51. }
  52. #if DISTRHO_PLUGIN_WANT_LATENCY
  53. portLatency = nullptr;
  54. #endif
  55. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  56. portSampleRate = nullptr;
  57. #endif
  58. }
  59. ~PluginLadspaDssi()
  60. {
  61. portControls.clear();
  62. lastControlValues.clear();
  63. }
  64. void ladspa_activate()
  65. {
  66. plugin.activate();
  67. updateParameterOutputs();
  68. }
  69. void ladspa_deactivate()
  70. {
  71. plugin.deactivate();
  72. }
  73. void ladspa_connect_port(unsigned long port, LADSPA_DataPtr dataLocation)
  74. {
  75. unsigned long i, index = 0;
  76. for (i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; i++)
  77. {
  78. if (port == index++)
  79. {
  80. portAudioIns[i] = dataLocation;
  81. return;
  82. }
  83. }
  84. for (i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; i++)
  85. {
  86. if (port == index++)
  87. {
  88. portAudioOuts[i] = dataLocation;
  89. return;
  90. }
  91. }
  92. #if DISTRHO_PLUGIN_WANT_LATENCY
  93. if (port == index++)
  94. {
  95. portLatency = dataLocation;
  96. return;
  97. }
  98. #endif
  99. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  100. if (port == index++)
  101. {
  102. portSampleRate = dataLocation;
  103. return;
  104. }
  105. #endif
  106. for (i=0; i < plugin.parameterCount(); i++)
  107. {
  108. if (port == index++)
  109. {
  110. portControls[i] = dataLocation;
  111. return;
  112. }
  113. }
  114. }
  115. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  116. # if DISTRHO_PLUGIN_WANT_STATE
  117. char* dssi_configure(const char* key, const char* value)
  118. {
  119. if (strncmp(key, DSSI_RESERVED_CONFIGURE_PREFIX, strlen(DSSI_RESERVED_CONFIGURE_PREFIX) == 0))
  120. return nullptr;
  121. if (strncmp(key, DSSI_GLOBAL_CONFIGURE_PREFIX, strlen(DSSI_GLOBAL_CONFIGURE_PREFIX) == 0))
  122. return nullptr;
  123. plugin.setState(key, value);
  124. return nullptr;
  125. }
  126. # endif
  127. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  128. const DSSI_Program_Descriptor* dssi_get_program(unsigned long index)
  129. {
  130. if (index >= plugin.programCount())
  131. return nullptr;
  132. static DSSI_Program_Descriptor desc;
  133. desc.Bank = index / 128;
  134. desc.Program = index % 128;
  135. desc.Name = plugin.programName(index);
  136. return &desc;
  137. }
  138. void dssi_select_program(unsigned long bank, unsigned long program)
  139. {
  140. const unsigned long realProgram = bank * 128 + program;
  141. if (realProgram >= plugin.programCount())
  142. return;
  143. plugin.setProgram(realProgram);
  144. // Update parameters
  145. for (uint32_t i=0; i < plugin.parameterCount(); i++)
  146. {
  147. if (! plugin.parameterIsOutput(i))
  148. {
  149. lastControlValues[i] = plugin.parameterValue(i);
  150. if (portControls[i])
  151. *portControls[i] = lastControlValues[i];
  152. }
  153. }
  154. }
  155. # endif
  156. void ladspa_run(unsigned long bufferSize)
  157. {
  158. dssi_run_synth(bufferSize, nullptr, 0);
  159. }
  160. void dssi_run_synth(unsigned long bufferSize, snd_seq_event_t* events, unsigned long eventCount)
  161. #else
  162. void ladspa_run(unsigned long bufferSize)
  163. #endif
  164. {
  165. // Check for updated bufferSize
  166. if (bufferSize != lastBufferSize)
  167. {
  168. lastBufferSize = bufferSize;
  169. d_lastBufferSize = bufferSize;
  170. plugin.setBufferSize(bufferSize, true);
  171. }
  172. // Check for updated parameters
  173. float curValue;
  174. for (uint32_t i=0; i < plugin.parameterCount(); i++)
  175. {
  176. curValue = *portControls[i];
  177. if (lastControlValues[i] != curValue && ! plugin.parameterIsOutput(i))
  178. {
  179. lastControlValues[i] = curValue;
  180. plugin.setParameterValue(i, curValue);
  181. }
  182. }
  183. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  184. # if DISTRHO_PLUGIN_IS_SYNTH
  185. // Get MIDI Events
  186. uint32_t midiEventCount = 0;
  187. for (uint32_t i=0, j=0; i < eventCount && midiEventCount < MAX_MIDI_EVENTS; i++)
  188. {
  189. snd_seq_event_t* event = &events[i];
  190. memset(&midiEvents[midiEventCount], 0, sizeof(MidiEvent));
  191. if (event->type == SND_SEQ_EVENT_NOTEON)
  192. {
  193. j = midiEventCount++;
  194. midiEvents[j].frame = event->time.tick;
  195. midiEvents[j].buffer[0] = 0x90 + event->data.note.channel;
  196. midiEvents[j].buffer[1] = event->data.note.note;
  197. midiEvents[j].buffer[2] = event->data.note.velocity;
  198. }
  199. else if (event->type == SND_SEQ_EVENT_NOTEOFF)
  200. {
  201. j = midiEventCount++;
  202. midiEvents[j].frame = event->time.tick;
  203. midiEvents[j].buffer[0] = 0x80 + event->data.note.channel;
  204. midiEvents[j].buffer[1] = event->data.note.note;
  205. }
  206. else if (event->type == SND_SEQ_EVENT_KEYPRESS)
  207. {
  208. j = midiEventCount++;
  209. midiEvents[j].frame = event->time.tick;
  210. midiEvents[j].buffer[0] = 0xA0 + event->data.note.channel;
  211. midiEvents[j].buffer[1] = event->data.note.note;
  212. midiEvents[j].buffer[2] = event->data.note.velocity;
  213. }
  214. else if (event->type == SND_SEQ_EVENT_CONTROLLER)
  215. {
  216. j = midiEventCount++;
  217. midiEvents[j].frame = event->time.tick;
  218. midiEvents[j].buffer[0] = 0xB0 + event->data.control.channel;
  219. midiEvents[j].buffer[1] = event->data.control.param;
  220. midiEvents[j].buffer[2] = event->data.control.value;
  221. }
  222. else if (event->type == SND_SEQ_EVENT_CHANPRESS)
  223. {
  224. j = midiEventCount++;
  225. midiEvents[j].frame = event->time.tick;
  226. midiEvents[j].buffer[0] = 0xD0 + event->data.control.channel;
  227. midiEvents[j].buffer[1] = event->data.control.value;
  228. }
  229. else if (event->type == SND_SEQ_EVENT_PITCHBEND)
  230. {
  231. // TODO
  232. //j = midiEventCount++;
  233. //midiEvents[j].frame = event->time.tick;
  234. //midiEvents[j].buffer[0] = 0xE0 + event->data.control.channel;
  235. //midiEvents[j].buffer[1] = 0;
  236. //midiEvents[j].buffer[2] = 0;
  237. }
  238. }
  239. # else
  240. // unused
  241. (void)events;
  242. (void)eventCount;
  243. # endif
  244. #endif
  245. // Run plugin for this cycle
  246. #if DISTRHO_PLUGIN_IS_SYNTH
  247. plugin.run(portAudioIns, portAudioOuts, bufferSize, midiEventCount, midiEvents);
  248. #else
  249. plugin.run(portAudioIns, portAudioOuts, bufferSize, 0, nullptr);
  250. #endif
  251. updateParameterOutputs();
  252. }
  253. private:
  254. PluginInternal plugin;
  255. // LADSPA ports
  256. LADSPA_DataPtr portAudioIns[DISTRHO_PLUGIN_NUM_INPUTS];
  257. LADSPA_DataPtr portAudioOuts[DISTRHO_PLUGIN_NUM_INPUTS];
  258. LADSPA_DataPtrVector portControls;
  259. #if DISTRHO_PLUGIN_WANT_LATENCY
  260. LADSPA_DataPtr portLatency;
  261. #endif
  262. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  263. LADSPA_DataPtr portSampleRate;
  264. #endif
  265. // Temporary data
  266. unsigned long lastBufferSize;
  267. const double lastSampleRate;
  268. LADSPA_DataVector lastControlValues;
  269. #if DISTRHO_PLUGIN_IS_SYNTH
  270. MidiEvent midiEvents[MAX_MIDI_EVENTS];
  271. #endif
  272. void updateParameterOutputs()
  273. {
  274. for (uint32_t i=0; i < plugin.parameterCount(); i++)
  275. {
  276. if (plugin.parameterIsOutput(i))
  277. {
  278. lastControlValues[i] = plugin.parameterValue(i);
  279. if (portControls[i])
  280. *portControls[i] = lastControlValues[i];
  281. }
  282. }
  283. #if DISTRHO_PLUGIN_WANT_LATENCY
  284. if (portLatency)
  285. *portLatency = plugin.latency();
  286. #endif
  287. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  288. if (portSampleRate)
  289. *portSampleRate = lastSampleRate;
  290. #endif
  291. }
  292. };
  293. // -------------------------------------------------
  294. static LADSPA_Handle ladspa_instantiate(const LADSPA_Descriptor*, unsigned long sampleRate)
  295. {
  296. if (d_lastBufferSize == 0)
  297. d_lastBufferSize = 2048;
  298. d_lastSampleRate = sampleRate;
  299. return new PluginLadspaDssi();
  300. }
  301. static void ladspa_connect_port(LADSPA_Handle instance, unsigned long port, LADSPA_Data* dataLocation)
  302. {
  303. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  304. assert(plugin);
  305. plugin->ladspa_connect_port(port, dataLocation);
  306. }
  307. static void ladspa_activate(LADSPA_Handle instance)
  308. {
  309. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  310. assert(plugin);
  311. plugin->ladspa_activate();
  312. }
  313. static void ladspa_run(LADSPA_Handle instance, unsigned long sampleCount)
  314. {
  315. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  316. assert(plugin);
  317. plugin->ladspa_run(sampleCount);
  318. }
  319. static void ladspa_deactivate(LADSPA_Handle instance)
  320. {
  321. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  322. assert(plugin);
  323. plugin->ladspa_deactivate();
  324. }
  325. static void ladspa_cleanup(LADSPA_Handle instance)
  326. {
  327. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  328. assert(plugin);
  329. delete plugin;
  330. }
  331. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  332. # if DISTRHO_PLUGIN_WANT_STATE
  333. static char* dssi_configure(LADSPA_Handle instance, const char* key, const char* value)
  334. {
  335. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  336. assert(plugin);
  337. return plugin->dssi_configure(key, value);
  338. }
  339. # endif
  340. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  341. static const DSSI_Program_Descriptor* dssi_get_program(LADSPA_Handle instance, unsigned long index)
  342. {
  343. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  344. assert(plugin);
  345. return plugin->dssi_get_program(index);
  346. }
  347. static void dssi_select_program(LADSPA_Handle instance, unsigned long bank, unsigned long program)
  348. {
  349. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  350. assert(plugin);
  351. plugin->dssi_select_program(bank, program);
  352. }
  353. # endif
  354. # if DISTRHO_PLUGIN_IS_SYNTH
  355. static void dssi_run_synth(LADSPA_Handle instance, unsigned long sampleCount, snd_seq_event_t* events, unsigned long eventCount)
  356. {
  357. PluginLadspaDssi* plugin = (PluginLadspaDssi*)instance;
  358. assert(plugin);
  359. plugin->dssi_run_synth(sampleCount, events, eventCount);
  360. }
  361. # endif
  362. #endif
  363. // -------------------------------------------------
  364. static LADSPA_Descriptor ldescriptor = {
  365. /* UniqueID */ 0,
  366. /* Label */ nullptr,
  367. /* Properties */ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
  368. /* Name */ nullptr,
  369. /* Maker */ nullptr,
  370. /* Copyright */ nullptr,
  371. /* PortCount */ 0,
  372. /* PortDescriptors */ nullptr,
  373. /* PortNames */ nullptr,
  374. /* PortRangeHints */ nullptr,
  375. /* ImplementationData */ nullptr,
  376. ladspa_instantiate,
  377. ladspa_connect_port,
  378. ladspa_activate,
  379. ladspa_run,
  380. /* run_adding */ nullptr,
  381. /* set_run_adding_gain */ nullptr,
  382. ladspa_deactivate,
  383. ladspa_cleanup
  384. };
  385. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  386. static DSSI_Descriptor descriptor = {
  387. 1,
  388. &ldescriptor,
  389. # if DISTRHO_PLUGIN_WANT_STATE
  390. dssi_configure,
  391. # else
  392. /* configure */ nullptr,
  393. # endif
  394. # if DISTRHO_PLUGIN_WANT_PROGRAMS
  395. dssi_get_program,
  396. dssi_select_program,
  397. # else
  398. /* get_program */ nullptr,
  399. /* select_program */ nullptr,
  400. # endif
  401. /* get_midi_controller_for_port */ nullptr,
  402. # if DISTRHO_PLUGIN_IS_SYNTH
  403. dssi_run_synth,
  404. # else
  405. /* run_synth */ nullptr,
  406. # endif
  407. /* run_synth_adding */ nullptr,
  408. /* run_multiple_synths */ nullptr,
  409. /* run_multiple_synths_adding */ nullptr,
  410. nullptr, nullptr
  411. };
  412. #endif
  413. // -------------------------------------------------
  414. class DescriptorInitializer
  415. {
  416. public:
  417. DescriptorInitializer()
  418. {
  419. // Create dummy plugin to get data from
  420. d_lastBufferSize = 512;
  421. d_lastSampleRate = 44100.0;
  422. PluginInternal plugin;
  423. d_lastBufferSize = 0;
  424. d_lastSampleRate = 0.0;
  425. // Get port count, init
  426. unsigned long i, port = 0;
  427. unsigned long portCount = DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS + plugin.parameterCount();
  428. #if DISTRHO_PLUGIN_WANT_LATENCY
  429. portCount += 1;
  430. #endif
  431. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  432. portCount += 1; // sample-rate
  433. #endif
  434. const char** portNames = new const char* [portCount];
  435. LADSPA_PortDescriptor* portDescriptors = new LADSPA_PortDescriptor [portCount];
  436. LADSPA_PortRangeHint* portRangeHints = new LADSPA_PortRangeHint [portCount];
  437. // Set ports
  438. for (i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; i++, port++)
  439. {
  440. char portName[24] = { 0 };
  441. sprintf(portName, "Audio Input %lu", i+1);
  442. portNames[port] = strdup(portName);
  443. portDescriptors[port] = LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT;
  444. portRangeHints[port].HintDescriptor = 0;
  445. portRangeHints[port].LowerBound = 0.0f;
  446. portRangeHints[port].UpperBound = 1.0f;
  447. }
  448. for (i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; i++, port++)
  449. {
  450. char portName[24] = { 0 };
  451. sprintf(portName, "Audio Output %lu", i+1);
  452. portNames[port] = strdup(portName);
  453. portDescriptors[port] = LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT;
  454. portRangeHints[port].HintDescriptor = 0;
  455. portRangeHints[port].LowerBound = 0.0f;
  456. portRangeHints[port].UpperBound = 1.0f;
  457. }
  458. #if DISTRHO_PLUGIN_WANT_LATENCY
  459. // Set latency port
  460. portNames[port] = strdup("_latency");
  461. portDescriptors[port] = LADSPA_PORT_CONTROL | LADSPA_PORT_OUTPUT;
  462. portRangeHints[port].HintDescriptor = LADSPA_HINT_SAMPLE_RATE;
  463. portRangeHints[port].LowerBound = 0.0f;
  464. portRangeHints[port].UpperBound = 1.0f;
  465. port++;
  466. #endif
  467. #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && DISTRHO_PLUGIN_HAS_UI
  468. // Set sample-rate port
  469. portNames[port] = strdup("_sample-rate");
  470. portDescriptors[port] = LADSPA_PORT_CONTROL | LADSPA_PORT_OUTPUT;
  471. portRangeHints[port].HintDescriptor = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
  472. portRangeHints[port].LowerBound = 0.0f;
  473. portRangeHints[port].UpperBound = 512000.0f;
  474. port++;
  475. #endif
  476. for (i=0; i < plugin.parameterCount(); i++, port++)
  477. {
  478. portNames[port] = strdup(plugin.parameterName(i));
  479. portDescriptors[port] = LADSPA_PORT_CONTROL;
  480. if (plugin.parameterIsOutput(i))
  481. portDescriptors[port] |= LADSPA_PORT_OUTPUT;
  482. else
  483. portDescriptors[port] |= LADSPA_PORT_INPUT;
  484. {
  485. const ParameterRanges* ranges = plugin.parameterRanges(i);
  486. const float defValue = ranges->def;
  487. portRangeHints[port].HintDescriptor = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE;
  488. portRangeHints[port].LowerBound = ranges->min;
  489. portRangeHints[port].UpperBound = ranges->max;
  490. if (defValue == 0.0f)
  491. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_0;
  492. else if (defValue == 1.0f)
  493. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_1;
  494. else if (defValue == 100.0f)
  495. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_100;
  496. else if (defValue == 440.0f)
  497. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_440;
  498. else if (ranges->min == defValue)
  499. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_MINIMUM;
  500. else if (ranges->max == defValue)
  501. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_MAXIMUM;
  502. else
  503. {
  504. const float middleValue = ranges->min/2 + ranges->max/2;
  505. const float middleLow = (ranges->min/2 + middleValue/2)/2 + middleValue/2;
  506. const float middleHigh = (ranges->max/2 + middleValue/2)/2 + middleValue/2;
  507. if (defValue < middleLow)
  508. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_LOW;
  509. else if (defValue > middleHigh)
  510. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_HIGH;
  511. else
  512. portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_MIDDLE;
  513. }
  514. }
  515. {
  516. uint32_t hints = plugin.parameterHints(i);
  517. if (hints & PARAMETER_IS_BOOLEAN)
  518. portRangeHints[port].HintDescriptor |= LADSPA_HINT_TOGGLED;
  519. if (hints & PARAMETER_IS_INTEGER)
  520. portRangeHints[port].HintDescriptor |= LADSPA_HINT_INTEGER;
  521. if (hints & PARAMETER_IS_LOGARITHMIC)
  522. portRangeHints[port].HintDescriptor |= LADSPA_HINT_LOGARITHMIC;
  523. }
  524. }
  525. // Set data
  526. ldescriptor.UniqueID = plugin.uniqueId();
  527. ldescriptor.Label = strdup(plugin.label());
  528. ldescriptor.Name = strdup(plugin.name());
  529. ldescriptor.Maker = strdup(plugin.maker());
  530. ldescriptor.Copyright = strdup(plugin.license());
  531. ldescriptor.PortCount = portCount;
  532. ldescriptor.PortNames = portNames;
  533. ldescriptor.PortDescriptors = portDescriptors;
  534. ldescriptor.PortRangeHints = portRangeHints;
  535. }
  536. ~DescriptorInitializer()
  537. {
  538. if (ldescriptor.Label)
  539. free((void*)ldescriptor.Label);
  540. if (ldescriptor.Name)
  541. free((void*)ldescriptor.Name);
  542. if (ldescriptor.Maker)
  543. free((void*)ldescriptor.Maker);
  544. if (ldescriptor.Copyright)
  545. free((void*)ldescriptor.Copyright);
  546. if (ldescriptor.PortDescriptors)
  547. delete[] ldescriptor.PortDescriptors;
  548. if (ldescriptor.PortRangeHints)
  549. delete[] ldescriptor.PortRangeHints;
  550. if (ldescriptor.PortNames)
  551. {
  552. for (unsigned long i=0; i < ldescriptor.PortCount; i++)
  553. {
  554. if (ldescriptor.PortNames[i])
  555. free((void*)ldescriptor.PortNames[i]);
  556. }
  557. delete[] ldescriptor.PortNames;
  558. }
  559. }
  560. };
  561. static DescriptorInitializer init;
  562. END_NAMESPACE_DISTRHO
  563. // -------------------------------------------------
  564. DISTRHO_PLUGIN_EXPORT
  565. const LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
  566. {
  567. USE_NAMESPACE_DISTRHO
  568. return (index == 0) ? &ldescriptor : nullptr;
  569. }
  570. #ifdef DISTRHO_PLUGIN_TARGET_DSSI
  571. DISTRHO_PLUGIN_EXPORT
  572. const DSSI_Descriptor* dssi_descriptor(unsigned long index)
  573. {
  574. USE_NAMESPACE_DISTRHO
  575. return (index == 0) ? &descriptor : nullptr;
  576. }
  577. #endif
  578. // -------------------------------------------------
  579. #endif // DISTRHO_PLUGIN_TARGET_LADSPA || DISTRHO_PLUGIN_TARGET_DSSI