From 3086d97d74d43e1f6b8842eab04493fa706b2f4a Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 13:57:33 +0200 Subject: [PATCH 1/7] SwitchTrigger4 save/restore channel as LV2_State --- SwitchTrigger4/src/switchtrigger4.cpp | 76 ++++++++++++++++++- SwitchTrigger4/ttl/SwitchTrigger4.ttl | 19 +++++ .../ttl/modgui/stylesheet-switchtrigger4.css | 2 +- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index 78932fd..54f13fa 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -1,16 +1,26 @@ -#include + #include #include #include #include + #include +#include +#include +#include +#include /**********************************************************************************************************************************************************/ #define PLUGIN_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4" +#define CHANNEL_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4#channel>" + enum {IN, OUT_1, OUT_2, OUT_3, OUT_4, CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4}; /**********************************************************************************************************************************************************/ +static LV2_State_Status channel_save(LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle state_handle, uint32_t flags, const LV2_Feature* const* features); +static LV2_State_Status channel_restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle state_handle, uint32_t flags, const LV2_Feature* const* features); + class SwitchTrigger { public: @@ -34,6 +44,15 @@ class SwitchTrigger float *channel3; float *channel4; int channel; + + LV2_URID_Map *urid_map; + + struct urids + { + LV2_URID atom_Path; + LV2_URID switch_channel; + } URIDs; + }; /**********************************************************************************************************************************************************/ @@ -51,6 +70,40 @@ static const LV2_Descriptor Descriptor = { /**********************************************************************************************************************************************************/ +static LV2_State_Status channel_save(LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle state_handle, + uint32_t flags, const LV2_Feature* const* features) +{ + SwitchTrigger *plugin = (SwitchTrigger*)handle; + + void *body = &plugin->channel; + store(state_handle, plugin->URIDs.switch_channel, body, sizeof(int), + plugin->URIDs.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + return LV2_STATE_SUCCESS; +} + +/**********************************************************************************************************************************************************/ + +static LV2_State_Status channel_restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle state_handle, + uint32_t flags, const LV2_Feature* const* features) +{ + SwitchTrigger *plugin = (SwitchTrigger*)handle; + + size_t size; + uint32_t type; + uint32_t valflags; + + const void* value = retrieve( state_handle, plugin->URIDs.switch_channel, &size, &type, &valflags); + + if (value) + { + plugin->channel = *((int*)(&value)); + } + + return LV2_STATE_SUCCESS; +} +/**********************************************************************************************************************************************************/ + LV2_SYMBOL_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) { @@ -63,6 +116,20 @@ const LV2_Descriptor* lv2_descriptor(uint32_t index) LV2_Handle SwitchTrigger::instantiate(const LV2_Descriptor* descriptor, double samplerate, const char* bundle_path, const LV2_Feature* const* features) { SwitchTrigger *plugin = new SwitchTrigger(); + + for(int i=0; features[i]; i++) + { + if(!strcmp(features[i]->URI,LV2_URID__map)) + { + plugin->urid_map = (LV2_URID_Map *) features[i]->data; + if(plugin->urid_map) + { + plugin->URIDs.atom_Path = plugin->urid_map->map(plugin->urid_map->handle,LV2_ATOM__Path); + plugin->URIDs.switch_channel = plugin->urid_map->map(plugin->urid_map->handle,CHANNEL_URI); + } + } + } + return (LV2_Handle)plugin; } @@ -230,5 +297,12 @@ void SwitchTrigger::cleanup(LV2_Handle instance) const void* SwitchTrigger::extension_data(const char* uri) { + static const LV2_State_Interface state = { channel_save, channel_restore }; + + if (!strcmp(uri, LV2_STATE__interface)) + { + return &state; + } + return NULL; } diff --git a/SwitchTrigger4/ttl/SwitchTrigger4.ttl b/SwitchTrigger4/ttl/SwitchTrigger4.ttl index 4410b73..4d205c0 100644 --- a/SwitchTrigger4/ttl/SwitchTrigger4.ttl +++ b/SwitchTrigger4/ttl/SwitchTrigger4.ttl @@ -5,6 +5,17 @@ @prefix mod: . @prefix rdf: . @prefix rdfs: . +@prefix atom: . +@prefix urid: . +@prefix patch: . +@prefix state: . +@prefix units: . +@prefix plug: . + +plug:channel + a lv2:Parameter ; + rdfs:label "channel" ; + rdfs:range atom:Int . a lv2:Plugin, lv2:UtilityPlugin; @@ -32,6 +43,10 @@ The switch trigger was designed to use the MOD on stage. By addressing each cont footswitch, the musician can quickly access a desired chain of effects. """; +lv2:requiredFeature urid:map ; +lv2:optionalFeature state:loadDefaultState ; +lv2:extensionData state:interface ; + doap:license ; lv2:minorVersion 1; @@ -112,6 +127,10 @@ lv2:port lv2:minimum 0; lv2:maximum 1; ]; + +patch:writable plug:channel ; +patch:state plug:channel ; + mod:gui [ mod:resourcesDirectory ; mod:iconTemplate ; diff --git a/SwitchTrigger4/ttl/modgui/stylesheet-switchtrigger4.css b/SwitchTrigger4/ttl/modgui/stylesheet-switchtrigger4.css index bb1c03a..224729f 100644 --- a/SwitchTrigger4/ttl/modgui/stylesheet-switchtrigger4.css +++ b/SwitchTrigger4/ttl/modgui/stylesheet-switchtrigger4.css @@ -69,7 +69,7 @@ text-shadow:0 0 1px black; text-transform:uppercase; } -.mod-switchtrigger4 .mod-footswitch5 { +.mod-switchtrigger4 .mod-footswitch { background-image:url(/resources/footswitch.png{{{ns}}}); background-position:bottom center; background-repeat:no-repeat; From c0767984c2d55c6612ae3cb34337c8a491e73db8 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 14:22:37 +0200 Subject: [PATCH 2/7] fix typo's --- SwitchTrigger4/src/switchtrigger4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index 54f13fa..bb5a098 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -1,4 +1,4 @@ - #include +#include #include #include #include @@ -12,7 +12,7 @@ /**********************************************************************************************************************************************************/ #define PLUGIN_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4" -#define CHANNEL_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4#channel>" +#define CHANNEL_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4#channel" enum {IN, OUT_1, OUT_2, OUT_3, OUT_4, CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4}; From e168d81a53e8e270a37665d3fd06ecdfc43d3e08 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 16:45:27 +0200 Subject: [PATCH 3/7] make save/restore functions part of class --- SwitchTrigger4/src/switchtrigger4.cpp | 72 ++++++++++++++------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index bb5a098..82bf2a7 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -32,6 +32,8 @@ class SwitchTrigger static void connect_port(LV2_Handle instance, uint32_t port, void *data); static void run(LV2_Handle instance, uint32_t n_samples); static void cleanup(LV2_Handle instance); + static LV2_State_Status channel_save(LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle state_handle, uint32_t flags, const LV2_Feature* const* features); + static LV2_State_Status channel_restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle state_handle, uint32_t flags, const LV2_Feature* const* features); static const void* extension_data(const char* uri); int select_channel(); float *in; @@ -70,40 +72,6 @@ static const LV2_Descriptor Descriptor = { /**********************************************************************************************************************************************************/ -static LV2_State_Status channel_save(LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle state_handle, - uint32_t flags, const LV2_Feature* const* features) -{ - SwitchTrigger *plugin = (SwitchTrigger*)handle; - - void *body = &plugin->channel; - store(state_handle, plugin->URIDs.switch_channel, body, sizeof(int), - plugin->URIDs.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); - - return LV2_STATE_SUCCESS; -} - -/**********************************************************************************************************************************************************/ - -static LV2_State_Status channel_restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle state_handle, - uint32_t flags, const LV2_Feature* const* features) -{ - SwitchTrigger *plugin = (SwitchTrigger*)handle; - - size_t size; - uint32_t type; - uint32_t valflags; - - const void* value = retrieve( state_handle, plugin->URIDs.switch_channel, &size, &type, &valflags); - - if (value) - { - plugin->channel = *((int*)(&value)); - } - - return LV2_STATE_SUCCESS; -} -/**********************************************************************************************************************************************************/ - LV2_SYMBOL_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index) { @@ -126,6 +94,7 @@ LV2_Handle SwitchTrigger::instantiate(const LV2_Descriptor* descriptor, double s { plugin->URIDs.atom_Path = plugin->urid_map->map(plugin->urid_map->handle,LV2_ATOM__Path); plugin->URIDs.switch_channel = plugin->urid_map->map(plugin->urid_map->handle,CHANNEL_URI); + break; } } } @@ -295,6 +264,41 @@ void SwitchTrigger::cleanup(LV2_Handle instance) /**********************************************************************************************************************************************************/ +LV2_State_Status SwitchTrigger::channel_save(LV2_Handle handle, LV2_State_Store_Function store, LV2_State_Handle state_handle, + uint32_t flags, const LV2_Feature* const* features) +{ + SwitchTrigger *plugin = (SwitchTrigger*)handle; + + void *body = &plugin->channel; + store(state_handle, plugin->URIDs.switch_channel, body, sizeof(int), + plugin->URIDs.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + + return LV2_STATE_SUCCESS; +} + +/**********************************************************************************************************************************************************/ + +LV2_State_Status SwitchTrigger::channel_restore(LV2_Handle handle, LV2_State_Retrieve_Function retrieve, LV2_State_Handle state_handle, + uint32_t flags, const LV2_Feature* const* features) +{ + SwitchTrigger *plugin = (SwitchTrigger*)handle; + + size_t size; + uint32_t type; + uint32_t valflags; + + const void* value = retrieve( state_handle, plugin->URIDs.switch_channel, &size, &type, &valflags); + + if (value) + { + plugin->channel = *((int*)(&value)); + } + + return LV2_STATE_SUCCESS; +} + +/**********************************************************************************************************************************************************/ + const void* SwitchTrigger::extension_data(const char* uri) { static const LV2_State_Interface state = { channel_save, channel_restore }; From f691bf71309d5ce6ad38230ec62832cf5be02e9b Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 16:45:40 +0200 Subject: [PATCH 4/7] cleanup ttl --- SwitchTrigger4/ttl/SwitchTrigger4.ttl | 9 --------- 1 file changed, 9 deletions(-) diff --git a/SwitchTrigger4/ttl/SwitchTrigger4.ttl b/SwitchTrigger4/ttl/SwitchTrigger4.ttl index 4d205c0..5ec7b23 100644 --- a/SwitchTrigger4/ttl/SwitchTrigger4.ttl +++ b/SwitchTrigger4/ttl/SwitchTrigger4.ttl @@ -12,11 +12,6 @@ @prefix units: . @prefix plug: . -plug:channel - a lv2:Parameter ; - rdfs:label "channel" ; - rdfs:range atom:Int . - a lv2:Plugin, lv2:UtilityPlugin; @@ -44,7 +39,6 @@ footswitch, the musician can quickly access a desired chain of effects. """; lv2:requiredFeature urid:map ; -lv2:optionalFeature state:loadDefaultState ; lv2:extensionData state:interface ; doap:license ; @@ -128,9 +122,6 @@ lv2:port lv2:maximum 1; ]; -patch:writable plug:channel ; -patch:state plug:channel ; - mod:gui [ mod:resourcesDirectory ; mod:iconTemplate ; From 46fda1258b63401565c60fbf95d9dd9e78f7d700 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 16:54:58 +0200 Subject: [PATCH 5/7] switchtrigger4: change atom_Path to atom_Int, also check size and type on channel restore --- SwitchTrigger4/src/switchtrigger4.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index 82bf2a7..8eeb45a 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -51,7 +51,7 @@ class SwitchTrigger struct urids { - LV2_URID atom_Path; + LV2_URID atom_Int; LV2_URID switch_channel; } URIDs; @@ -92,7 +92,7 @@ LV2_Handle SwitchTrigger::instantiate(const LV2_Descriptor* descriptor, double s plugin->urid_map = (LV2_URID_Map *) features[i]->data; if(plugin->urid_map) { - plugin->URIDs.atom_Path = plugin->urid_map->map(plugin->urid_map->handle,LV2_ATOM__Path); + plugin->URIDs.atom_Int = plugin->urid_map->map(plugin->urid_map->handle,LV2_ATOM__Int); plugin->URIDs.switch_channel = plugin->urid_map->map(plugin->urid_map->handle,CHANNEL_URI); break; } @@ -271,7 +271,7 @@ LV2_State_Status SwitchTrigger::channel_save(LV2_Handle handle, LV2_State_Store_ void *body = &plugin->channel; store(state_handle, plugin->URIDs.switch_channel, body, sizeof(int), - plugin->URIDs.atom_Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); + plugin->URIDs.atom_Int, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE); return LV2_STATE_SUCCESS; } @@ -289,7 +289,7 @@ LV2_State_Status SwitchTrigger::channel_restore(LV2_Handle handle, LV2_State_Ret const void* value = retrieve( state_handle, plugin->URIDs.switch_channel, &size, &type, &valflags); - if (value) + if ((value) && (size == sizeof(int)) && (type == plugin->URIDs.switch_channel)) { plugin->channel = *((int*)(&value)); } From 40c5e636f30ade56cc6d63fd1e8eba882bdbdc1d Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 17:12:22 +0200 Subject: [PATCH 6/7] Switchtrigger: initialize channel, cleanup run --- SwitchTrigger4/src/switchtrigger4.cpp | 66 ++++++++------------------- 1 file changed, 18 insertions(+), 48 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index 8eeb45a..2f5d10e 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -99,6 +99,8 @@ LV2_Handle SwitchTrigger::instantiate(const LV2_Descriptor* descriptor, double s } } + plugin->channel = 0; + return (LV2_Handle)plugin; } @@ -193,63 +195,31 @@ void SwitchTrigger::run(LV2_Handle instance, uint32_t n_samples) switch (channel) { case 0: - for ( uint32_t i = 0; i < n_samples; i++) - { - *out_1 = *in; - *out_2=0; - *out_3=0; - *out_4=0; - in++; - out_1++; - out_2++; - out_3++; - out_4++; - } + memcpy(out_1, in, sizeof(float)*n_samples); + memset(out_2, 0, sizeof(float)*n_samples); + memset(out_3, 0, sizeof(float)*n_samples); + memset(out_4, 0, sizeof(float)*n_samples); break; case 1: - for (uint32_t i = 0; i < n_samples; i++) - { - *out_1=0; - *out_2 = *in; - *out_3=0; - *out_4=0; - in++; - out_1++; - out_2++; - out_3++; - out_4++; - } + memcpy(out_2, in, sizeof(float)*n_samples); + memset(out_1, 0, sizeof(float)*n_samples); + memset(out_3, 0, sizeof(float)*n_samples); + memset(out_4, 0, sizeof(float)*n_samples); break; case 2: - for (uint32_t i = 0; i < n_samples; i++) - { - *out_1=0; - *out_2=0; - *out_3 = *in; - *out_4=0; - in++; - out_1++; - out_2++; - out_3++; - out_4++; - } + memcpy(out_3, in, sizeof(float)*n_samples); + memset(out_1, 0, sizeof(float)*n_samples); + memset(out_2, 0, sizeof(float)*n_samples); + memset(out_4, 0, sizeof(float)*n_samples); break; case 3: - for (uint32_t i = 0; i < n_samples; i++) - { - *out_1=0; - *out_2=0; - *out_3=0; - *out_4 = *in; - in++; - out_1++; - out_2++; - out_3++; - out_4++; - } + memcpy(out_4, in, sizeof(float)*n_samples); + memset(out_1, 0, sizeof(float)*n_samples); + memset(out_2, 0, sizeof(float)*n_samples); + memset(out_3, 0, sizeof(float)*n_samples); break; } From 48627197e409a70a9b3aa10f37705400a45e2522 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 19 May 2022 17:18:04 +0200 Subject: [PATCH 7/7] Switchtrigger: add channel output control --- SwitchTrigger4/src/switchtrigger4.cpp | 9 +++++++-- SwitchTrigger4/ttl/SwitchTrigger4.ttl | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/SwitchTrigger4/src/switchtrigger4.cpp b/SwitchTrigger4/src/switchtrigger4.cpp index 2f5d10e..238089b 100644 --- a/SwitchTrigger4/src/switchtrigger4.cpp +++ b/SwitchTrigger4/src/switchtrigger4.cpp @@ -14,7 +14,7 @@ #define PLUGIN_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4" #define CHANNEL_URI "http://moddevices.com/plugins/mod-devel/SwitchTrigger4#channel" -enum {IN, OUT_1, OUT_2, OUT_3, OUT_4, CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4}; +enum {IN, OUT_1, OUT_2, OUT_3, OUT_4, CHANNEL1, CHANNEL2, CHANNEL3, CHANNEL4, CHANNEL_OUTPUT}; /**********************************************************************************************************************************************************/ @@ -45,6 +45,7 @@ class SwitchTrigger float *channel2; float *channel3; float *channel4; + float *channel_output; int channel; LV2_URID_Map *urid_map; @@ -154,6 +155,9 @@ void SwitchTrigger::connect_port(LV2_Handle instance, uint32_t port, void *data) case CHANNEL4: plugin->channel4 = (float*) data; break; + case CHANNEL_OUTPUT: + plugin->channel_output = (float*) data; + break; } } @@ -221,8 +225,9 @@ void SwitchTrigger::run(LV2_Handle instance, uint32_t n_samples) memset(out_2, 0, sizeof(float)*n_samples); memset(out_3, 0, sizeof(float)*n_samples); break; - } + + plugin->channel_output = (float*)&channel; } /**********************************************************************************************************************************************************/ diff --git a/SwitchTrigger4/ttl/SwitchTrigger4.ttl b/SwitchTrigger4/ttl/SwitchTrigger4.ttl index 5ec7b23..37a209d 100644 --- a/SwitchTrigger4/ttl/SwitchTrigger4.ttl +++ b/SwitchTrigger4/ttl/SwitchTrigger4.ttl @@ -120,6 +120,13 @@ lv2:port lv2:default 0; lv2:minimum 0; lv2:maximum 1; +], +[ + a lv2:ControlPort, lv2:OutputPort; + lv2:index 9; + lv2:symbol "channelOut"; + lv2:minimum 0; + lv2:maximum 3; ]; mod:gui [