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.

CarlaLv2Utils.hpp 51KB

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
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
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
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
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262
  1. /*
  2. * Carla LV2 utils
  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. #ifndef __CARLA_LV2_UTILS_HPP__
  18. #define __CARLA_LV2_UTILS_HPP__
  19. #include "CarlaJuceUtils.hpp"
  20. #include "lv2/lv2.h"
  21. #include "lv2/atom.h"
  22. #include "lv2/atom-forge.h"
  23. #include "lv2/atom-util.h"
  24. #include "lv2/buf-size.h"
  25. #include "lv2/data-access.h"
  26. // dynmanifest
  27. #include "lv2/event.h"
  28. #include "lv2/event-helpers.h"
  29. #include "lv2/instance-access.h"
  30. #include "lv2/log.h"
  31. // logger
  32. #include "lv2/midi.h"
  33. // morph
  34. #include "lv2/options.h"
  35. #include "lv2/parameters.h"
  36. #include "lv2/patch.h"
  37. #include "lv2/port-groups.h"
  38. #include "lv2/port-props.h"
  39. #include "lv2/presets.h"
  40. // resize-port
  41. #include "lv2/state.h"
  42. #include "lv2/time.h"
  43. #include "lv2/ui.h"
  44. #include "lv2/units.h"
  45. #include "lv2/uri-map.h"
  46. #include "lv2/urid.h"
  47. #include "lv2/worker.h"
  48. #include "lv2/lv2-miditype.h"
  49. #include "lv2/lv2-midifunctions.h"
  50. #include "lv2/lv2_external_ui.h"
  51. #include "lv2/lv2_programs.h"
  52. #include "lv2/lv2_rtmempool.h"
  53. #include "lv2_rdf.hpp"
  54. #include "lilv/lilvmm.hpp"
  55. #include "sratom/sratom.h"
  56. #include <QtCore/QMap>
  57. #include <QtCore/QStringList>
  58. // -------------------------------------------------
  59. // Define namespaces and missing prefixes
  60. #define NS_dct "http://purl.org/dc/terms/"
  61. #define NS_doap "http://usefulinc.com/ns/doap#"
  62. #define NS_rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  63. #define NS_rdfs "http://www.w3.org/2000/01/rdf-schema#"
  64. #define NS_llmm "http://ll-plugins.nongnu.org/lv2/ext/midimap#"
  65. #define LV2_MIDI_Map__CC "http://ll-plugins.nongnu.org/lv2/namespace#CC"
  66. #define LV2_MIDI_Map__NRPN "http://ll-plugins.nongnu.org/lv2/namespace#NRPN"
  67. #define LV2_MIDI_LL__MidiPort "http://ll-plugins.nongnu.org/lv2/ext/MidiPort"
  68. #define LV2_UI__Qt5UI LV2_UI_PREFIX "Qt5UI"
  69. #define LV2_UI__idle LV2_UI_PREFIX "idle"
  70. #define LV2_UI__makeResident LV2_UI_PREFIX "makeResident"
  71. // -------------------------------------------------
  72. // Custom Atom types
  73. struct LV2_Atom_MidiEvent {
  74. LV2_Atom_Event event;
  75. uint8_t data[4];
  76. };
  77. // -------------------------------------------------
  78. // Our LV2 World class
  79. class Lv2WorldClass : public Lilv::World
  80. {
  81. public:
  82. // Base Types
  83. Lilv::Node port;
  84. Lilv::Node symbol;
  85. Lilv::Node designation;
  86. Lilv::Node freeWheeling;
  87. Lilv::Node reportsLatency;
  88. // Plugin Types
  89. Lilv::Node class_allpass;
  90. Lilv::Node class_amplifier;
  91. Lilv::Node class_analyzer;
  92. Lilv::Node class_bandpass;
  93. Lilv::Node class_chorus;
  94. Lilv::Node class_comb;
  95. Lilv::Node class_compressor;
  96. Lilv::Node class_constant;
  97. Lilv::Node class_converter;
  98. Lilv::Node class_delay;
  99. Lilv::Node class_distortion;
  100. Lilv::Node class_dynamics;
  101. Lilv::Node class_eq;
  102. Lilv::Node class_envelope;
  103. Lilv::Node class_expander;
  104. Lilv::Node class_filter;
  105. Lilv::Node class_flanger;
  106. Lilv::Node class_function;
  107. Lilv::Node class_gate;
  108. Lilv::Node class_generator;
  109. Lilv::Node class_highpass;
  110. Lilv::Node class_instrument;
  111. Lilv::Node class_limiter;
  112. Lilv::Node class_lowpass;
  113. Lilv::Node class_mixer;
  114. Lilv::Node class_modulator;
  115. Lilv::Node class_multiEQ;
  116. Lilv::Node class_oscillator;
  117. Lilv::Node class_paraEQ;
  118. Lilv::Node class_phaser;
  119. Lilv::Node class_pitch;
  120. Lilv::Node class_reverb;
  121. Lilv::Node class_simulator;
  122. Lilv::Node class_spatial;
  123. Lilv::Node class_spectral;
  124. Lilv::Node class_utility;
  125. Lilv::Node class_waveshaper;
  126. // Port Types
  127. Lilv::Node port_input;
  128. Lilv::Node port_output;
  129. Lilv::Node port_control;
  130. Lilv::Node port_audio;
  131. Lilv::Node port_cv;
  132. Lilv::Node port_atom;
  133. Lilv::Node port_event;
  134. Lilv::Node port_midi;
  135. // Port Properties
  136. Lilv::Node pprop_optional;
  137. Lilv::Node pprop_enumeration;
  138. Lilv::Node pprop_integer;
  139. Lilv::Node pprop_sampleRate;
  140. Lilv::Node pprop_toggled;
  141. Lilv::Node pprop_artifacts;
  142. Lilv::Node pprop_continuousCV;
  143. Lilv::Node pprop_discreteCV;
  144. Lilv::Node pprop_expensive;
  145. Lilv::Node pprop_strictBounds;
  146. Lilv::Node pprop_logarithmic;
  147. Lilv::Node pprop_notAutomatic;
  148. Lilv::Node pprop_notOnGUI;
  149. Lilv::Node pprop_trigger;
  150. // Unit Hints
  151. Lilv::Node unit_name;
  152. Lilv::Node unit_render;
  153. Lilv::Node unit_symbol;
  154. Lilv::Node unit_unit;
  155. // UI Types
  156. Lilv::Node ui_gtk2;
  157. Lilv::Node ui_gtk3;
  158. Lilv::Node ui_qt4;
  159. Lilv::Node ui_qt5;
  160. Lilv::Node ui_cocoa;
  161. Lilv::Node ui_windows;
  162. Lilv::Node ui_x11;
  163. Lilv::Node ui_external;
  164. Lilv::Node ui_externalOld;
  165. // Misc
  166. Lilv::Node atom_bufferType;
  167. Lilv::Node atom_sequence;
  168. Lilv::Node atom_supports;
  169. Lilv::Node preset_preset;
  170. Lilv::Node state_state;
  171. Lilv::Node value_default;
  172. Lilv::Node value_minimum;
  173. Lilv::Node value_maximum;
  174. // Port Data Types
  175. Lilv::Node midi_event;
  176. Lilv::Node patch_message;
  177. Lilv::Node time_position;
  178. // MIDI CC
  179. Lilv::Node mm_defaultControl;
  180. Lilv::Node mm_controlType;
  181. Lilv::Node mm_controlNumber;
  182. // Other
  183. Lilv::Node dct_replaces;
  184. Lilv::Node doap_license;
  185. Lilv::Node rdf_type;
  186. Lilv::Node rdfs_label;
  187. // -------------------------------------------------
  188. Lv2WorldClass()
  189. : Lilv::World(),
  190. port (new_uri(LV2_CORE__port)),
  191. symbol (new_uri(LV2_CORE__symbol)),
  192. designation (new_uri(LV2_CORE__designation)),
  193. freeWheeling (new_uri(LV2_CORE__freeWheeling)),
  194. reportsLatency (new_uri(LV2_CORE__reportsLatency)),
  195. class_allpass (new_uri(LV2_CORE__AllpassPlugin)),
  196. class_amplifier (new_uri(LV2_CORE__AmplifierPlugin)),
  197. class_analyzer (new_uri(LV2_CORE__AnalyserPlugin)),
  198. class_bandpass (new_uri(LV2_CORE__BandpassPlugin)),
  199. class_chorus (new_uri(LV2_CORE__ChorusPlugin)),
  200. class_comb (new_uri(LV2_CORE__CombPlugin)),
  201. class_compressor (new_uri(LV2_CORE__CompressorPlugin)),
  202. class_constant (new_uri(LV2_CORE__ConstantPlugin)),
  203. class_converter (new_uri(LV2_CORE__ConverterPlugin)),
  204. class_delay (new_uri(LV2_CORE__DelayPlugin)),
  205. class_distortion (new_uri(LV2_CORE__DistortionPlugin)),
  206. class_dynamics (new_uri(LV2_CORE__DynamicsPlugin)),
  207. class_eq (new_uri(LV2_CORE__EQPlugin)),
  208. class_envelope (new_uri(LV2_CORE__EnvelopePlugin)),
  209. class_expander (new_uri(LV2_CORE__ExpanderPlugin)),
  210. class_filter (new_uri(LV2_CORE__FilterPlugin)),
  211. class_flanger (new_uri(LV2_CORE__FlangerPlugin)),
  212. class_function (new_uri(LV2_CORE__FunctionPlugin)),
  213. class_gate (new_uri(LV2_CORE__GatePlugin)),
  214. class_generator (new_uri(LV2_CORE__GeneratorPlugin)),
  215. class_highpass (new_uri(LV2_CORE__HighpassPlugin)),
  216. class_instrument (new_uri(LV2_CORE__InstrumentPlugin)),
  217. class_limiter (new_uri(LV2_CORE__LimiterPlugin)),
  218. class_lowpass (new_uri(LV2_CORE__LowpassPlugin)),
  219. class_mixer (new_uri(LV2_CORE__MixerPlugin)),
  220. class_modulator (new_uri(LV2_CORE__ModulatorPlugin)),
  221. class_multiEQ (new_uri(LV2_CORE__MultiEQPlugin)),
  222. class_oscillator (new_uri(LV2_CORE__OscillatorPlugin)),
  223. class_paraEQ (new_uri(LV2_CORE__ParaEQPlugin)),
  224. class_phaser (new_uri(LV2_CORE__PhaserPlugin)),
  225. class_pitch (new_uri(LV2_CORE__PitchPlugin)),
  226. class_reverb (new_uri(LV2_CORE__ReverbPlugin)),
  227. class_simulator (new_uri(LV2_CORE__SimulatorPlugin)),
  228. class_spatial (new_uri(LV2_CORE__SpatialPlugin)),
  229. class_spectral (new_uri(LV2_CORE__SpectralPlugin)),
  230. class_utility (new_uri(LV2_CORE__UtilityPlugin)),
  231. class_waveshaper (new_uri(LV2_CORE__WaveshaperPlugin)),
  232. port_input (new_uri(LV2_CORE__InputPort)),
  233. port_output (new_uri(LV2_CORE__OutputPort)),
  234. port_control (new_uri(LV2_CORE__ControlPort)),
  235. port_audio (new_uri(LV2_CORE__AudioPort)),
  236. port_cv (new_uri(LV2_CORE__CVPort)),
  237. port_atom (new_uri(LV2_ATOM__AtomPort)),
  238. port_event (new_uri(LV2_EVENT__EventPort)),
  239. port_midi (new_uri(LV2_MIDI_LL__MidiPort)),
  240. pprop_optional (new_uri(LV2_CORE__connectionOptional)),
  241. pprop_enumeration (new_uri(LV2_CORE__enumeration)),
  242. pprop_integer (new_uri(LV2_CORE__integer)),
  243. pprop_sampleRate (new_uri(LV2_CORE__sampleRate)),
  244. pprop_toggled (new_uri(LV2_CORE__toggled)),
  245. pprop_artifacts (new_uri(LV2_PORT_PROPS__causesArtifacts)),
  246. pprop_continuousCV (new_uri(LV2_PORT_PROPS__continuousCV)),
  247. pprop_discreteCV (new_uri(LV2_PORT_PROPS__discreteCV)),
  248. pprop_expensive (new_uri(LV2_PORT_PROPS__expensive)),
  249. pprop_strictBounds (new_uri(LV2_PORT_PROPS__hasStrictBounds)),
  250. pprop_logarithmic (new_uri(LV2_PORT_PROPS__logarithmic)),
  251. pprop_notAutomatic (new_uri(LV2_PORT_PROPS__notAutomatic)),
  252. pprop_notOnGUI (new_uri(LV2_PORT_PROPS__notOnGUI)),
  253. pprop_trigger (new_uri(LV2_PORT_PROPS__trigger)),
  254. unit_name (new_uri(LV2_UNITS__name)),
  255. unit_render (new_uri(LV2_UNITS__render)),
  256. unit_symbol (new_uri(LV2_UNITS__symbol)),
  257. unit_unit (new_uri(LV2_UNITS__unit)),
  258. ui_gtk2 (new_uri(LV2_UI__GtkUI)),
  259. ui_gtk3 (new_uri(LV2_UI__Gtk3UI)),
  260. ui_qt4 (new_uri(LV2_UI__Qt4UI)),
  261. ui_qt5 (new_uri(LV2_UI__Qt5UI)),
  262. ui_cocoa (new_uri(LV2_UI__CocoaUI)),
  263. ui_windows (new_uri(LV2_UI__WindowsUI)),
  264. ui_x11 (new_uri(LV2_UI__X11UI)),
  265. ui_external (new_uri(LV2_EXTERNAL_UI__Widget)),
  266. ui_externalOld (new_uri(LV2_EXTERNAL_UI_DEPRECATED_URI)),
  267. atom_bufferType (new_uri(LV2_ATOM__bufferType)),
  268. atom_sequence (new_uri(LV2_ATOM__Sequence)),
  269. atom_supports (new_uri(LV2_ATOM__supports)),
  270. preset_preset (new_uri(LV2_PRESETS__Preset)),
  271. state_state (new_uri(LV2_STATE__state)),
  272. value_default (new_uri(LV2_CORE__default)),
  273. value_minimum (new_uri(LV2_CORE__minimum)),
  274. value_maximum (new_uri(LV2_CORE__maximum)),
  275. midi_event (new_uri(LV2_MIDI__MidiEvent)),
  276. patch_message (new_uri(LV2_PATCH__Message)),
  277. time_position (new_uri(LV2_TIME__Position)),
  278. mm_defaultControl (new_uri(NS_llmm "defaultMidiController")),
  279. mm_controlType (new_uri(NS_llmm "controllerType")),
  280. mm_controlNumber (new_uri(NS_llmm "controllerNumber")),
  281. dct_replaces (new_uri(NS_dct "replaces")),
  282. doap_license (new_uri(NS_doap "license")),
  283. rdf_type (new_uri(NS_rdf "type")),
  284. rdfs_label (new_uri(NS_rdfs "label"))
  285. {
  286. needInit = true;
  287. }
  288. void init()
  289. {
  290. if (! needInit)
  291. return;
  292. needInit = false;
  293. Lilv::World::load_all();
  294. }
  295. const LilvPlugin* getPlugin(const LV2_URI uri)
  296. {
  297. CARLA_ASSERT(uri != nullptr);
  298. static const Lilv::Plugins lilvPlugins(Lilv::World::get_all_plugins());
  299. LilvNode* const uriNode(Lilv::World::new_uri(uri));
  300. if (uriNode == nullptr)
  301. {
  302. carla_stderr("Lv2WorldClass::getPlugin(\"%s\") - Failed to get node from uri", uri);
  303. return nullptr;
  304. }
  305. if (const LilvPlugin* const cPlugin = lilv_plugins_get_by_uri(lilvPlugins.me, uriNode))
  306. {
  307. lilv_node_free(uriNode);
  308. return cPlugin;
  309. }
  310. else
  311. {
  312. carla_stderr("Lv2WorldClass::getPlugin(\"%s\") - Failed to get plugin", uri);
  313. lilv_node_free(uriNode);
  314. return nullptr;
  315. }
  316. }
  317. private:
  318. bool needInit;
  319. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Lv2WorldClass)
  320. };
  321. // -----------------------------------------------------
  322. // Our LV2 World class object
  323. extern Lv2WorldClass gLv2World;
  324. // -----------------------------------------------------
  325. // Create new RDF object (using lilv)
  326. static inline
  327. const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri)
  328. {
  329. CARLA_ASSERT(uri != nullptr);
  330. if (uri == nullptr)
  331. {
  332. carla_stderr("lv2_rdf_new() - Invalid uri");
  333. return nullptr;
  334. }
  335. const LilvPlugin* const cPlugin(gLv2World.getPlugin(uri));
  336. if (cPlugin == nullptr)
  337. {
  338. // Error already printed in getPlugin()
  339. return nullptr;
  340. }
  341. Lilv::Plugin lilvPlugin(cPlugin);
  342. LV2_RDF_Descriptor* const rdfDescriptor(new LV2_RDF_Descriptor());
  343. // --------------------------------------------------
  344. // Set Plugin Type
  345. {
  346. Lilv::Nodes typeNodes(lilvPlugin.get_value(gLv2World.rdf_type));
  347. if (typeNodes.size() > 0)
  348. {
  349. if (typeNodes.contains(gLv2World.class_allpass))
  350. rdfDescriptor->Type[0] |= LV2_PLUGIN_ALLPASS;
  351. if (typeNodes.contains(gLv2World.class_amplifier))
  352. rdfDescriptor->Type[0] |= LV2_PLUGIN_AMPLIFIER;
  353. if (typeNodes.contains(gLv2World.class_analyzer))
  354. rdfDescriptor->Type[1] |= LV2_PLUGIN_ANALYSER;
  355. if (typeNodes.contains(gLv2World.class_bandpass))
  356. rdfDescriptor->Type[0] |= LV2_PLUGIN_BANDPASS;
  357. if (typeNodes.contains(gLv2World.class_chorus))
  358. rdfDescriptor->Type[1] |= LV2_PLUGIN_CHORUS;
  359. if (typeNodes.contains(gLv2World.class_comb))
  360. rdfDescriptor->Type[1] |= LV2_PLUGIN_COMB;
  361. if (typeNodes.contains(gLv2World.class_compressor))
  362. rdfDescriptor->Type[0] |= LV2_PLUGIN_COMPRESSOR;
  363. if (typeNodes.contains(gLv2World.class_constant))
  364. rdfDescriptor->Type[1] |= LV2_PLUGIN_CONSTANT;
  365. if (typeNodes.contains(gLv2World.class_converter))
  366. rdfDescriptor->Type[1] |= LV2_PLUGIN_CONVERTER;
  367. if (typeNodes.contains(gLv2World.class_delay))
  368. rdfDescriptor->Type[0] |= LV2_PLUGIN_DELAY;
  369. if (typeNodes.contains(gLv2World.class_distortion))
  370. rdfDescriptor->Type[0] |= LV2_PLUGIN_DISTORTION;
  371. if (typeNodes.contains(gLv2World.class_dynamics))
  372. rdfDescriptor->Type[0] |= LV2_PLUGIN_DYNAMICS;
  373. if (typeNodes.contains(gLv2World.class_eq))
  374. rdfDescriptor->Type[0] |= LV2_PLUGIN_EQ;
  375. if (typeNodes.contains(gLv2World.class_envelope))
  376. rdfDescriptor->Type[0] |= LV2_PLUGIN_ENVELOPE;
  377. if (typeNodes.contains(gLv2World.class_expander))
  378. rdfDescriptor->Type[0] |= LV2_PLUGIN_EXPANDER;
  379. if (typeNodes.contains(gLv2World.class_filter))
  380. rdfDescriptor->Type[0] |= LV2_PLUGIN_FILTER;
  381. if (typeNodes.contains(gLv2World.class_flanger))
  382. rdfDescriptor->Type[1] |= LV2_PLUGIN_FLANGER;
  383. if (typeNodes.contains(gLv2World.class_function))
  384. rdfDescriptor->Type[1] |= LV2_PLUGIN_FUNCTION;
  385. if (typeNodes.contains(gLv2World.class_gate))
  386. rdfDescriptor->Type[0] |= LV2_PLUGIN_GATE;
  387. if (typeNodes.contains(gLv2World.class_generator))
  388. rdfDescriptor->Type[1] |= LV2_PLUGIN_GENERATOR;
  389. if (typeNodes.contains(gLv2World.class_highpass))
  390. rdfDescriptor->Type[0] |= LV2_PLUGIN_HIGHPASS;
  391. if (typeNodes.contains(gLv2World.class_instrument))
  392. rdfDescriptor->Type[1] |= LV2_PLUGIN_INSTRUMENT;
  393. if (typeNodes.contains(gLv2World.class_limiter))
  394. rdfDescriptor->Type[0] |= LV2_PLUGIN_LIMITER;
  395. if (typeNodes.contains(gLv2World.class_lowpass))
  396. rdfDescriptor->Type[0] |= LV2_PLUGIN_LOWPASS;
  397. if (typeNodes.contains(gLv2World.class_mixer))
  398. rdfDescriptor->Type[1] |= LV2_PLUGIN_MIXER;
  399. if (typeNodes.contains(gLv2World.class_modulator))
  400. rdfDescriptor->Type[1] |= LV2_PLUGIN_MODULATOR;
  401. if (typeNodes.contains(gLv2World.class_multiEQ))
  402. rdfDescriptor->Type[0] |= LV2_PLUGIN_MULTI_EQ;
  403. if (typeNodes.contains(gLv2World.class_oscillator))
  404. rdfDescriptor->Type[1] |= LV2_PLUGIN_OSCILLATOR;
  405. if (typeNodes.contains(gLv2World.class_paraEQ))
  406. rdfDescriptor->Type[0] |= LV2_PLUGIN_PARA_EQ;
  407. if (typeNodes.contains(gLv2World.class_phaser))
  408. rdfDescriptor->Type[1] |= LV2_PLUGIN_PHASER;
  409. if (typeNodes.contains(gLv2World.class_pitch))
  410. rdfDescriptor->Type[1] |= LV2_PLUGIN_PITCH;
  411. if (typeNodes.contains(gLv2World.class_reverb))
  412. rdfDescriptor->Type[0] |= LV2_PLUGIN_REVERB;
  413. if (typeNodes.contains(gLv2World.class_simulator))
  414. rdfDescriptor->Type[0] |= LV2_PLUGIN_SIMULATOR;
  415. if (typeNodes.contains(gLv2World.class_spatial))
  416. rdfDescriptor->Type[1] |= LV2_PLUGIN_SPATIAL;
  417. if (typeNodes.contains(gLv2World.class_spectral))
  418. rdfDescriptor->Type[1] |= LV2_PLUGIN_SPECTRAL;
  419. if (typeNodes.contains(gLv2World.class_utility))
  420. rdfDescriptor->Type[1] |= LV2_PLUGIN_UTILITY;
  421. if (typeNodes.contains(gLv2World.class_waveshaper))
  422. rdfDescriptor->Type[0] |= LV2_PLUGIN_WAVESHAPER;
  423. }
  424. }
  425. // --------------------------------------------------
  426. // Set Plugin Information
  427. {
  428. rdfDescriptor->URI = carla_strdup(uri);
  429. if (const char* const name = lilvPlugin.get_name().as_string())
  430. rdfDescriptor->Name = carla_strdup(name);
  431. if (const char* const author = lilvPlugin.get_author_name().as_string())
  432. rdfDescriptor->Author = carla_strdup(author);
  433. if (const char* const binary = lilvPlugin.get_library_uri().as_string())
  434. rdfDescriptor->Binary = carla_strdup(lilv_uri_to_path(binary));
  435. if (const char* const bundle = lilvPlugin.get_bundle_uri().as_string())
  436. rdfDescriptor->Bundle = carla_strdup(lilv_uri_to_path(bundle));
  437. Lilv::Nodes licenseNodes(lilvPlugin.get_value(gLv2World.doap_license));
  438. if (licenseNodes.size() > 0)
  439. {
  440. if (const char* const license = licenseNodes.get_first().as_string())
  441. rdfDescriptor->License = carla_strdup(license);
  442. }
  443. }
  444. // --------------------------------------------------
  445. // Set Plugin UniqueID
  446. {
  447. Lilv::Nodes replaceNodes(lilvPlugin.get_value(gLv2World.dct_replaces));
  448. if (replaceNodes.size() > 0)
  449. {
  450. Lilv::Node replaceNode(replaceNodes.get_first());
  451. if (replaceNode.is_uri())
  452. {
  453. const QString replaceURI(replaceNode.as_uri());
  454. if (replaceURI.startsWith("urn:"))
  455. {
  456. const QString replaceId(replaceURI.split(":").last());
  457. bool ok;
  458. ulong uniqueId = replaceId.toULong(&ok);
  459. if (ok && uniqueId != 0)
  460. rdfDescriptor->UniqueID = uniqueId;
  461. }
  462. }
  463. }
  464. }
  465. // --------------------------------------------------
  466. // Set Plugin Ports
  467. if (lilvPlugin.get_num_ports() > 0)
  468. {
  469. rdfDescriptor->PortCount = lilvPlugin.get_num_ports();
  470. rdfDescriptor->Ports = new LV2_RDF_Port[rdfDescriptor->PortCount];
  471. for (uint32_t j = 0; j < rdfDescriptor->PortCount; j++)
  472. {
  473. Lilv::Port lilvPort(lilvPlugin.get_port_by_index(j));
  474. LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j];
  475. // --------------------------------------
  476. // Set Port Information
  477. {
  478. if (const char* const name = Lilv::Node(lilvPort.get_name()).as_string())
  479. rdfPort->Name = carla_strdup(name);
  480. if (const char* const symbol = Lilv::Node(lilvPort.get_symbol()).as_string())
  481. rdfPort->Symbol = carla_strdup(symbol);
  482. }
  483. // --------------------------------------
  484. // Set Port Mode and Type
  485. {
  486. // Input or Output
  487. if (lilvPort.is_a(gLv2World.port_input))
  488. rdfPort->Types |= LV2_PORT_INPUT;
  489. else if (lilvPort.is_a(gLv2World.port_output))
  490. rdfPort->Types |= LV2_PORT_OUTPUT;
  491. else
  492. carla_stderr("lv2_rdf_new(\"%s\") - port '%s' is not input or output", uri, rdfPort->Name);
  493. // Data Type
  494. if (lilvPort.is_a(gLv2World.port_control))
  495. rdfPort->Types |= LV2_PORT_CONTROL;
  496. else if (lilvPort.is_a(gLv2World.port_audio))
  497. rdfPort->Types |= LV2_PORT_AUDIO;
  498. else if (lilvPort.is_a(gLv2World.port_cv))
  499. rdfPort->Types |= LV2_PORT_CV;
  500. else if (lilvPort.is_a(gLv2World.port_atom))
  501. {
  502. rdfPort->Types |= LV2_PORT_ATOM;
  503. Lilv::Nodes bufferTypeNodes(lilvPort.get_value(gLv2World.atom_bufferType));
  504. if (bufferTypeNodes.contains(gLv2World.atom_sequence))
  505. rdfPort->Types |= LV2_PORT_ATOM_SEQUENCE;
  506. else
  507. carla_stderr("lv2_rdf_new(\"%s\") - port '%s' uses an unknown atom buffer type", uri, rdfPort->Name);
  508. Lilv::Nodes supportNodes(lilvPort.get_value(gLv2World.atom_supports));
  509. bool supported = false;
  510. if (supportNodes.contains(gLv2World.midi_event))
  511. {
  512. rdfPort->Types |= LV2_PORT_DATA_MIDI_EVENT;
  513. supported = true;
  514. }
  515. if (supportNodes.contains(gLv2World.patch_message))
  516. {
  517. rdfPort->Types |= LV2_PORT_DATA_PATCH_MESSAGE;
  518. supported = true;
  519. }
  520. if (supportNodes.contains(gLv2World.time_position))
  521. {
  522. rdfPort->Types |= LV2_PORT_DATA_TIME_POSITION;
  523. supported = true;
  524. }
  525. if (! supported)
  526. carla_stderr("lv2_rdf_new(\"%s\") - port '%s' is of atom type but has unsupported data", uri, rdfPort->Name);
  527. }
  528. else if (lilvPort.is_a(gLv2World.port_event))
  529. {
  530. rdfPort->Types |= LV2_PORT_EVENT;
  531. bool supported = false;
  532. if (lilvPort.supports_event(gLv2World.midi_event))
  533. {
  534. rdfPort->Types |= LV2_PORT_DATA_MIDI_EVENT;
  535. supported = true;
  536. }
  537. if (lilvPort.supports_event(gLv2World.patch_message))
  538. {
  539. rdfPort->Types |= LV2_PORT_DATA_PATCH_MESSAGE;
  540. supported = true;
  541. }
  542. if (lilvPort.supports_event(gLv2World.time_position))
  543. {
  544. rdfPort->Types |= LV2_PORT_DATA_TIME_POSITION;
  545. supported = true;
  546. }
  547. if (! supported)
  548. carla_stderr("lv2_rdf_new(\"%s\") - port '%s' is of event type but has unsupported data", uri, rdfPort->Name);
  549. }
  550. else if (lilvPort.is_a(gLv2World.port_midi))
  551. {
  552. rdfPort->Types |= LV2_PORT_MIDI_LL;
  553. rdfPort->Types |= LV2_PORT_DATA_MIDI_EVENT;
  554. }
  555. else
  556. carla_stderr("lv2_rdf_new(\"%s\") - port '%s' is of unkown data type", uri, rdfPort->Name);
  557. }
  558. // --------------------------------------
  559. // Set Port Properties
  560. {
  561. if (lilvPort.has_property(gLv2World.pprop_optional))
  562. rdfPort->Properties |= LV2_PORT_OPTIONAL;
  563. if (lilvPort.has_property(gLv2World.pprop_enumeration))
  564. rdfPort->Properties |= LV2_PORT_ENUMERATION;
  565. if (lilvPort.has_property(gLv2World.pprop_integer))
  566. rdfPort->Properties |= LV2_PORT_INTEGER;
  567. if (lilvPort.has_property(gLv2World.pprop_sampleRate))
  568. rdfPort->Properties |= LV2_PORT_SAMPLE_RATE;
  569. if (lilvPort.has_property(gLv2World.pprop_toggled))
  570. rdfPort->Properties |= LV2_PORT_TOGGLED;
  571. if (lilvPort.has_property(gLv2World.pprop_artifacts))
  572. rdfPort->Properties |= LV2_PORT_CAUSES_ARTIFACTS;
  573. if (lilvPort.has_property(gLv2World.pprop_continuousCV))
  574. rdfPort->Properties |= LV2_PORT_CONTINUOUS_CV;
  575. if (lilvPort.has_property(gLv2World.pprop_discreteCV))
  576. rdfPort->Properties |= LV2_PORT_DISCRETE_CV;
  577. if (lilvPort.has_property(gLv2World.pprop_expensive))
  578. rdfPort->Properties |= LV2_PORT_EXPENSIVE;
  579. if (lilvPort.has_property(gLv2World.pprop_strictBounds))
  580. rdfPort->Properties |= LV2_PORT_STRICT_BOUNDS;
  581. if (lilvPort.has_property(gLv2World.pprop_logarithmic))
  582. rdfPort->Properties |= LV2_PORT_LOGARITHMIC;
  583. if (lilvPort.has_property(gLv2World.pprop_notAutomatic))
  584. rdfPort->Properties |= LV2_PORT_NOT_AUTOMATIC;
  585. if (lilvPort.has_property(gLv2World.pprop_notOnGUI))
  586. rdfPort->Properties |= LV2_PORT_NOT_ON_GUI;
  587. if (lilvPort.has_property(gLv2World.pprop_trigger))
  588. rdfPort->Properties |= LV2_PORT_TRIGGER;
  589. if (lilvPort.has_property(gLv2World.reportsLatency))
  590. rdfPort->Designation = LV2_PORT_DESIGNATION_LATENCY;
  591. }
  592. // --------------------------------------
  593. // Set Port Designation
  594. {
  595. Lilv::Nodes designationNodes(lilvPort.get_value(gLv2World.designation));
  596. if (designationNodes.size() > 0)
  597. {
  598. if (const char* const designation = designationNodes.get_first().as_string())
  599. {
  600. if (std::strcmp(designation, LV2_CORE__control) == 0)
  601. rdfPort->Designation = LV2_PORT_DESIGNATION_CONTROL;
  602. else if (std::strcmp(designation, LV2_CORE__freeWheeling) == 0)
  603. rdfPort->Designation = LV2_PORT_DESIGNATION_FREEWHEELING;
  604. else if (std::strcmp(designation, LV2_CORE__latency) == 0)
  605. rdfPort->Designation = LV2_PORT_DESIGNATION_LATENCY;
  606. else if (std::strcmp(designation, LV2_PARAMETERS__sampleRate) == 0)
  607. rdfPort->Designation = LV2_PORT_DESIGNATION_SAMPLE_RATE;
  608. else if (std::strcmp(designation, LV2_TIME__bar) == 0)
  609. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BAR;
  610. else if (std::strcmp(designation, LV2_TIME__barBeat) == 0)
  611. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BAR_BEAT;
  612. else if (std::strcmp(designation, LV2_TIME__beat) == 0)
  613. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BEAT;
  614. else if (std::strcmp(designation, LV2_TIME__beatUnit) == 0)
  615. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BEAT_UNIT;
  616. else if (std::strcmp(designation, LV2_TIME__beatsPerBar) == 0)
  617. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR;
  618. else if (std::strcmp(designation, LV2_TIME__beatsPerMinute) == 0)
  619. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE;
  620. else if (std::strcmp(designation, LV2_TIME__frame) == 0)
  621. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_FRAME;
  622. else if (std::strcmp(designation, LV2_TIME__framesPerSecond) == 0)
  623. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND;
  624. else if (std::strcmp(designation, LV2_TIME__position) == 0)
  625. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_POSITION;
  626. else if (std::strcmp(designation, LV2_TIME__speed) == 0)
  627. rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_SPEED;
  628. else if (std::strncmp(designation, LV2_PARAMETERS_PREFIX, std::strlen(LV2_PARAMETERS_PREFIX)) == 0)
  629. pass();
  630. else if (std::strncmp(designation, LV2_PORT_GROUPS_PREFIX, std::strlen(LV2_PORT_GROUPS_PREFIX)) == 0)
  631. pass();
  632. else
  633. carla_stderr("lv2_rdf_new(\"%s\") - got unknown port designation '%s'", uri, designation);
  634. }
  635. }
  636. }
  637. // --------------------------------------
  638. // Set Port MIDI Map
  639. {
  640. Lilv::Nodes midiMapNodes(lilvPort.get_value(gLv2World.mm_defaultControl));
  641. if (midiMapNodes.size() > 0)
  642. {
  643. Lilv::Node midiMapNode(midiMapNodes.get_first());
  644. if (midiMapNode.is_blank())
  645. {
  646. Lilv::Nodes midiMapTypeNodes(gLv2World.find_nodes(midiMapNode, gLv2World.mm_controlType, nullptr));
  647. Lilv::Nodes midiMapNumberNodes(gLv2World.find_nodes(midiMapNode, gLv2World.mm_controlNumber, nullptr));
  648. if (midiMapTypeNodes.size() == 1 && midiMapNumberNodes.size() == 1)
  649. {
  650. if (const char* const midiMapType = midiMapTypeNodes.get_first().as_string())
  651. {
  652. if (std::strcmp(midiMapType, LV2_MIDI_Map__CC) == 0)
  653. rdfPort->MidiMap.Type = LV2_PORT_MIDI_MAP_CC;
  654. else if (std::strcmp(midiMapType, LV2_MIDI_Map__NRPN) == 0)
  655. rdfPort->MidiMap.Type = LV2_PORT_MIDI_MAP_NRPN;
  656. else
  657. carla_stderr("lv2_rdf_new(\"%s\") - got unknown port Midi-Map type '%s'", uri, midiMapType);
  658. rdfPort->MidiMap.Number = static_cast<uint32_t>(midiMapNumberNodes.get_first().as_int());
  659. }
  660. }
  661. }
  662. }
  663. // TODO - also check using new official MIDI API too
  664. }
  665. // --------------------------------------
  666. // Set Port Points
  667. {
  668. Lilv::Nodes valueNodes(lilvPort.get_value(gLv2World.value_default));
  669. if (valueNodes.size() > 0)
  670. {
  671. rdfPort->Points.Hints |= LV2_PORT_POINT_DEFAULT;
  672. rdfPort->Points.Default = valueNodes.get_first().as_float();
  673. }
  674. valueNodes = lilvPort.get_value(gLv2World.value_minimum);
  675. if (valueNodes.size() > 0)
  676. {
  677. rdfPort->Points.Hints |= LV2_PORT_POINT_MINIMUM;
  678. rdfPort->Points.Minimum = valueNodes.get_first().as_float();
  679. }
  680. valueNodes = lilvPort.get_value(gLv2World.value_maximum);
  681. if (valueNodes.size() > 0)
  682. {
  683. rdfPort->Points.Hints |= LV2_PORT_POINT_MAXIMUM;
  684. rdfPort->Points.Maximum = valueNodes.get_first().as_float();
  685. }
  686. }
  687. // --------------------------------------
  688. // Set Port Unit
  689. {
  690. Lilv::Nodes unitUnitNodes(lilvPort.get_value(gLv2World.unit_unit));
  691. if (unitUnitNodes.size() > 0)
  692. {
  693. if (const char* const unitUnit = unitUnitNodes.get_first().as_uri())
  694. {
  695. rdfPort->Unit.Hints |= LV2_PORT_UNIT_UNIT;
  696. if (std::strcmp(unitUnit, LV2_UNITS__bar) == 0)
  697. rdfPort->Unit.Unit = LV2_PORT_UNIT_BAR;
  698. else if (std::strcmp(unitUnit, LV2_UNITS__beat) == 0)
  699. rdfPort->Unit.Unit = LV2_PORT_UNIT_BEAT;
  700. else if (std::strcmp(unitUnit, LV2_UNITS__bpm) == 0)
  701. rdfPort->Unit.Unit = LV2_PORT_UNIT_BPM;
  702. else if (std::strcmp(unitUnit, LV2_UNITS__cent) == 0)
  703. rdfPort->Unit.Unit = LV2_PORT_UNIT_CENT;
  704. else if (std::strcmp(unitUnit, LV2_UNITS__cm) == 0)
  705. rdfPort->Unit.Unit = LV2_PORT_UNIT_CM;
  706. else if (std::strcmp(unitUnit, LV2_UNITS__coef) == 0)
  707. rdfPort->Unit.Unit = LV2_PORT_UNIT_COEF;
  708. else if (std::strcmp(unitUnit, LV2_UNITS__db) == 0)
  709. rdfPort->Unit.Unit = LV2_PORT_UNIT_DB;
  710. else if (std::strcmp(unitUnit, LV2_UNITS__degree) == 0)
  711. rdfPort->Unit.Unit = LV2_PORT_UNIT_DEGREE;
  712. else if (std::strcmp(unitUnit, LV2_UNITS__frame) == 0)
  713. rdfPort->Unit.Unit = LV2_PORT_UNIT_FRAME;
  714. else if (std::strcmp(unitUnit, LV2_UNITS__hz) == 0)
  715. rdfPort->Unit.Unit = LV2_PORT_UNIT_HZ;
  716. else if (std::strcmp(unitUnit, LV2_UNITS__inch) == 0)
  717. rdfPort->Unit.Unit = LV2_PORT_UNIT_INCH;
  718. else if (std::strcmp(unitUnit, LV2_UNITS__khz) == 0)
  719. rdfPort->Unit.Unit = LV2_PORT_UNIT_KHZ;
  720. else if (std::strcmp(unitUnit, LV2_UNITS__km) == 0)
  721. rdfPort->Unit.Unit = LV2_PORT_UNIT_KM;
  722. else if (std::strcmp(unitUnit, LV2_UNITS__m) == 0)
  723. rdfPort->Unit.Unit = LV2_PORT_UNIT_M;
  724. else if (std::strcmp(unitUnit, LV2_UNITS__mhz) == 0)
  725. rdfPort->Unit.Unit = LV2_PORT_UNIT_MHZ;
  726. else if (std::strcmp(unitUnit, LV2_UNITS__midiNote) == 0)
  727. rdfPort->Unit.Unit = LV2_PORT_UNIT_MIDINOTE;
  728. else if (std::strcmp(unitUnit, LV2_UNITS__mile) == 0)
  729. rdfPort->Unit.Unit = LV2_PORT_UNIT_MILE;
  730. else if (std::strcmp(unitUnit, LV2_UNITS__min) == 0)
  731. rdfPort->Unit.Unit = LV2_PORT_UNIT_MIN;
  732. else if (std::strcmp(unitUnit, LV2_UNITS__mm) == 0)
  733. rdfPort->Unit.Unit = LV2_PORT_UNIT_MM;
  734. else if (std::strcmp(unitUnit, LV2_UNITS__ms) == 0)
  735. rdfPort->Unit.Unit = LV2_PORT_UNIT_MS;
  736. else if (std::strcmp(unitUnit, LV2_UNITS__oct) == 0)
  737. rdfPort->Unit.Unit = LV2_PORT_UNIT_OCT;
  738. else if (std::strcmp(unitUnit, LV2_UNITS__pc) == 0)
  739. rdfPort->Unit.Unit = LV2_PORT_UNIT_PC;
  740. else if (std::strcmp(unitUnit, LV2_UNITS__s) == 0)
  741. rdfPort->Unit.Unit = LV2_PORT_UNIT_S;
  742. else if (std::strcmp(unitUnit, LV2_UNITS__semitone12TET) == 0)
  743. rdfPort->Unit.Unit = LV2_PORT_UNIT_SEMITONE;
  744. else
  745. carla_stderr("lv2_rdf_new(\"%s\") - got unknown unit type '%s'", uri, unitUnit);
  746. }
  747. }
  748. Lilv::Nodes unitNameNodes(lilvPort.get_value(gLv2World.unit_name));
  749. if (unitNameNodes.size() > 0)
  750. {
  751. if (const char* const unitName = unitNameNodes.get_first().as_string())
  752. {
  753. rdfPort->Unit.Hints |= LV2_PORT_UNIT_NAME;
  754. rdfPort->Unit.Name = carla_strdup(unitName);
  755. }
  756. }
  757. Lilv::Nodes unitRenderNodes(lilvPort.get_value(gLv2World.unit_render));
  758. if (unitRenderNodes.size() > 0)
  759. {
  760. if (const char* const unitRender = unitRenderNodes.get_first().as_string())
  761. {
  762. rdfPort->Unit.Hints |= LV2_PORT_UNIT_RENDER;
  763. rdfPort->Unit.Render = carla_strdup(unitRender);
  764. }
  765. }
  766. Lilv::Nodes unitSymbolNodes(lilvPort.get_value(gLv2World.unit_symbol));
  767. if (unitSymbolNodes.size() > 0)
  768. {
  769. if (const char* const unitSymbol = unitSymbolNodes.get_first().as_string())
  770. {
  771. rdfPort->Unit.Hints |= LV2_PORT_UNIT_SYMBOL;
  772. rdfPort->Unit.Symbol = carla_strdup(unitSymbol);
  773. }
  774. }
  775. }
  776. // --------------------------------------
  777. // Set Port Scale Points
  778. Lilv::ScalePoints lilvScalePoints(lilvPort.get_scale_points());
  779. if (lilvScalePoints.size() > 0)
  780. {
  781. rdfPort->ScalePointCount = lilvScalePoints.size();
  782. rdfPort->ScalePoints = new LV2_RDF_PortScalePoint[rdfPort->ScalePointCount];
  783. uint32_t h = 0;
  784. LILV_FOREACH(scale_points, j, lilvScalePoints)
  785. {
  786. Lilv::ScalePoint lilvScalePoint(lilvScalePoints.get(j));
  787. LV2_RDF_PortScalePoint* const rdfScalePoint = &rdfPort->ScalePoints[h++];
  788. if (const char* const label = Lilv::Node(lilvScalePoint.get_label()).as_string())
  789. rdfScalePoint->Label = carla_strdup(label);
  790. rdfScalePoint->Value = Lilv::Node(lilvScalePoint.get_value()).as_float();
  791. }
  792. }
  793. }
  794. }
  795. // --------------------------------------------------
  796. // Set Plugin Presets
  797. {
  798. Lilv::Nodes presetNodes(lilvPlugin.get_related(gLv2World.preset_preset));
  799. if (presetNodes.size() > 0)
  800. {
  801. // create a list of preset URIs (for checking appliesTo, sorting and unique-ness)
  802. QStringList presetListURIs;
  803. LILV_FOREACH(nodes, j, presetNodes)
  804. {
  805. Lilv::Node presetNode(presetNodes.get(j));
  806. // FIXME - check appliesTo
  807. QString presetURI(presetNode.as_uri());
  808. if (! presetListURIs.contains(presetURI))
  809. presetListURIs.append(presetURI);
  810. }
  811. presetListURIs.sort();
  812. // create presets with unique URIs
  813. rdfDescriptor->PresetCount = static_cast<uint32_t>(presetListURIs.count());
  814. rdfDescriptor->Presets = new LV2_RDF_Preset[rdfDescriptor->PresetCount];
  815. // set preset data
  816. LILV_FOREACH(nodes, j, presetNodes)
  817. {
  818. Lilv::Node presetNode(presetNodes.get(j));
  819. if (gLv2World.load_resource(presetNode) == -1)
  820. continue;
  821. if (const char* const presetURI = presetNode.as_uri())
  822. {
  823. int32_t index = presetListURIs.indexOf(QString(presetURI));
  824. if (index < 0)
  825. continue;
  826. LV2_RDF_Preset* const rdfPreset = &rdfDescriptor->Presets[index];
  827. // --------------------------------------
  828. // Set Preset Information
  829. {
  830. rdfPreset->URI = carla_strdup(presetURI);
  831. Lilv::Nodes presetLabelNodes(gLv2World.find_nodes(presetNode, gLv2World.rdfs_label, nullptr));
  832. if (presetLabelNodes.size() > 0)
  833. {
  834. if (const char* const label = presetLabelNodes.get_first().as_string())
  835. rdfPreset->Label = carla_strdup(label);
  836. }
  837. }
  838. }
  839. }
  840. }
  841. }
  842. // --------------------------------------------------
  843. // Set Plugin Features
  844. {
  845. Lilv::Nodes lilvFeatureNodes(lilvPlugin.get_supported_features());
  846. if (lilvFeatureNodes.size() > 0)
  847. {
  848. Lilv::Nodes lilvFeatureNodesR(lilvPlugin.get_required_features());
  849. rdfDescriptor->FeatureCount = lilvFeatureNodes.size();
  850. rdfDescriptor->Features = new LV2_RDF_Feature[rdfDescriptor->FeatureCount];
  851. uint32_t h = 0;
  852. LILV_FOREACH(nodes, j, lilvFeatureNodes)
  853. {
  854. CARLA_ASSERT(h < rdfDescriptor->FeatureCount);
  855. Lilv::Node lilvFeatureNode(lilvFeatureNodes.get(j));
  856. LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[h++];
  857. rdfFeature->Type = lilvFeatureNodesR.contains(lilvFeatureNode) ? LV2_FEATURE_REQUIRED : LV2_FEATURE_OPTIONAL;
  858. if (const char* const featureURI = lilvFeatureNode.as_uri())
  859. rdfFeature->URI = carla_strdup(featureURI);
  860. }
  861. }
  862. }
  863. // --------------------------------------------------
  864. // Set Plugin Extensions
  865. {
  866. Lilv::Nodes lilvExtensionDataNodes(lilvPlugin.get_extension_data());
  867. if (lilvExtensionDataNodes.size() > 0)
  868. {
  869. rdfDescriptor->ExtensionCount = lilvExtensionDataNodes.size();
  870. rdfDescriptor->Extensions = new LV2_URI[rdfDescriptor->ExtensionCount];
  871. uint32_t h = 0;
  872. LILV_FOREACH(nodes, j, lilvExtensionDataNodes)
  873. {
  874. CARLA_ASSERT(h < rdfDescriptor->ExtensionCount);
  875. Lilv::Node lilvExtensionDataNode(lilvExtensionDataNodes.get(j));
  876. LV2_URI* const rdfExtension = &rdfDescriptor->Extensions[h++];
  877. if (const char* const extURI = lilvExtensionDataNode.as_uri())
  878. *rdfExtension = carla_strdup(extURI);
  879. }
  880. }
  881. }
  882. // --------------------------------------------------
  883. // Set Plugin UIs
  884. {
  885. Lilv::UIs lilvUIs(lilvPlugin.get_uis());
  886. if (lilvUIs.size() > 0)
  887. {
  888. rdfDescriptor->UICount = lilvUIs.size();
  889. rdfDescriptor->UIs = new LV2_RDF_UI[rdfDescriptor->UICount];
  890. uint32_t h = 0;
  891. LILV_FOREACH(uis, j, lilvUIs)
  892. {
  893. CARLA_ASSERT(h < rdfDescriptor->UICount);
  894. Lilv::UI lilvUI(lilvUIs.get(j));
  895. LV2_RDF_UI* const rdfUI = &rdfDescriptor->UIs[h++];
  896. // --------------------------------------
  897. // Set UI Type
  898. if (lilvUI.is_a(gLv2World.ui_gtk2))
  899. rdfUI->Type = LV2_UI_GTK2;
  900. else if (lilvUI.is_a(gLv2World.ui_gtk3))
  901. rdfUI->Type = LV2_UI_GTK3;
  902. else if (lilvUI.is_a(gLv2World.ui_qt4))
  903. rdfUI->Type = LV2_UI_QT4;
  904. else if (lilvUI.is_a(gLv2World.ui_qt5))
  905. rdfUI->Type = LV2_UI_QT5;
  906. else if (lilvUI.is_a(gLv2World.ui_cocoa))
  907. rdfUI->Type = LV2_UI_COCOA;
  908. else if (lilvUI.is_a(gLv2World.ui_windows))
  909. rdfUI->Type = LV2_UI_WINDOWS;
  910. else if (lilvUI.is_a(gLv2World.ui_x11))
  911. rdfUI->Type = LV2_UI_X11;
  912. else if (lilvUI.is_a(gLv2World.ui_external))
  913. rdfUI->Type = LV2_UI_EXTERNAL;
  914. else if (lilvUI.is_a(gLv2World.ui_externalOld))
  915. rdfUI->Type = LV2_UI_OLD_EXTERNAL;
  916. else
  917. carla_stderr("lv2_rdf_new(\"%s\") - UI '%s' is of unknown type", uri, lilvUI.get_uri().as_uri());
  918. // --------------------------------------
  919. // Set UI Information
  920. {
  921. if (const char* const uiURI = lilvUI.get_uri().as_uri())
  922. rdfUI->URI = carla_strdup(uiURI);
  923. if (const char* const uiBinary = lilvUI.get_binary_uri().as_string())
  924. rdfUI->Binary = carla_strdup(lilv_uri_to_path(uiBinary));
  925. if (const char* const uiBundle = lilvUI.get_bundle_uri().as_string())
  926. rdfUI->Bundle = carla_strdup(lilv_uri_to_path(uiBundle));
  927. }
  928. // --------------------------------------
  929. // Set UI Features
  930. {
  931. Lilv::Nodes lilvFeatureNodes(lilvUI.get_supported_features());
  932. if (lilvFeatureNodes.size() > 0)
  933. {
  934. Lilv::Nodes lilvFeatureNodesR(lilvUI.get_required_features());
  935. rdfUI->FeatureCount = lilvFeatureNodes.size();
  936. rdfUI->Features = new LV2_RDF_Feature[rdfUI->FeatureCount];
  937. uint32_t x = 0;
  938. LILV_FOREACH(nodes, k, lilvFeatureNodes)
  939. {
  940. CARLA_ASSERT(x < rdfUI->FeatureCount);
  941. Lilv::Node lilvFeatureNode(lilvFeatureNodes.get(k));
  942. LV2_RDF_Feature* const rdfFeature = &rdfUI->Features[x++];
  943. rdfFeature->Type = lilvFeatureNodesR.contains(lilvFeatureNode) ? LV2_FEATURE_REQUIRED : LV2_FEATURE_OPTIONAL;
  944. if (const char* const featureURI = lilvFeatureNode.as_uri())
  945. rdfFeature->URI = carla_strdup(featureURI);
  946. }
  947. }
  948. }
  949. // --------------------------------------
  950. // Set UI Extensions
  951. {
  952. Lilv::Nodes lilvExtensionDataNodes(lilvUI.get_extension_data());
  953. if (lilvExtensionDataNodes.size() > 0)
  954. {
  955. rdfUI->ExtensionCount = lilvExtensionDataNodes.size();
  956. rdfUI->Extensions = new LV2_URI[rdfUI->ExtensionCount];
  957. uint32_t x = 0;
  958. LILV_FOREACH(nodes, k, lilvExtensionDataNodes)
  959. {
  960. CARLA_ASSERT(x < rdfUI->ExtensionCount);
  961. Lilv::Node lilvExtensionDataNode(lilvExtensionDataNodes.get(k));
  962. LV2_URI* const rdfExtension = &rdfUI->Extensions[x++];
  963. if (const char* const extURI = lilvExtensionDataNode.as_uri())
  964. *rdfExtension = carla_strdup(extURI);
  965. }
  966. }
  967. }
  968. }
  969. }
  970. }
  971. return rdfDescriptor;
  972. }
  973. // -------------------------------------------------
  974. // Check if we support a plugin port
  975. static inline
  976. bool is_lv2_port_supported(const LV2_Property types)
  977. {
  978. if (LV2_IS_PORT_CONTROL(types))
  979. return true;
  980. if (LV2_IS_PORT_AUDIO(types))
  981. return true;
  982. if (LV2_IS_PORT_ATOM_SEQUENCE(types))
  983. return true;
  984. if (LV2_IS_PORT_CV(types))
  985. return false; // TODO
  986. if (LV2_IS_PORT_EVENT(types))
  987. return true;
  988. if (LV2_IS_PORT_MIDI_LL(types))
  989. return true;
  990. return false;
  991. }
  992. // -------------------------------------------------
  993. // Check if we support a plugin feature
  994. static inline
  995. bool is_lv2_feature_supported(const LV2_URI uri)
  996. {
  997. CARLA_ASSERT(uri != nullptr);
  998. if (uri == nullptr)
  999. return false;
  1000. if (std::strcmp(uri, LV2_CORE__hardRTCapable) == 0)
  1001. return true;
  1002. if (std::strcmp(uri, LV2_CORE__inPlaceBroken) == 0)
  1003. return true;
  1004. if (std::strcmp(uri, LV2_CORE__isLive) == 0)
  1005. return true;
  1006. if (std::strcmp(uri, LV2_BUF_SIZE__boundedBlockLength) == 0)
  1007. return true;
  1008. if (std::strcmp(uri, LV2_BUF_SIZE__fixedBlockLength) == 0)
  1009. return true;
  1010. if (std::strcmp(uri, LV2_BUF_SIZE__powerOf2BlockLength) == 0)
  1011. return true;
  1012. if (std::strcmp(uri, LV2_EVENT_URI) == 0)
  1013. return true;
  1014. if (std::strcmp(uri, LV2_LOG__log) == 0)
  1015. return true;
  1016. if (std::strcmp(uri, LV2_OPTIONS__options) == 0)
  1017. return true;
  1018. if (std::strcmp(uri, LV2_PROGRAMS__Host) == 0)
  1019. return true;
  1020. if (std::strcmp(uri, LV2_RTSAFE_MEMORY_POOL__Pool) == 0)
  1021. return true;
  1022. if (std::strcmp(uri, LV2_STATE__makePath) == 0)
  1023. return true;
  1024. if (std::strcmp(uri, LV2_STATE__mapPath) == 0)
  1025. return true;
  1026. if (std::strcmp(uri, LV2_PORT_PROPS__supportsStrictBounds) == 0)
  1027. return true;
  1028. if (std::strcmp(uri, LV2_URI_MAP_URI) == 0)
  1029. return true;
  1030. if (std::strcmp(uri, LV2_URID__map) == 0)
  1031. return true;
  1032. if (std::strcmp(uri, LV2_URID__unmap) == 0)
  1033. return true;
  1034. if (std::strcmp(uri, LV2_WORKER__schedule) == 0)
  1035. return false; // TODO
  1036. return false;
  1037. }
  1038. // -------------------------------------------------
  1039. // Check if we support a plugin or UI feature
  1040. static inline
  1041. bool is_lv2_ui_feature_supported(const LV2_URI uri)
  1042. {
  1043. CARLA_ASSERT(uri != nullptr);
  1044. if (uri == nullptr)
  1045. return false;
  1046. if (is_lv2_feature_supported(uri))
  1047. return true;
  1048. if (std::strcmp(uri, LV2_DATA_ACCESS_URI) == 0)
  1049. return true;
  1050. if (std::strcmp(uri, LV2_INSTANCE_ACCESS_URI) == 0)
  1051. return true;
  1052. if (std::strcmp(uri, LV2_UI__idle) == 0)
  1053. return true;
  1054. if (std::strcmp(uri, LV2_UI__fixedSize) == 0)
  1055. return true;
  1056. if (std::strcmp(uri, LV2_UI__makeResident) == 0)
  1057. return true;
  1058. if (std::strcmp(uri, LV2_UI__noUserResize) == 0)
  1059. return true;
  1060. if (std::strcmp(uri, LV2_UI__parent) == 0)
  1061. return true;
  1062. if (std::strcmp(uri, LV2_UI__portMap) == 0)
  1063. return true;
  1064. if (std::strcmp(uri, LV2_UI__portSubscribe) == 0)
  1065. return false; // TODO
  1066. if (std::strcmp(uri, LV2_UI__resize) == 0)
  1067. return true;
  1068. if (std::strcmp(uri, LV2_UI__touch) == 0)
  1069. return false; // TODO
  1070. if (std::strcmp(uri, LV2_EXTERNAL_UI__Widget) == 0)
  1071. return true;
  1072. if (std::strcmp(uri, LV2_EXTERNAL_UI_DEPRECATED_URI) == 0)
  1073. return true;
  1074. return false;
  1075. }
  1076. // -------------------------------------------------
  1077. #endif // __CARLA_LV2_UTILS_HPP__