commit 195ec62d55c7998dbe59a7277ff0ba854331f336
parent 5d040f1a2c0542d78b32f6d0df9a2386187478eb
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Thu, 15 Jun 2017 13:23:06 -0400
LV2/VST Automation WIP
Diffstat:
5 files changed, 192 insertions(+), 124 deletions(-)
diff --git a/src/Misc/Master.cpp b/src/Misc/Master.cpp
@@ -110,6 +110,50 @@ static const Ports watchPorts = {
rEnd},
};
+static const Ports automate_ports = {
+ {"slot#16/learn-binding:s", rDoc("Create binding for automation path with midi-learn"), 0,
+ rBegin;
+ m->automate.createBinding(rtosc_argument(msg, 0).i,
+ rtosc_argument(msg, 1).s,
+ rtosc_argument(msg, 2).T);
+ rEnd},
+ {"slot#16/create-binding:s", rDoc("Create binding for automation path"), 0,
+ rBegin;
+ m->automate.createBinding(rtosc_argument(msg, 0).i,
+ rtosc_argument(msg, 1).s,
+ rtosc_argument(msg, 2).T);
+ rEnd},
+ {"slot#16/value::f", rProp(parameter) rMap(default, 0.5) rDoc("Access current value in slot 'i' (0..1)"), 0,
+ rBegin;
+ rEnd},
+
+ {"slot#16/name::s", rProp(parameter) rDoc("Access name of automation slot"), 0,
+ rBegin;
+ rEnd},
+ {"slot#16/midi-cc::i", rProp(parameter) rMap(default, -1) rDoc("Access assigned midi CC slot") , 0,
+ rBegin;
+ rEnd},
+ {"slot#16/active::T:F", rProp(parameter) rMap(default, F) rDoc("If Slot is enabled"), 0,
+ rBegin;
+ rEnd},
+ {"slot#16/learning::T:F", rProp(parameter) rMap(default, F) rDoc("If slot is trying to find a midi learn binding"), 0,
+ rBegin;
+ rEnd},
+
+ {"slot#16/param#4/used:", 0, 0,
+ rBegin;
+ rEnd},
+ {"slot#16/param#4/active:", 0, 0,
+ rBegin;
+ rEnd},
+ {"slot#16/param#4/path:", 0, 0,
+ rBegin;
+ rEnd},
+ {"slot#16/param#4/mapping:", 0, 0,
+ rBegin;
+ rEnd},
+};
+
extern const Ports bankPorts;
static const Ports master_ports = {
rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."),
@@ -233,13 +277,11 @@ static const Ports master_ports = {
[](const char *,RtData &d) {
Master *M = (Master*)d.obj;
M->frozenState = false;}},
- {"midi-learn/", 0, &rtosc::MidiMapperRT::ports,
+ {"automate/", 0, &automate_ports,
[](const char *msg, RtData &d) {
- Master *M = (Master*)d.obj;
SNIP;
- printf("residue message = <%s>\n", msg);
- d.obj = &M->midi;
- rtosc::MidiMapperRT::ports.dispatch(msg,d);}},
+ automate_ports.dispatch(msg, d);
+ }},
{"close-ui:", rDoc("Request to close any connection named \"GUI\""), 0,
[](const char *, RtData &d) {
d.reply("/close-ui", "");}},
@@ -367,14 +409,15 @@ Master::Master(const SYNTH_T &synth_, Config* config)
:HDDRecorder(synth_), time(synth_), ctl(synth_, &time),
microtonal(config->cfg.GzipCompression), bank(config),
frozenState(false), pendingMemory(false),
+ automate(16,4,8),
synth(synth_), gzip_compression(config->cfg.GzipCompression)
{
bToU = NULL;
uToB = NULL;
//Setup MIDI
- midi.frontend = [this](const char *msg) {bToU->raw_write(msg);};
- midi.backend = [this](const char *msg) {applyOscEvent(msg);};
+ //midi.frontend = [this](const char *msg) {bToU->raw_write(msg);};
+ //midi.backend = [this](const char *msg) {applyOscEvent(msg);};
memory = new AllocatorClass();
swaplr = 0;
@@ -524,7 +567,7 @@ void Master::setController(char chan, int type, int par)
if(frozenState)
return;
//TODO add chan back
- midi.handleCC(type,par);
+ //midi.handleCC(type,par);
if((type == C_dataentryhi) || (type == C_dataentrylo)
|| (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan)
ctl.setparameternumber(type, par);
diff --git a/src/Misc/Master.h b/src/Misc/Master.h
@@ -16,7 +16,7 @@
#define MASTER_H
#include "../globals.h"
#include "Microtonal.h"
-#include <rtosc/miditable.h>
+#include <rtosc/automations.h>
#include <rtosc/ports.h>
#include "Time.h"
@@ -171,7 +171,7 @@ class Master
WatchManager watcher;
//Midi Learn
- rtosc::MidiMapperRT midi;
+ rtosc::AutomationMgr automate;
bool frozenState;//read-only parameters for threadsafe actions
Allocator *memory;
diff --git a/src/Misc/MiddleWare.cpp b/src/Misc/MiddleWare.cpp
@@ -227,50 +227,50 @@ void preparePadSynth(string path, PADnoteParameters *p, rtosc::RtData &d)
* MIDI Serialization *
* *
******************************************************************************/
-void saveMidiLearn(XMLwrapper &xml, const rtosc::MidiMappernRT &midi)
-{
- xml.beginbranch("midi-learn");
- for(auto value:midi.inv_map) {
- XmlNode binding("midi-binding");
- auto biject = std::get<3>(value.second);
- binding["osc-path"] = value.first;
- binding["coarse-CC"] = to_s(std::get<1>(value.second));
- binding["fine-CC"] = to_s(std::get<2>(value.second));
- binding["type"] = "i";
- binding["minimum"] = to_s(biject.min);
- binding["maximum"] = to_s(biject.max);
- xml.add(binding);
- }
- xml.endbranch();
-}
-
-void loadMidiLearn(XMLwrapper &xml, rtosc::MidiMappernRT &midi)
-{
- using rtosc::Port;
- if(xml.enterbranch("midi-learn")) {
- auto nodes = xml.getBranch();
-
- //TODO clear mapper
-
- for(auto node:nodes) {
- if(node.name != "midi-binding" ||
- !node.has("osc-path") ||
- !node.has("coarse-CC"))
- continue;
- const string path = node["osc-path"];
- const int CC = atoi(node["coarse-CC"].c_str());
- const Port *p = Master::ports.apropos(path.c_str());
- if(p) {
- printf("loading midi port...\n");
- midi.addNewMapper(CC, *p, path);
- } else {
- printf("unknown midi bindable <%s>\n", path.c_str());
- }
- }
- xml.exitbranch();
- } else
- printf("cannot find 'midi-learn' branch...\n");
-}
+//void saveMidiLearn(XMLwrapper &xml, const rtosc::MidiMappernRT &midi)
+//{
+// xml.beginbranch("midi-learn");
+// for(auto value:midi.inv_map) {
+// XmlNode binding("midi-binding");
+// auto biject = std::get<3>(value.second);
+// binding["osc-path"] = value.first;
+// binding["coarse-CC"] = to_s(std::get<1>(value.second));
+// binding["fine-CC"] = to_s(std::get<2>(value.second));
+// binding["type"] = "i";
+// binding["minimum"] = to_s(biject.min);
+// binding["maximum"] = to_s(biject.max);
+// xml.add(binding);
+// }
+// xml.endbranch();
+//}
+//
+//void loadMidiLearn(XMLwrapper &xml, rtosc::MidiMappernRT &midi)
+//{
+// using rtosc::Port;
+// if(xml.enterbranch("midi-learn")) {
+// auto nodes = xml.getBranch();
+//
+// //TODO clear mapper
+//
+// for(auto node:nodes) {
+// if(node.name != "midi-binding" ||
+// !node.has("osc-path") ||
+// !node.has("coarse-CC"))
+// continue;
+// const string path = node["osc-path"];
+// const int CC = atoi(node["coarse-CC"].c_str());
+// const Port *p = Master::ports.apropos(path.c_str());
+// if(p) {
+// printf("loading midi port...\n");
+// midi.addNewMapper(CC, *p, path);
+// } else {
+// printf("unknown midi bindable <%s>\n", path.c_str());
+// }
+// }
+// xml.exitbranch();
+// } else
+// printf("cannot find 'midi-learn' branch...\n");
+//}
/******************************************************************************
* Non-RealTime Object Store *
@@ -747,7 +747,7 @@ public:
rtosc::UndoHistory undo;
//MIDI Learn
- rtosc::MidiMappernRT midi_mapper;
+ //rtosc::MidiMappernRT midi_mapper;
//Link To the Realtime
rtosc::ThreadLink *bToU;
@@ -1202,24 +1202,24 @@ static rtosc::Ports middwareSnoopPorts = {
impl.kitEnable(msg);
d.forward();
rEnd},
- {"save_xlz:s", 0, 0,
- rBegin;
- const char *file = rtosc_argument(msg, 0).s;
- XMLwrapper xml;
- saveMidiLearn(xml, impl.midi_mapper);
- xml.saveXMLfile(file, impl.master->gzip_compression);
- rEnd},
- {"load_xlz:s", 0, 0,
- rBegin;
- const char *file = rtosc_argument(msg, 0).s;
- XMLwrapper xml;
- xml.loadXMLfile(file);
- loadMidiLearn(xml, impl.midi_mapper);
- rEnd},
- {"clear_xlz:", 0, 0,
- rBegin;
- impl.midi_mapper.clear();
- rEnd},
+ //{"save_xlz:s", 0, 0,
+ // rBegin;
+ // const char *file = rtosc_argument(msg, 0).s;
+ // XMLwrapper xml;
+ // saveMidiLearn(xml, impl.midi_mapper);
+ // xml.saveXMLfile(file, impl.master->gzip_compression);
+ // rEnd},
+ //{"load_xlz:s", 0, 0,
+ // rBegin;
+ // const char *file = rtosc_argument(msg, 0).s;
+ // XMLwrapper xml;
+ // xml.loadXMLfile(file);
+ // loadMidiLearn(xml, impl.midi_mapper);
+ // rEnd},
+ //{"clear_xlz:", 0, 0,
+ // rBegin;
+ // impl.midi_mapper.clear();
+ // rEnd},
//scale file stuff
{"load_xsz:s", 0, 0,
rBegin;
@@ -1391,51 +1391,51 @@ static rtosc::Ports middwareSnoopPorts = {
impl.undo.seekHistory(+1);
rEnd},
//port to observe the midi mappings
- {"midi-learn-values:", 0, 0,
- rBegin;
- auto &midi = impl.midi_mapper;
- auto key = keys(midi.inv_map);
- //cc-id, path, min, max
-#define MAX_MIDI 32
- rtosc_arg_t args[MAX_MIDI*4];
- char argt[MAX_MIDI*4+1] = {0};
- int j=0;
- for(unsigned i=0; i<key.size() && i<MAX_MIDI; ++i) {
- auto val = midi.inv_map[key[i]];
- if(std::get<1>(val) == -1)
- continue;
- argt[4*j+0] = 'i';
- args[4*j+0].i = std::get<1>(val);
- argt[4*j+1] = 's';
- args[4*j+1].s = key[i].c_str();
- argt[4*j+2] = 'i';
- args[4*j+2].i = 0;
- argt[4*j+3] = 'i';
- args[4*j+3].i = 127;
- j++;
-
- }
- d.replyArray(d.loc, argt, args);
-#undef MAX_MIDI
- rEnd},
- {"learn:s", 0, 0,
- rBegin;
- string addr = rtosc_argument(msg, 0).s;
- auto &midi = impl.midi_mapper;
- auto map = midi.getMidiMappingStrings();
- if(map.find(addr) != map.end())
- midi.map(addr.c_str(), false);
- else
- midi.map(addr.c_str(), true);
- rEnd},
- {"unlearn:s", 0, 0,
- rBegin;
- string addr = rtosc_argument(msg, 0).s;
- auto &midi = impl.midi_mapper;
- auto map = midi.getMidiMappingStrings();
- midi.unMap(addr.c_str(), false);
- midi.unMap(addr.c_str(), true);
- rEnd},
+ //{"midi-learn-values:", 0, 0,
+ // rBegin;
+ // auto &midi = impl.midi_mapper;
+ // auto key = keys(midi.inv_map);
+ // //cc-id, path, min, max
+//#define MAX_MIDI 32
+ // rtosc_arg_t args[MAX_MIDI*4];
+ // char argt[MAX_MIDI*4+1] = {0};
+ // int j=0;
+ // for(unsigned i=0; i<key.size() && i<MAX_MIDI; ++i) {
+ // auto val = midi.inv_map[key[i]];
+ // if(std::get<1>(val) == -1)
+ // continue;
+ // argt[4*j+0] = 'i';
+ // args[4*j+0].i = std::get<1>(val);
+ // argt[4*j+1] = 's';
+ // args[4*j+1].s = key[i].c_str();
+ // argt[4*j+2] = 'i';
+ // args[4*j+2].i = 0;
+ // argt[4*j+3] = 'i';
+ // args[4*j+3].i = 127;
+ // j++;
+
+ // }
+ // d.replyArray(d.loc, argt, args);
+//#undef MAX_MIDI
+ // rEnd},
+ //{"learn:s", 0, 0,
+ // rBegin;
+ // string addr = rtosc_argument(msg, 0).s;
+ // auto &midi = impl.midi_mapper;
+ // auto map = midi.getMidiMappingStrings();
+ // if(map.find(addr) != map.end())
+ // midi.map(addr.c_str(), false);
+ // else
+ // midi.map(addr.c_str(), true);
+ // rEnd},
+ //{"unlearn:s", 0, 0,
+ // rBegin;
+ // string addr = rtosc_argument(msg, 0).s;
+ // auto &midi = impl.midi_mapper;
+ // auto map = midi.getMidiMappingStrings();
+ // midi.unMap(addr.c_str(), false);
+ // midi.unMap(addr.c_str(), true);
+ // rEnd},
//drop this message into the abyss
{"ui/title:", 0, 0, [](const char *msg, RtData &d) {}},
{"quit:", 0, 0, [](const char *, RtData&) {Pexitprogram = 1;}},
@@ -1482,10 +1482,10 @@ static rtosc::Ports middlewareReplyPorts = {
if(impl.recording_undo)
impl.undo.recordEvent(msg);
rEnd},
- {"midi-use-CC:i", 0, 0,
- rBegin;
- impl.midi_mapper.useFreeID(rtosc_argument(msg, 0).i);
- rEnd},
+ //{"midi-use-CC:i", 0, 0,
+ // rBegin;
+ // impl.midi_mapper.useFreeID(rtosc_argument(msg, 0).i);
+ // rEnd},
{"broadcast:", 0, 0, rBegin; impl.broadcast = true; rEnd},
{"forward:", 0, 0, rBegin; impl.forward = true; rEnd},
};
@@ -1510,8 +1510,8 @@ MiddleWareImpl::MiddleWareImpl(MiddleWare *mw, SYNTH_T synth_,
{
bToU = new rtosc::ThreadLink(4096*2*16,1024/16);
uToB = new rtosc::ThreadLink(4096*2*16,1024/16);
- midi_mapper.base_ports = &Master::ports;
- midi_mapper.rt_cb = [this](const char *msg){handleMsg(msg);};
+ //midi_mapper.base_ports = &Master::ports;
+ //midi_mapper.rt_cb = [this](const char *msg){handleMsg(msg);};
if(preferrred_port != -1)
server = lo_server_new_with_proto(to_s(preferrred_port).c_str(),
LO_UDP, liblo_error_cb);
diff --git a/src/Plugin/ZynAddSubFX/DistrhoPluginInfo.h b/src/Plugin/ZynAddSubFX/DistrhoPluginInfo.h
@@ -42,6 +42,22 @@
enum Parameters {
kParamOscPort,
+ kParamSlot1,
+ kParamSlot2,
+ kParamSlot3,
+ kParamSlot4,
+ kParamSlot5,
+ kParamSlot6,
+ kParamSlot7,
+ kParamSlot8,
+ kParamSlot9,
+ kParamSlot10,
+ kParamSlot11,
+ kParamSlot12,
+ kParamSlot13,
+ kParamSlot14,
+ kParamSlot15,
+ kParamSlot16,
kParamCount
};
diff --git a/src/Plugin/ZynAddSubFX/ZynAddSubFX.cpp b/src/Plugin/ZynAddSubFX/ZynAddSubFX.cpp
@@ -226,6 +226,15 @@ protected:
parameter.ranges.def = 0.0f;
break;
}
+ if(kParamSlot1 <= index && index <= kParamSlot16) {
+ parameter.hints = kParameterIsAutomable;
+ parameter.name = ("Automation Slot " + zyn::to_s(index)).c_str();
+ parameter.symbol = ("slot" + zyn::to_s(index)).c_str();
+ parameter.unit = "";
+ parameter.ranges.min = 0.0f;
+ parameter.ranges.max = 1.0f;
+ parameter.ranges.def = 0.5f;
+ }
}
/**