From 337a13119180bf7fa6996d6c23962c31ea53db54 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 21 Apr 2012 22:35:41 +0000 Subject: MDA-LV2 1.0.0 git-svn-id: http://svn.drobilla.net/lad/tags/mda-lv2-1.0.0@4223 a436a847-0d15-0410-975c-d299462d15a1 --- lvz/audioeffectx.h | 41 ++++++++++++++++++++++++++--------------- lvz/gendata.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++----------- lvz/wrapper.cpp | 24 +++++++++++++++++++----- 3 files changed, 87 insertions(+), 31 deletions(-) (limited to 'lvz') diff --git a/lvz/audioeffectx.h b/lvz/audioeffectx.h index e4a7fb9..296bb06 100644 --- a/lvz/audioeffectx.h +++ b/lvz/audioeffectx.h @@ -22,6 +22,9 @@ #include #include +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" + class AudioEffect; typedef int (*audioMasterCallback)(int, int ver, int, int, int, int); @@ -69,12 +72,12 @@ public: virtual void masterIdle() {} }; - class AudioEffectX : public AudioEffect { public: AudioEffectX(audioMasterCallback audioMaster, int32_t progs, int32_t params) : URI("NIL") , uniqueID("NIL") + , eventInput(NULL) , sampleRate(44100) , curProgram(0) , numInputs(0) @@ -84,9 +87,12 @@ public: { } - virtual void process (float **inputs, float **outputs, int32_t nframes) = 0; + virtual void process (float **inputs, float **outputs, int32_t nframes) {} virtual void processReplacing(float **inputs, float **outputs, int32_t nframes) = 0; + void setMidiEventType(LV2_URID urid) { midiEventType = urid; } + void setEventInput(const LV2_Atom_Sequence* seq) { eventInput = seq; } + virtual int32_t processEvents(LvzEvents* ev) { return 0; } virtual const char* getURI() { return URI; } @@ -95,15 +101,18 @@ public: virtual int32_t getNumInputs() { return numInputs; } virtual int32_t getNumOutputs() { return numOutputs; } virtual int32_t getNumParameters() { return numParams; } + virtual int32_t getNumPrograms() { return numPrograms; } virtual void getParameterName(int32_t index, char *label) = 0; virtual bool getProductString(char* text) = 0; + virtual void getProgramName(char *name) { name[0] = '\0'; } - virtual bool canHostDo(const char* act) { return false; } - virtual void canMono() {} - virtual void canProcessReplacing() {} - virtual void isSynth() {} - virtual void wantEvents() {} + virtual int32_t canDo(const char* text) { return false; } + virtual bool canHostDo(const char* act) { return false; } + virtual void canMono() {} + virtual void canProcessReplacing() {} + virtual void isSynth() {} + virtual void wantEvents() {} virtual void setBlockSize(int32_t size) {} virtual void setNumInputs(int32_t num) { numInputs = num; } @@ -121,14 +130,16 @@ public: } protected: - const char* URI; - const char* uniqueID; - float sampleRate; - int32_t curProgram; - int32_t numInputs; - int32_t numOutputs; - int32_t numParams; - int32_t numPrograms; + const char* URI; + const char* uniqueID; + const LV2_Atom_Sequence* eventInput; + LV2_URID midiEventType; + float sampleRate; + int32_t curProgram; + int32_t numInputs; + int32_t numOutputs; + int32_t numParams; + int32_t numPrograms; }; #endif // LVZ_AUDIOEFFECTX_H diff --git a/lvz/gendata.cpp b/lvz/gendata.cpp index 233e5c3..cc4cc49 100644 --- a/lvz/gendata.cpp +++ b/lvz/gendata.cpp @@ -33,7 +33,6 @@ using namespace std; #define MAX_NAME_LENGTH 1024 char name_buf[MAX_NAME_LENGTH]; - struct Record { Record(const string& n) : base_name(n) {} string base_name; @@ -41,20 +40,18 @@ struct Record { UIs uis; }; - typedef std::map Manifest; Manifest manifest; - string -symbolify(const char* name) +symbolify(const char* name, char space_char='_') { string str(name); // Like This -> Like_This for (size_t i=0; i < str.length(); ++i) if (str[i] == ' ') - str[i] = '_'; + str[i] = space_char; str[0] = std::tolower(str[0]); @@ -66,15 +63,15 @@ symbolify(const char* name) && (!(str[i-1] == 'd' && str[i] == 'B')) && (!(str[i-1] == 'F' && str[i] == 'X')) && (!(str[i-1] == 'D' && str[i] == 'C'))) - str = str.substr(0, i) + '_' + str.substr(i); + str = str.substr(0, i) + space_char + str.substr(i); // To lowercase, and skip invalids for (size_t i=1; i < str.length(); ) { if (std::isalpha(str[i]) || std::isdigit(str[i])) { str[i] = std::tolower(str[i]); ++i; - } else if (str[i-1] != '_') { - str[i] = '_'; + } else if (str[i-1] != space_char) { + str[i] = space_char; ++i; } else { str = str.substr(0, i) + str.substr(i+1); @@ -84,7 +81,6 @@ symbolify(const char* name) return str; } - void write_plugin(AudioEffectX* effect, const string& lib_file_name) { @@ -150,8 +146,44 @@ write_plugin(AudioEffectX* effect, const string& lib_file_name) } else { manifest.insert(std::make_pair(effect->getURI(), Record(base_name))); } -} + if (effect->getNumPrograms() > 1) { + std::string preset_file = base_name + "-presets.ttl"; + + fstream pos(preset_file.c_str(), ios::out); + pos << "@prefix lv2: ." << endl; + pos << "@prefix pset: ." << endl; + pos << "@prefix rdfs: ." << endl << endl; + for (int32_t i = 0; i < effect->getNumPrograms(); ++i) { + effect->setProgram(i); + effect->getProgramName(name_buf); + + std::string preset_uri = string(effect->getURI()) + + "#pset-" + symbolify(name_buf, '-'); + + // Write wanifest entry + std::cout << "<" << preset_uri << ">" + << "\n\ta pset:Preset ;\n\tlv2:appliesTo <" + << effect->getURI() << "> ;\n\t" + << "rdfs:seeAlso <" << preset_file << "> .\n" << std::endl; + + // Write preset file + pos << "<" << preset_uri << ">" + << "\n\ta pset:Preset ;\n\tlv2:appliesTo <" + << effect->getURI() << "> ;\n\t" + << "rdfs:label \"" << name_buf << "\""; + for (uint32_t i = 0; i < num_params; ++i) { + effect->getParameterName(i, name_buf); + pos << " ;\n\tlv2:port [" << endl; + pos << "\t\tlv2:symbol \"" << symbolify(name_buf) << "\" ;" << endl; + pos << "\t\tpset:value " << effect->getParameter(i) << " ;" << endl; + pos << "\t]"; + } + pos << " .\n" << endl; + } + pos.close(); + } +} void write_manifest(ostream& os) @@ -170,7 +202,6 @@ write_manifest(ostream& os) } } - int main(int argc, char** argv) { diff --git a/lvz/wrapper.cpp b/lvz/wrapper.cpp index b8b9624..6d265a7 100644 --- a/lvz/wrapper.cpp +++ b/lvz/wrapper.cpp @@ -32,6 +32,9 @@ #include #include "audioeffectx.h" #include "lv2.h" +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/midi/midi.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" #include PLUGIN_HEADER extern "C" { @@ -61,17 +64,19 @@ lvz_cleanup(LV2_Handle instance) static void lvz_connect_port(LV2_Handle instance, uint32_t port, void* data) { - LVZPlugin* plugin = (LVZPlugin*)instance; - - uint32_t num_params = plugin->effect->getNumParameters(); - uint32_t num_inputs = plugin->effect->getNumInputs(); + LVZPlugin* plugin = (LVZPlugin*)instance; + const uint32_t num_params = plugin->effect->getNumParameters(); + const uint32_t num_inputs = plugin->effect->getNumInputs(); + const uint32_t num_outputs = plugin->effect->getNumOutputs(); if (port < num_params) { plugin->control_buffers[port] = (float*)data; } else if (port < num_params + num_inputs) { plugin->inputs[port - num_params] = (float*)data; - } else { + } else if (port < num_params + num_inputs + num_outputs) { plugin->outputs[port - num_params - num_inputs] = (float*)data; + } else if (port == num_params + num_inputs + num_outputs) { + plugin->effect->setEventInput((LV2_Atom_Sequence*)data); } } @@ -98,6 +103,15 @@ lvz_instantiate(const LV2_Descriptor* descriptor, LVZPlugin* plugin = (LVZPlugin*)malloc(sizeof(LVZPlugin)); plugin->effect = effect; + for (int i = 0; features[i]; ++i) { + if (!strcmp(features[i]->URI, LV2_URID__map)) { + LV2_URID_Map* map = (LV2_URID_Map*)features[i]->data; + plugin->effect->setMidiEventType( + map->map(map->handle, LV2_MIDI__MidiEvent)); + break; + } + } + if (num_params > 0) { plugin->controls = (float*)malloc(sizeof(float) * num_params); plugin->control_buffers = (float**)malloc(sizeof(float*) * num_params); -- cgit v1.2.1