OSC: select channel plugin support with paging.
This commit is contained in:
parent
1794d08789
commit
9441e8d484
@ -893,6 +893,11 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
|
||||
|
||||
ret = cue_parse (path, types, argv, argc, msg);
|
||||
|
||||
} else
|
||||
if (!strncmp (path, "/select/plugin/parameter", 24)) {
|
||||
|
||||
ret = select_plugin_parameter (path, types, argv, argc, msg);
|
||||
|
||||
} else
|
||||
if (!strncmp (path, "/access_action/", 15)) {
|
||||
check_surface (msg);
|
||||
@ -1461,11 +1466,6 @@ OSC::get_surface (lo_address addr)
|
||||
return &_surface[it];
|
||||
}
|
||||
}
|
||||
// if we do this when OSC is started we get the wrong stripable
|
||||
// we don't need this until we actually have a surface to deal with
|
||||
if (!_select || (_select != ControlProtocol::first_selected_stripable())) {
|
||||
gui_selection_changed();
|
||||
}
|
||||
|
||||
// No surface create one with default values
|
||||
OSCSurface s;
|
||||
@ -1487,10 +1487,14 @@ OSC::get_surface (lo_address addr)
|
||||
s.send_page_size = 0;
|
||||
s.plug_page = 1;
|
||||
s.plug_page_size = 0;
|
||||
s.plugin = 1;
|
||||
s.plugin_id = 1;
|
||||
|
||||
s.nstrips = s.strips.size();
|
||||
_surface.push_back (s);
|
||||
// moved this down here as selection may need s.<anything to do with select> set
|
||||
if (!_select || (_select != ControlProtocol::first_selected_stripable())) {
|
||||
gui_selection_changed();
|
||||
}
|
||||
|
||||
// set bank and strip feedback
|
||||
_set_bank(s.bank, addr);
|
||||
@ -1796,13 +1800,80 @@ OSC::sel_plug_page (int page, lo_message msg)
|
||||
}
|
||||
|
||||
int
|
||||
OSC::sel_plugin (uint32_t id, lo_message msg)
|
||||
OSC::sel_plugin (int delta, lo_message msg)
|
||||
{
|
||||
OSCSurface *s = get_surface(get_address (msg));
|
||||
s->plugin = id;
|
||||
s->plug_page = 1;
|
||||
s->sel_obs->renew_plugin();
|
||||
OSCSurface *sur = get_surface(get_address (msg));
|
||||
return _sel_plugin (sur->plugin_id + delta, get_address (msg));
|
||||
}
|
||||
|
||||
int
|
||||
OSC::_sel_plugin (int id, lo_address addr)
|
||||
{
|
||||
OSCSurface *sur = get_surface(addr);
|
||||
boost::shared_ptr<Stripable> s;
|
||||
if (sur->expand_enable) {
|
||||
s = get_strip (sur->expand, addr);
|
||||
} else {
|
||||
s = _select;
|
||||
}
|
||||
if (s) {
|
||||
boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
|
||||
if (!r) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// find out how many plugins we have
|
||||
bool plugs;
|
||||
int nplugs = 0;
|
||||
do {
|
||||
plugs = false;
|
||||
if (r->nth_plugin (nplugs)) {
|
||||
plugs = true;
|
||||
nplugs++;
|
||||
}
|
||||
} while (plugs);
|
||||
|
||||
// limit plugin_id to actual plugins
|
||||
if (nplugs < id) {
|
||||
sur->plugin_id = nplugs;
|
||||
} else if (!nplugs) {
|
||||
sur->plugin_id = 0;
|
||||
} else if (nplugs && !id) {
|
||||
sur->plugin_id = 1;
|
||||
} else {
|
||||
sur->plugin_id = id;
|
||||
}
|
||||
|
||||
// we have a plugin number now get the processor
|
||||
boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugin_id - 1);
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
|
||||
PBD::warning << "OSC: Plugin: " << sur->plugin_id << " does not seem to be a plugin" << endmsg;
|
||||
return 1;
|
||||
}
|
||||
boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
|
||||
bool ok = false;
|
||||
// put only input controls into a vector
|
||||
sur->plug_params.clear ();
|
||||
uint32_t nplug_params = pip->parameter_count();
|
||||
for ( uint32_t ppi = 0; ppi < nplug_params; ++ppi) {
|
||||
uint32_t controlid = pip->nth_parameter(ppi, ok);
|
||||
if (!ok) {
|
||||
continue;
|
||||
}
|
||||
if (pip->parameter_is_input(controlid)) {
|
||||
sur->plug_params.push_back (ppi);
|
||||
}
|
||||
}
|
||||
|
||||
sur->plug_page = 1;
|
||||
|
||||
if (sur->sel_obs) {
|
||||
sur->sel_obs->renew_plugin();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2844,16 +2915,26 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
|
||||
s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
|
||||
sur->sel_obs = sel_fb;
|
||||
} else if (sur->expand_enable) {
|
||||
// expand doesn't point to a stripable, turn it off and use select
|
||||
sur->expand = 0;
|
||||
sur->expand_enable = false;
|
||||
if (_select && feedback_on) {
|
||||
OSCSelectObserver* sel_fb = new OSCSelectObserver (_select, addr, sur);
|
||||
_select->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
|
||||
s = _select;
|
||||
OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur);
|
||||
s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
|
||||
sur->sel_obs = sel_fb;
|
||||
}
|
||||
} else if (feedback_on) {
|
||||
route_send_fail ("select", sur->expand, 0 , addr);
|
||||
}
|
||||
// need to set monitor for processor changed signal
|
||||
// detecting processor changes requires cast to route
|
||||
boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
|
||||
if (r) {
|
||||
r->processors_changed.connect (sur->proc_connection, MISSING_INVALIDATOR, boost::bind (&OSC::processor_changed, this, addr), this);
|
||||
processor_changed (addr);
|
||||
}
|
||||
|
||||
if (!feedback_on) {
|
||||
return 0;
|
||||
}
|
||||
@ -2904,6 +2985,18 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
OSC::processor_changed (lo_address addr)
|
||||
{
|
||||
OSCSurface *sur = get_surface (addr);
|
||||
sur->proc_connection.disconnect ();
|
||||
_sel_plugin (sur->plugin_id, addr);
|
||||
if (sur->sel_obs) {
|
||||
sur->sel_obs->renew_sends ();
|
||||
sur->sel_obs->eq_restart (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
OSC::strip_gui_select (int ssid, int yn, lo_message msg)
|
||||
{
|
||||
@ -3381,6 +3474,115 @@ OSC::sel_sendenable (int id, float val, lo_message msg)
|
||||
return sel_send_fail ("send_enable", id, 0, get_address (msg));
|
||||
}
|
||||
|
||||
int
|
||||
OSC::select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg) {
|
||||
OSCSurface *sur = get_surface(get_address (msg));
|
||||
int paid;
|
||||
int piid = sur->plugin_id;
|
||||
float value = 0;
|
||||
if (argc > 1) {
|
||||
// no inline args
|
||||
if (argc == 2) {
|
||||
// change parameter in already selected plugin
|
||||
if (argv[0]->f) {
|
||||
paid = (int) argv[0]->f;
|
||||
} else {
|
||||
paid = argv[0]->i;
|
||||
}
|
||||
value = argv[1]->f;
|
||||
} else if (argc == 3) {
|
||||
if (argv[0]->f) {
|
||||
piid = (int) argv[0]->f;
|
||||
} else {
|
||||
piid = argv[0]->i;
|
||||
}
|
||||
_sel_plugin (piid, get_address (msg));
|
||||
if (argv[1]->f) {
|
||||
paid = (int) argv[1]->f;
|
||||
} else {
|
||||
paid = argv[1]->i;
|
||||
}
|
||||
value = argv[2]->f;
|
||||
} else if (argc > 3) {
|
||||
PBD::warning << "OSC: Too many parameters: " << argc << endmsg;
|
||||
return -1;
|
||||
}
|
||||
} else if (argc) {
|
||||
const char * par = strstr (&path[25], "/");
|
||||
if (par) {
|
||||
piid = atoi (&path[25]);
|
||||
_sel_plugin (piid, msg);
|
||||
paid = atoi (&par[1]);
|
||||
value = argv[0]->f;
|
||||
// we have plugin id too
|
||||
} else {
|
||||
// just parameter
|
||||
paid = atoi (&path[25]);
|
||||
value = argv[0]->f;
|
||||
}
|
||||
} else {
|
||||
PBD::warning << "OSC: Must have parameters." << endmsg;
|
||||
return -1;
|
||||
}
|
||||
if (piid != sur->plugin_id) {
|
||||
// if the user is sending to a non-existant plugin, don't adjust one we do have
|
||||
PBD::warning << "OSC: plugin: " << piid << " out of range" << endmsg;
|
||||
return -1;
|
||||
}
|
||||
if (sur->plug_page_size && (paid > (int)sur->plug_page_size)) {
|
||||
return sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
|
||||
}
|
||||
boost::shared_ptr<Stripable> s;
|
||||
if (sur->expand_enable) {
|
||||
s = get_strip (sur->expand, get_address (msg));
|
||||
} else {
|
||||
s = _select;
|
||||
}
|
||||
boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
|
||||
if (!r) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugin_id - 1);
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
|
||||
return 1;
|
||||
}
|
||||
boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
|
||||
// paid is paged parameter convert to absolute
|
||||
int parid = paid + (int)(sur->plug_page_size * (sur->plug_page - 1));
|
||||
if (parid > (int) sur->plug_params.size ()) {
|
||||
if (sur->feedback[13]) {
|
||||
sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
uint32_t controlid = pip->nth_parameter(sur->plug_params[parid - 1], ok);
|
||||
if (!ok) {
|
||||
return 1;
|
||||
}
|
||||
ParameterDescriptor pd;
|
||||
pip->get_parameter_descriptor(controlid, pd);
|
||||
if ( pip->parameter_is_input(controlid) || pip->parameter_is_control(controlid) ) {
|
||||
boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
|
||||
if (c) {
|
||||
if (pd.integer_step && pd.upper == 1) {
|
||||
if (c->get_value () && value < 1.0) {
|
||||
c->set_value (0, PBD::Controllable::NoGroup);
|
||||
} else if (!c->get_value () && value) {
|
||||
c->set_value (1, PBD::Controllable::NoGroup);
|
||||
}
|
||||
} else {
|
||||
c->set_value (c->interface_to_internal (value), PBD::Controllable::NoGroup);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
OSC::route_plugin_list (int ssid, lo_message msg) {
|
||||
if (!session) {
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/send.h"
|
||||
#include "ardour/plugin.h"
|
||||
#include "control_protocol/control_protocol.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
@ -123,9 +124,11 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
|
||||
uint32_t bank_size; // size of banks for this surface
|
||||
int plug_page; // current plugin page
|
||||
uint32_t plug_page_size; // plugin page size (number of controls)
|
||||
uint32_t plugin; // id of current plugin
|
||||
int plugin_id; // id of current plugin
|
||||
std::vector<int> plug_params; // vector to store ports that are controls
|
||||
int send_page; // current send page
|
||||
uint32_t send_page_size; // send page size in channels
|
||||
PBD::ScopedConnection proc_connection; // for processor signal monitoring
|
||||
std::bitset<32> strip_types;// what strip types are a part of this bank
|
||||
uint32_t nstrips; // how many strips are there for strip_types
|
||||
std::bitset<32> feedback; // What is fed back? strips/meters/timecode/bar_beat/global
|
||||
@ -266,6 +269,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
|
||||
boost::shared_ptr<ARDOUR::Send> cue_get_send (uint32_t id, lo_address addr);
|
||||
// end cue
|
||||
|
||||
int select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg);
|
||||
|
||||
#define OSC_DEBUG \
|
||||
if (_debugmode == All) { \
|
||||
debugmsg (dgettext(PACKAGE, "OSC"), path, types, argv, argc); \
|
||||
@ -592,7 +597,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
|
||||
int sel_send_page (int page, lo_message msg);
|
||||
int sel_plug_pagesize (uint32_t size, lo_message msg);
|
||||
int sel_plug_page (int page, lo_message msg);
|
||||
int sel_plugin (uint32_t id, lo_message msg);
|
||||
int sel_plugin (int delta, lo_message msg);
|
||||
int _sel_plugin (int id, lo_address addr);
|
||||
void processor_changed (lo_address addr);
|
||||
|
||||
int scrub (float delta, lo_message msg);
|
||||
int jog (float delta, lo_message msg);
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "ardour/solo_safe_control.h"
|
||||
#include "ardour/route.h"
|
||||
#include "ardour/send.h"
|
||||
#include "ardour/plugin.h"
|
||||
#include "ardour/plugin_insert.h"
|
||||
#include "ardour/processor.h"
|
||||
#include "ardour/readonly_control.h"
|
||||
|
||||
@ -142,14 +144,8 @@ OSCSelectObserver::OSCSelectObserver (boost::shared_ptr<Stripable> s, lo_address
|
||||
change_message ("/select/pan_lfe_control", _strip->pan_lfe_control());
|
||||
}
|
||||
|
||||
// sends and eq
|
||||
// detecting processor changes requires cast to route
|
||||
boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(_strip);
|
||||
if (r) {
|
||||
r->processors_changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_restart, this, -1), OSC::instance());
|
||||
send_init();
|
||||
eq_init();
|
||||
}
|
||||
// sends, plugins and eq
|
||||
// detecting processor changes is now in osc.cc
|
||||
|
||||
// Compressor
|
||||
if (_strip->comp_enable_controllable ()) {
|
||||
@ -231,6 +227,7 @@ OSCSelectObserver::~OSCSelectObserver ()
|
||||
send_float ("/select/comp_makeup", 0);
|
||||
}
|
||||
send_end();
|
||||
plugin_end();
|
||||
eq_end();
|
||||
|
||||
lo_address_free (addr);
|
||||
@ -244,7 +241,8 @@ OSCSelectObserver::renew_sends () {
|
||||
|
||||
void
|
||||
OSCSelectObserver::renew_plugin () {
|
||||
// to be written :)
|
||||
plugin_end();
|
||||
plugin_init();
|
||||
}
|
||||
|
||||
void
|
||||
@ -264,6 +262,7 @@ OSCSelectObserver::send_init()
|
||||
return;
|
||||
}
|
||||
|
||||
// paging should be done in osc.cc in case there is no feedback
|
||||
send_size = nsends;
|
||||
if (sur->send_page_size) {
|
||||
send_size = sur->send_page_size;
|
||||
@ -311,6 +310,79 @@ OSCSelectObserver::send_init()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OSCSelectObserver::plugin_init()
|
||||
{
|
||||
if (!sur->plugin_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(_strip);
|
||||
if (!r) {
|
||||
return;
|
||||
}
|
||||
|
||||
// we have a plugin number now get the processor
|
||||
boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugin_id - 1);
|
||||
boost::shared_ptr<PluginInsert> pi;
|
||||
if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
|
||||
return;
|
||||
}
|
||||
boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
|
||||
|
||||
bool ok = false;
|
||||
nplug_params = sur->plug_params.size ();
|
||||
|
||||
// default of 0 page size means show all
|
||||
plug_size = nplug_params;
|
||||
if (sur->plug_page_size) {
|
||||
plug_size = sur->plug_page_size;
|
||||
}
|
||||
text_message ("/select/plugin/name", pip->name());
|
||||
uint32_t page_end = nplug_params;
|
||||
uint32_t max_page = 1;
|
||||
if (plug_size) {
|
||||
max_page = (uint32_t)((nplug_params - 1) / plug_size) + 1;
|
||||
}
|
||||
|
||||
if (sur->plug_page < 1) {
|
||||
sur->plug_page = 1;
|
||||
}
|
||||
if ((uint32_t)sur->plug_page > max_page) {
|
||||
sur->plug_page = max_page;
|
||||
}
|
||||
uint32_t page_start = ((sur->plug_page - 1) * plug_size);
|
||||
page_end = sur->plug_page * plug_size;
|
||||
|
||||
int pid = 1;
|
||||
for ( uint32_t ppi = page_start; ppi < page_end; ++ppi, ++pid) {
|
||||
if (ppi >= nplug_params) {
|
||||
text_with_id ("/select/plugin/parameter/name", pid, " ");
|
||||
send_float_with_id ("/select/plugin/parameter", pid, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t controlid = pip->nth_parameter(sur->plug_params[ppi], ok);
|
||||
if (!ok) {
|
||||
continue;
|
||||
}
|
||||
ParameterDescriptor pd;
|
||||
pip->get_parameter_descriptor(controlid, pd);
|
||||
text_with_id ("/select/plugin/parameter/name", pid, pd.label);
|
||||
if ( pip->parameter_is_input(controlid)) {
|
||||
boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
|
||||
if (c) {
|
||||
bool swtch = false;
|
||||
if (pd.integer_step && pd.upper == 1) {
|
||||
swtch = true;
|
||||
}
|
||||
c->Changed.connect (plugin_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::plugin_parameter_changed, this, pid, swtch, c), OSC::instance());
|
||||
plugin_parameter_changed (pid, swtch, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OSCSelectObserver::send_end ()
|
||||
{
|
||||
@ -332,10 +404,26 @@ OSCSelectObserver::send_end ()
|
||||
}
|
||||
|
||||
void
|
||||
OSCSelectObserver::send_restart(int x)
|
||||
OSCSelectObserver::plugin_parameter_changed (int pid, bool swtch, boost::shared_ptr<PBD::Controllable> controllable)
|
||||
{
|
||||
send_end();
|
||||
send_init();
|
||||
if (swtch) {
|
||||
enable_message_with_id ("/select/plugin/parameter", pid, controllable);
|
||||
} else {
|
||||
change_message_with_id ("/select/plugin/parameter", pid, controllable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OSCSelectObserver::plugin_end ()
|
||||
{
|
||||
plugin_connections.drop_connections ();
|
||||
text_message ("/select/plugin/name", " ");
|
||||
for (uint32_t i = 1; i <= plug_size; i++) {
|
||||
send_float_with_id ("/select/plugin/parameter", i, 0);
|
||||
// next name
|
||||
text_with_id ("/select/plugin/parameter/name", i, " ");
|
||||
}
|
||||
nplug_params = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -45,13 +45,15 @@ class OSCSelectObserver
|
||||
void tick (void);
|
||||
void renew_sends (void);
|
||||
void renew_plugin (void);
|
||||
void eq_restart (int);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::Stripable> _strip;
|
||||
|
||||
PBD::ScopedConnectionList strip_connections;
|
||||
// sends and eq need their own
|
||||
// sends, plugins and eq need their own
|
||||
PBD::ScopedConnectionList send_connections;
|
||||
PBD::ScopedConnectionList plugin_connections;
|
||||
PBD::ScopedConnectionList eq_connections;
|
||||
|
||||
lo_address addr;
|
||||
@ -66,6 +68,8 @@ class OSCSelectObserver
|
||||
float _last_gain;
|
||||
ARDOUR::AutoState as;
|
||||
uint32_t send_size;
|
||||
uint32_t nplug_params;
|
||||
uint32_t plug_size;
|
||||
|
||||
void name_changed (const PBD::PropertyChange& what_changed);
|
||||
void change_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable);
|
||||
@ -82,12 +86,13 @@ class OSCSelectObserver
|
||||
// sends stuff
|
||||
void send_init (void);
|
||||
void send_end (void);
|
||||
void send_restart (int);
|
||||
void plugin_init (void);
|
||||
void plugin_end (void);
|
||||
void plugin_parameter_changed (int pid, bool swtch, boost::shared_ptr<PBD::Controllable> controllable);
|
||||
void send_gain (uint32_t id, boost::shared_ptr<PBD::Controllable> controllable);
|
||||
void send_enable (std::string path, uint32_t id, boost::shared_ptr<ARDOUR::Processor> proc);
|
||||
void eq_init (void);
|
||||
void eq_end (void);
|
||||
void eq_restart (int);
|
||||
std::string set_path (std::string path, uint32_t id);
|
||||
void send_float (std::string path, float val);
|
||||
void send_float_with_id (std::string path, uint32_t id, float val);
|
||||
|
Loading…
Reference in New Issue
Block a user