From a74406332f24e0dfe9342f418ae81c2a242d8765 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 9 Aug 2008 03:27:51 +0000 Subject: Clean up port names and automatically generate nice/legal symbols for them. Write run wrapper to set plugin parameters values if they have changed since last cycle (bit of overhead...). Set port parameter ranges and default values. git-svn-id: http://svn.drobilla.net/lad/mda-lv2@1326 a436a847-0d15-0410-975c-d299462d15a1 --- lvz/audioeffectx.h | 47 ++++++++++++++++++++++++----------------------- lvz/gendata.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- lvz/wrapper.cpp | 46 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 114 insertions(+), 31 deletions(-) (limited to 'lvz') diff --git a/lvz/audioeffectx.h b/lvz/audioeffectx.h index 0030065..025c0cc 100644 --- a/lvz/audioeffectx.h +++ b/lvz/audioeffectx.h @@ -77,29 +77,30 @@ public: { } - const char* getURI() { return URI; } - const char* getUniqueID() { return uniqueID; } - float getSampleRate() { return sampleRate; } - uint32_t getNumInputs() { return numInputs; } - uint32_t getNumOutputs() { return numOutputs; } - uint32_t getNumParameters() { return numParams; } - - virtual void getParameterName(LvzInt32 index, char *label) = 0; - virtual bool getProductString(char* text) = 0; - - void canMono() {} - void canProcessReplacing() {} - void isSynth() {} - void process(float **inputs, float **outputs, uint32_t nframes) {} - void setBlockSize(uint32_t blockSize) {} - void setNumInputs(uint32_t num) { numInputs = num; } - void setNumOutputs(uint32_t num) { numOutputs = num;} - void setParameter(uint32_t index, float value) {} - void setSampleRate(float rate) { sampleRate = rate; } - void setUniqueID(const char* id) { uniqueID = id; } - void setURI(const char* uri) { URI = uri; } - void suspend() {} - void wantEvents() {} + virtual const char* getURI() { return URI; } + virtual const char* getUniqueID() { return uniqueID; } + virtual float getSampleRate() { return sampleRate; } + virtual uint32_t getNumInputs() { return numInputs; } + virtual uint32_t getNumOutputs() { return numOutputs; } + virtual uint32_t getNumParameters() { return numParams; } + + virtual float getParameter(LvzInt32 index) = 0; + virtual void getParameterName(LvzInt32 index, char *label) = 0; + virtual bool getProductString(char* text) = 0; + + virtual void suspend() {}; + virtual void canMono() {} + virtual void canProcessReplacing() {} + virtual void isSynth() {} + virtual void process(float **inputs, float **outputs, uint32_t nframes) {} + virtual void setBlockSize(uint32_t blockSize) {} + virtual void setNumInputs(uint32_t num) { numInputs = num; } + virtual void setNumOutputs(uint32_t num) { numOutputs = num;} + virtual void setParameter(uint32_t index, float value) {} + virtual void setSampleRate(float rate) { sampleRate = rate; } + virtual void setUniqueID(const char* id) { uniqueID = id; } + virtual void setURI(const char* uri) { URI = uri; } + virtual void wantEvents() {} protected: const char* uniqueID; diff --git a/lvz/gendata.cpp b/lvz/gendata.cpp index 57d1336..7efd739 100644 --- a/lvz/gendata.cpp +++ b/lvz/gendata.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,45 @@ struct Record { typedef std::list Manifest; Manifest manifest; + +string +symbolify(const char* name) +{ + string str(name); + + // Like This -> Like_This + for (size_t i=0; i < str.length(); ++i) + if (str[i] == ' ') + str[i] = '_'; + + str[0] = std::tolower(str[0]); + + // LikeThis -> like_this + for (size_t i=1; i < str.length(); ++i) + if (str[i] >= 'A' && str[i] <= 'Z' + && str[i-1] >= 'a' && str[i-1] <= 'z' + && ((i == str.length() - 1) || (str[i+1] <= 'a' && str[i+1] >= 'Z')) + && (!(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); + + // 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] = '_'; + ++i; + } else { + str = str.substr(0, i) + str.substr(i+1); + } + } + + return str; +} + void write_plugin(AudioEffectX* effect, const string& lib_file_name) @@ -76,18 +116,28 @@ write_plugin(AudioEffectX* effect, const string& lib_file_name) os << "\t\ta :InputPort, :ControlPort ;" << endl; os << "\t\t:index" << " " << idx << " ;" << endl; os << "\t\t:name \"" << name << "\" ;" << endl; + os << "\t\t:symbol \"" << symbolify(name) << "\" ;" << endl; + os << "\t\t:default " << effect->getParameter(i) << " ;" << endl; + os << "\t\t:minimum 0.0 ;" << endl; + os << "\t\t:maximum 1.0 ;" << endl; os << ((idx == num_ports - 1) ? "\t] ." : "\t] , [") << endl; } for (uint32_t i = 0; i < num_audio_ins; ++i, ++idx) { + snprintf(name, MAX_NAME_LENGTH, "\"in%d\"", i); os << "\t\ta :InputPort, :AudioPort ;" << endl; os << "\t\t:index" << " " << idx << " ;" << endl; + os << "\t\t:symbol \"in" << i+1 << "\" ;" << endl; + os << "\t\t:name \"Input " << i+1 << "\" ;" << endl; os << ((idx == num_ports - 1) ? "\t] ." : "\t] , [") << endl; } for (uint32_t i = 0; i < num_audio_outs; ++i, ++idx) { + snprintf(name, MAX_NAME_LENGTH, "\"out%d\"", i); os << "\t\ta :OutputPort, :AudioPort ;" << endl; - os << "\t\t:index" << " " << idx << " ;" << endl; + os << "\t\t:index " << idx << " ;" << endl; + os << "\t\t:symbol \"out" << i+1 << "\" ;" << endl; + os << "\t\t:name \"Output " << i+1 << "\" ;" << endl; os << ((idx == num_ports - 1) ? "\t] ." : "\t] , [") << endl; } diff --git a/lvz/wrapper.cpp b/lvz/wrapper.cpp index 14f73a9..0877053 100644 --- a/lvz/wrapper.cpp +++ b/lvz/wrapper.cpp @@ -37,8 +37,8 @@ extern "C" { typedef struct { PLUGIN_CLASS* effect; - float** inputs; - float** outputs; + float** buffers; + float* controls; } MDAPlugin; @@ -51,7 +51,10 @@ static void mda_cleanup(LV2_Handle instance) static void mda_connect_port(LV2_Handle instance, uint32_t port, void* data) { MDAPlugin* plugin = (MDAPlugin*)instance; - plugin->effect->setParameter(port, *(float*)data); + plugin->buffers[port] = (float*)data; + + if (data != NULL && port < plugin->effect->getNumParameters()) + plugin->controls[port] = *(float*)data; } @@ -67,8 +70,14 @@ mda_instantiate(const LV2_Descriptor* descriptor, MDAPlugin* plugin = (MDAPlugin*)malloc(sizeof(MDAPlugin)); plugin->effect = effect; - plugin->inputs = (float**)malloc(sizeof(float*) * effect->getNumInputs()); - plugin->outputs = (float**)malloc(sizeof(float*) * effect->getNumOutputs()); + + uint32_t num_ports = effect->getNumParameters() + + effect->getNumInputs() + + effect->getNumOutputs(); + + plugin->buffers = (float**)malloc(sizeof(float*) * num_ports); + plugin->controls = (float*)malloc(sizeof(float) * effect->getNumParameters()); + memset(plugin->controls, '\0', sizeof(float) * effect->getNumParameters()); return (LV2_Handle)plugin; } @@ -78,8 +87,31 @@ static void mda_run(LV2_Handle instance, uint32_t sample_count) { MDAPlugin* plugin = (MDAPlugin*)instance; - plugin->effect->process(plugin->inputs, plugin->outputs, sample_count); + + uint32_t num_params = plugin->effect->getNumParameters(); + uint32_t num_inputs = plugin->effect->getNumInputs(); + + for (uint32_t i = 0; i < num_params; ++i) { + float val = plugin->buffers[i][0]; + if (val != plugin->controls[i]) { + plugin->effect->setParameter(i, val); + plugin->controls[i] = val; + } + } + + plugin->effect->process(plugin->buffers + num_params, + plugin->buffers + num_params + num_inputs, + sample_count); } + + +static void +mda_deactivate(LV2_Handle instance) +{ + MDAPlugin* plugin = (MDAPlugin*)instance; + plugin->effect->suspend(); +} + /* Library */ @@ -94,7 +126,7 @@ init_descriptor() mda_descriptor->activate = NULL; mda_descriptor->cleanup = mda_cleanup; mda_descriptor->connect_port = mda_connect_port; - mda_descriptor->deactivate = NULL; + mda_descriptor->deactivate = mda_deactivate; mda_descriptor->instantiate = mda_instantiate; mda_descriptor->run = mda_run; } -- cgit v1.2.1