Add remaining files
[juce-lv2.git] / juce / source / src / audio / plugin_client / LV2 / lv2_rdf_gen.cpp
blob4cc88b14c811d171454843ed006a401edf92f3b3
1 /*
2 * LV2 ttl generator for JUCE Plugins
3 */
5 #include <fstream>
6 #include <iostream>
7 #include <stdint.h>
9 #include "JuceHeader.h"
10 #include "JucePluginCharacteristics.h"
12 #include JucePlugin_LV2Includes
14 // These are dummy values!
15 enum FakePlugCategory
17 kPlugCategUnknown,
18 kPlugCategEffect,
19 kPlugCategSynth,
20 kPlugCategAnalysis,
21 kPlugCategMastering,
22 kPlugCategSpacializer,
23 kPlugCategRoomFx,
24 kPlugSurroundFx,
25 kPlugCategRestoration,
26 kPlugCategOfflineProcess,
27 kPlugCategGenerator
30 String name_to_symbol(String Name)
32 String Symbol = Name.trimStart().trimEnd().replace(" ", "_").toLowerCase();
34 for (int i=0; i < Symbol.length(); i++) {
35 if (std::isalpha(Symbol[i]) || std::isdigit(Symbol[i]) || Symbol[i] == '_') {
36 // nothing
37 } else {
38 Symbol[i] == '_';
41 return Symbol;
44 String float_to_string(float value)
46 if (value < 0.0f || value > 1.0f) {
47 std::cerr << "WARNING - Parameter uses out-of-bounds default value -> " << value << std::endl;
49 String string(value);
50 if (!string.contains(".")) {
51 string += ".0";
53 return string;
56 String get_uri()
58 return String("urn:" JucePlugin_Manufacturer ":" JucePlugin_Name ":" JucePlugin_VersionString).replace(" ", "_");
61 String get_juce_ui_uri()
63 return String("urn:" JucePlugin_Manufacturer ":" JucePlugin_Name ":JUCE-Native-UI").replace(" ", "_");
66 String get_external_ui_uri()
68 return String("urn:" JucePlugin_Manufacturer ":" JucePlugin_Name ":JUCE-External-UI").replace(" ", "_");
71 String get_binary_name()
73 return String(JucePlugin_Name).replace(" ", "_");
76 String get_plugin_type()
78 String ptype;
80 switch (JucePlugin_VSTCategory) {
81 case kPlugCategSynth:
82 ptype += "lv2:InstrumentPlugin";
83 break;
84 case kPlugCategAnalysis:
85 ptype += "lv2:AnalyserPlugin";
86 break;
87 case kPlugCategMastering:
88 ptype += "lv2:DynamicsPlugin";
89 break;
90 case kPlugCategSpacializer:
91 ptype += "lv2:SpatialPlugin";
92 break;
93 case kPlugCategRoomFx:
94 ptype += "lv2:ModulatorPlugin";
95 break;
96 case kPlugCategRestoration:
97 ptype += "lv2:UtilityPlugin";
98 break;
99 case kPlugCategGenerator:
100 ptype += "lv2:GeneratorPlugin";
101 break;
104 if (ptype.isNotEmpty()) {
105 ptype += ", ";
108 ptype += "lv2:Plugin";
109 return ptype;
112 String get_manifest_ttl(String URI, String Binary)
114 String manifest;
115 manifest += "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n";
116 manifest += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
117 manifest += "\n";
118 manifest += "<" + URI + ">\n";
119 manifest += " a lv2:Plugin ;\n";
120 manifest += " lv2:binary <" + Binary + ".so> ;\n";
121 manifest += " rdfs:seeAlso <" + Binary +".ttl> .\n";
122 return manifest;
125 String get_plugin_ttl(String URI, String Binary)
127 JucePlugin_LV2ClassName* JucePlugin = new JucePlugin_LV2ClassName();
129 String plugin;
130 plugin += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
131 //plugin += "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n";
132 //plugin += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
133 plugin += "@prefix lv2: <http://lv2plug.in/ns/lv2core#> .\n";
134 plugin += "@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .\n";
135 plugin += "@prefix lv2ui: <http://lv2plug.in/ns/extensions/ui#> .\n";
136 plugin += "\n";
138 if (JucePlugin->hasEditor()) {
139 plugin += "<" + get_juce_ui_uri() + ">\n";
140 plugin += " a lv2ui:JUCEUI ;\n";
141 plugin += " lv2ui:binary <" + Binary + ".so> .\n";
142 plugin += "<" + get_external_ui_uri() + ">\n";
143 plugin += " a lv2ui:external ;\n";
144 plugin += " lv2ui:binary <" + Binary + ".so> .\n";
145 plugin += "\n";
148 plugin += "<" + URI + ">\n";
149 plugin += " a " + get_plugin_type() + " ;\n";
150 plugin += "\n";
152 uint32_t i, port_index = 0;
154 #if JucePlugin_WantsMidiInput
155 plugin += " lv2:port [\n";
156 plugin += " a lv2:InputPort, lv2ev:EventPort;\n";
157 plugin += " lv2ev:supportsEvent <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n";
158 plugin += " lv2:index " + String(port_index) + ";\n";
159 plugin += " lv2:symbol \"midi_in\";\n";
160 plugin += " lv2:name \"MIDI Input\";\n";
161 plugin += " ] ;\n";
162 port_index++;
163 #endif
165 #if JucePlugin_ProducesMidiOutput
166 plugin += " lv2:port [\n";
167 plugin += " a lv2:OutputPort, lv2ev:EventPort;\n";
168 plugin += " lv2ev:supportsEvent <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n";
169 plugin += " lv2:index " + String(port_index) + ";\n";
170 plugin += " lv2:symbol \"midi_out\";\n";
171 plugin += " lv2:name \"MIDI Output\";\n";
172 plugin += " ] ;\n";
173 port_index++;
174 #endif
176 #if JucePlugin_WantsMidiInput || JucePlugin_ProducesMidiOutput
177 plugin += "\n";
178 #endif
180 for (i=0; i<JucePlugin_MaxNumInputChannels; i++) {
181 if (i == 0) {
182 plugin += " lv2:port [\n";
183 } else {
184 plugin += " [\n";
187 plugin += " a lv2:InputPort, lv2:AudioPort;\n";
188 //plugin += " lv2:datatype lv2:float;\n";
189 plugin += " lv2:index " + String(port_index) + ";\n";
190 plugin += " lv2:symbol \"audio_in_" + String(i+1) + "\";\n";
191 plugin += " lv2:name \"Audio Input " + String(i+1) + "\";\n";
193 if (i == JucePlugin_MaxNumInputChannels-1) {
194 plugin += " ] ;\n";
195 } else {
196 plugin += " ],\n";
199 port_index++;
202 for (i=0; i<JucePlugin_MaxNumOutputChannels; i++) {
203 if (i == 0) {
204 plugin += " lv2:port [\n";
205 } else {
206 plugin += " [\n";
209 plugin += " a lv2:OutputPort, lv2:AudioPort;\n";
210 //plugin += " lv2:datatype lv2:float;\n";
211 plugin += " lv2:index " + String(port_index) + ";\n";
212 plugin += " lv2:symbol \"audio_out_" + String(i+1) + "\";\n";
213 plugin += " lv2:name \"Audio Output " + String(i+1) + "\";\n";
215 if (i == JucePlugin_MaxNumOutputChannels-1) {
216 plugin += " ] ;\n";
217 } else {
218 plugin += " ],\n";
221 port_index++;
224 #if JucePlugin_MaxNumInputChannels > 0 || JucePlugin_MaxNumOutputChannels > 0
225 plugin += "\n";
226 #endif
228 for (i=0; i < JucePlugin->getNumParameters(); i++) {
229 if (i == 0) {
230 plugin += " lv2:port [\n";
231 } else {
232 plugin += " [\n";
235 plugin += " a lv2:InputPort;\n";
236 plugin += " a lv2:ControlPort;\n";
237 //plugin += " lv2:datatype lv2:float;\n";
238 plugin += " lv2:index " + String(port_index) + ";\n";
239 plugin += " lv2:symbol \"" + name_to_symbol(JucePlugin->getParameterName(i)) + "\";\n";
240 plugin += " lv2:name \"" + JucePlugin->getParameterName(i) + "\";\n";
241 plugin += " lv2:default " + float_to_string(JucePlugin->getParameter(i)) + ";\n";
242 plugin += " lv2:minimum 0.0;\n";
243 plugin += " lv2:maximum 1.0;\n";
244 // TODO - units
246 if (i == JucePlugin_MaxNumOutputChannels-1) {
247 plugin += " ] ;\n";
248 } else {
249 plugin += " ],\n";
252 port_index++;
255 if (JucePlugin->getNumParameters() > 0) {
256 plugin += "\n";
259 plugin += " doap:name \"" + String(JucePlugin_Name) + "\" ;\n";
260 plugin += " doap:creator \"" + String(JucePlugin_Manufacturer) + "\" .\n";
262 delete JucePlugin;
263 return plugin;
266 int main(int argc, char *argv[])
268 String URI = get_uri();
269 String Binary = get_binary_name();
270 String BinaryTTL = Binary + ".ttl";
272 std::cout << "Writing manifest.ttl...";
273 std::fstream manifest("manifest.ttl", std::ios::out);
274 manifest << get_manifest_ttl(URI, Binary) << std::endl;
275 manifest.close();
276 std::cout << " done!" << std::endl;
278 std::cout << "Writing " << BinaryTTL;
279 std::fstream plugin(BinaryTTL.toUTF8(), std::ios::out);
280 plugin << get_plugin_ttl(URI, Binary) << std::endl;
281 plugin.close();
282 std::cout << " done!" << std::endl;
284 return 0;