OSC link: first working commit for linking two surfaces as one

This commit is contained in:
Len Ovens 2017-11-03 12:35:19 -07:00
parent caedbbf543
commit 3eee4fe8a5
6 changed files with 373 additions and 93 deletions

View file

@ -415,6 +415,8 @@ OSC::register_callbacks()
REGISTER_CALLBACK (serv, "/refresh", "f", refresh_surface); REGISTER_CALLBACK (serv, "/refresh", "f", refresh_surface);
REGISTER_CALLBACK (serv, "/strip/list", "", routes_list); REGISTER_CALLBACK (serv, "/strip/list", "", routes_list);
REGISTER_CALLBACK (serv, "/strip/list", "f", routes_list); REGISTER_CALLBACK (serv, "/strip/list", "f", routes_list);
REGISTER_CALLBACK (serv, "/surface/list", "", surface_list);
REGISTER_CALLBACK (serv, "/surface/list", "f", surface_list);
REGISTER_CALLBACK (serv, "/add_marker", "", add_marker); REGISTER_CALLBACK (serv, "/add_marker", "", add_marker);
REGISTER_CALLBACK (serv, "/add_marker", "f", add_marker); REGISTER_CALLBACK (serv, "/add_marker", "f", add_marker);
REGISTER_CALLBACK (serv, "/access_action", "s", access_action); REGISTER_CALLBACK (serv, "/access_action", "s", access_action);
@ -992,6 +994,9 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
else if (!strncmp (path, "/set_surface", 12)) { else if (!strncmp (path, "/set_surface", 12)) {
ret = surface_parse (path, types, argv, argc, msg); ret = surface_parse (path, types, argv, argc, msg);
} }
else if (strstr (path, "/link")) {
ret = parse_link (path, types, argv, argc, msg);
}
if (ret) { if (ret) {
check_surface (msg); check_surface (msg);
} }
@ -1246,6 +1251,54 @@ OSC::routes_list (lo_message msg)
} }
void
OSC::surface_list (lo_message msg)
{
/* this function is for debugging and prints lots of
* information about what surfaces Ardour knows about and their
* internal parameters. It is best accessed by sending:
* /surface/list from oscsend. This command does not create
* a surface entry.
*/
cerr << "List of known Surfaces: " << _surface.size() << "\n\n";
Glib::Threads::Mutex::Lock lm (surfaces_lock);
for (uint32_t it = 0; it < _surface.size(); it++) {
OSCSurface* sur = &_surface[it];
cerr << string_compose (" Surface: %1 URL: %2\n", it, sur->remote_url);
cerr << string_compose (" Number of strips: %1 Bank size: %2 Current Bank %3\n", sur->nstrips, sur->bank_size, sur->bank);
bool ug = false;
if (sur->usegroup == PBD::Controllable::UseGroup) {
ug = true;
}
cerr << string_compose (" Strip Types: %1 Feedback: %2 no_clear: %3 gain mode: %4 use groups? %5\n", \
sur->strip_types.to_ulong(), sur->feedback.to_ulong(), sur->no_clear, sur->gainmode, ug);
cerr << string_compose (" using plugin: %1 of %2 plugins, with %3 params. page size: %4 page: %5\n", \
sur->plugin_id, sur->plugins.size(), sur->plug_params.size(), sur->plug_page_size, sur->plug_page);
cerr << string_compose (" send page size: %1 page: %2\n", sur->send_page_size, sur->send_page);
cerr << string_compose (" expanded? %1 track: %2 jogmode: %3\n", sur->expand_enable, sur->expand, sur->jogmode);
cerr << string_compose (" personal monitor? %1, Aux master: %2, number of sends: %3\n", sur->cue, sur->aux, sur->sends.size());
cerr << string_compose (" Linkset: %1 Device Id: %2\n", sur->linkset, sur->linkid);
}
cerr << "\nList of LinkSets " << link_sets.size() << "\n\n";
std::map<uint32_t, LinkSet>::iterator it;
for (it = link_sets.begin(); it != link_sets.end(); it++) {
if (!(*it).first) {
continue;
}
uint32_t devices = 0;
LinkSet* set = &(*it).second;
if (set->linked.size()) {
devices = set->linked.size() - 1;
}
cerr << string_compose (" Linkset %1 has %2 devices and sees %3 strips\n", (*it).first, devices, set->strips.size());
cerr << string_compose (" Bank size: %1 Current bank: %2 Strip Types: %3\n", set->banksize, set->bank, set->strip_types.to_ulong());
cerr << string_compose (" auto bank sizing: %1 linkset not ready: %2\n", set->autobank, set->not_ready);
}
cerr << "\n";
}
int int
OSC::cancel_all_solos () OSC::cancel_all_solos ()
{ {
@ -1295,6 +1348,7 @@ OSC::clear_devices ()
surface_destroy (sur); surface_destroy (sur);
} }
_surface.clear(); _surface.clear();
link_sets.clear ();
PresentationInfo::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); PresentationInfo::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
@ -1302,6 +1356,134 @@ OSC::clear_devices ()
tick = true; tick = true;
} }
int
OSC::parse_link (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
{
int ret = 1; /* unhandled */
int set = 0;
if (!argc) {
PBD::warning << "OSC: /link/* needs at least one parameter" << endmsg;
return ret;
}
float data = 0;
if (types[argc - 1] == 'f') {
data = argv[argc - 1]->f;
} else {
data = argv[argc - 1]->i;
}
if (isdigit(strrchr (path, '/')[1])) {
set = atoi (&(strrchr (path, '/')[1]));
} else if (argc == 2) {
if (types[0] == 'f') {
set = (int) argv[0]->f;
} else {
set = argv[0]->i;
}
} else {
PBD::warning << "OSC: wrong number of parameters." << endmsg;
return ret;
}
OSCSurface *sur = get_surface(get_address (msg));
LinkSet *ls = 0;
if (set) {
// need to check if set is wanted
std::map<uint32_t, LinkSet>::iterator it;
it = link_sets.find(set);
if (it == link_sets.end()) {
// no such linkset make it
LinkSet new_ls;
new_ls.banksize = 0;
new_ls.bank = 1;
new_ls.autobank = true;
new_ls.not_ready = true;
new_ls.strip_types = sur->strip_types;
new_ls.strips = sur->strips;
link_sets[set] = new_ls;
}
ls = &link_sets[set];
} else {
// User expects this surface to be removed from any sets
int oldset = sur->linkset;
if (oldset) {
int oldid = sur->linkid;
sur->linkid = 1;
sur->linkset = 0;
ls = &link_sets[oldid];
if (ls) {
ls->not_ready = 1;
ls->linked[(uint32_t) data] = 0;
}
}
return 0;
}
if (!strncmp (path, "/link/bank_size", 15)) {
ls->banksize = (uint32_t) data;
ls->autobank = false;
ls->not_ready = link_check (set);
if (ls->not_ready) {
ls->bank = 1;
strip_feedback (sur, true);
} else {
_set_bank (ls->bank, get_address (msg));
}
ret = 0;
} else if (!strncmp (path, "/link/set", 9)) {
sur->linkset = set;
sur->linkid = (uint32_t) data;
if (ls->linked.size() <= (uint32_t) data) {
ls->linked.resize((int) data + 1);
}
ls->linked[(uint32_t) data] = sur;
ls->not_ready = link_check (set);
if (ls->not_ready) {
strip_feedback (sur, true);
} else {
_set_bank (1, get_address (msg));
}
ret = 0;
}
return ret;
}
int
OSC::link_check (uint32_t set)
{
LinkSet *ls = 0;
if (!set) {
return 1;
}
std::map<uint32_t, LinkSet>::iterator it;
it = link_sets.find(set);
if (it == link_sets.end()) {
// this should never happen... but
return 1;
}
ls = &link_sets[set];
uint32_t bank_total = 0;
uint32_t set_ready = 0;
for (uint32_t dv = 1; dv < ls->linked.size(); dv++) {
if ((ls->linked[dv]) && ((ls->linked[dv]))->linkset == set) {
OSCSurface *su = (ls->linked[dv]);
bank_total = bank_total + su->bank_size;
} else if (!set_ready) {
set_ready = dv;
}
}
if (ls->autobank) {
ls->banksize = bank_total;
} else {
if (!set_ready && bank_total != ls->banksize) {
set_ready = ls->linked.size();
}
}
return set_ready;
}
int int
OSC::surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg) OSC::surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
{ {
@ -1496,10 +1678,11 @@ OSC::set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gm, ui
s->send_page_size = se_size; s->send_page_size = se_size;
s->plug_page_size = pi_size; s->plug_page_size = pi_size;
// set bank and strip feedback // set bank and strip feedback
// XXXX check if we are already in a linkset
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), get_address (msg), true);
strip_feedback(s, true); strip_feedback(s, true);
global_feedback (s); global_feedback (s);
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), get_address (msg));
sel_send_pagesize (se_size, msg); sel_send_pagesize (se_size, msg);
sel_plug_pagesize (pi_size, msg); sel_plug_pagesize (pi_size, msg);
return 0; return 0;
@ -1513,6 +1696,7 @@ OSC::set_surface_bank_size (uint32_t bs, lo_message msg)
} }
OSCSurface *s = get_surface(get_address (msg), true); OSCSurface *s = get_surface(get_address (msg), true);
s->bank_size = bs; s->bank_size = bs;
// XXXX check if we are already in a linkset
s->bank = 1; s->bank = 1;
// set bank and strip feedback // set bank and strip feedback
@ -1536,6 +1720,7 @@ OSC::set_surface_strip_types (uint32_t st, lo_message msg)
} }
// set bank and strip feedback // set bank and strip feedback
// XXXX check for linkset
s->bank = 1; s->bank = 1;
strip_feedback (s, true); strip_feedback (s, true);
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), get_address (msg)); _strip_select (boost::shared_ptr<ARDOUR::Stripable>(), get_address (msg));
@ -1599,7 +1784,7 @@ OSC::get_surface (lo_address addr , bool quiet)
free (rurl); free (rurl);
{ {
for (uint32_t it = 0; it < _surface.size(); ++it) { for (uint32_t it = 0; it < _surface.size(); ++it) {
//find setup for this server //find setup for this surface
if (!_surface[it].remote_url.find(r_url)){ if (!_surface[it].remote_url.find(r_url)){
return &_surface[it]; return &_surface[it];
} }
@ -1632,6 +1817,8 @@ OSC::get_surface (lo_address addr , bool quiet)
s.plug_page = 1; s.plug_page = 1;
s.plug_page_size = default_plugin_size; s.plug_page_size = default_plugin_size;
s.plugin_id = 1; s.plugin_id = 1;
s.linkset = 0;
s.linkid = 1;
s.nstrips = s.strips.size(); s.nstrips = s.strips.size();
{ {
@ -1674,7 +1861,6 @@ OSC::strip_feedback (OSCSurface* sur, bool new_bank_size)
} }
sur->observers.clear(); sur->observers.clear();
// get freash striplist - just in case
uint32_t bank_size = sur->bank_size; uint32_t bank_size = sur->bank_size;
if (!bank_size) { if (!bank_size) {
bank_size = sur->nstrips; bank_size = sur->nstrips;
@ -1739,9 +1925,11 @@ OSC::_recalcbanks ()
// refresh each surface we know about. // refresh each surface we know about.
for (uint32_t it = 0; it < _surface.size(); ++it) { for (uint32_t it = 0; it < _surface.size(); ++it) {
OSCSurface* sur = &_surface[it]; OSCSurface* sur = &_surface[it];
sur->strips = get_sorted_stripables(sur->strip_types, sur->cue);
sur->nstrips = sur->strips.size();
// find lo_address // find lo_address
lo_address addr = lo_address_new_from_url (sur->remote_url.c_str()); lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), addr); _strip_select (boost::shared_ptr<ARDOUR::Stripable>(), addr, true);
if (sur->cue) { if (sur->cue) {
_cue_set (sur->aux, addr); _cue_set (sur->aux, addr);
} else if (!sur->bank_size) { } else if (!sur->bank_size) {
@ -1770,58 +1958,107 @@ OSC::_set_bank (uint32_t bank_start, lo_address addr)
if (!session) { if (!session) {
return -1; return -1;
} }
// no nstripables yet
if (!session->nroutes()) { if (!session->nroutes()) {
return -1; return -1;
} }
OSCSurface *s = get_surface (addr); OSCSurface *s = get_surface (addr, true);
// revert any expand to select Sorted striplist = s->strips;
s->expand = 0; uint32_t nstrips = s->nstrips;
s->expand_enable = false;
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), addr);
s->strips = get_sorted_stripables(s->strip_types, s->cue); LinkSet *set;
s->nstrips = s->strips.size(); uint32_t l_set = s->linkset;
uint32_t b_size; if (l_set) {
if (!s->bank_size) { //we have a linkset... deal with each surface
// no banking - bank includes all stripables set = &(link_sets[l_set]);
b_size = s->nstrips; if (set->not_ready) {
return 1;
}
uint32_t s_count = set->linked.size();
set->strips = striplist;
bank_start = bank_limits_check (bank_start, set->banksize, nstrips);
set->bank = bank_start;
for (uint32_t ls = 1; ls < s_count; ls++) {
OSCSurface *sur = (set->linked[ls]);
if (!sur || sur->linkset != l_set) {
if (!set->not_ready) {
set->not_ready = ls;
}
set->bank = 1;
return 1;
}
lo_address sur_addr = lo_address_new_from_url (sur->remote_url.c_str());
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), addr, true);
sur->bank = bank_start;
bank_start = bank_start + sur->bank_size;
strip_feedback (sur, false);
bank_leds (sur);
lo_address_free (sur_addr);
}
} else { } else {
b_size = s->bank_size;
_strip_select (boost::shared_ptr<ARDOUR::Stripable>(), addr, true);
s->bank = bank_limits_check (bank_start, s->bank_size, nstrips);
strip_feedback (s, true);
bank_leds (s);
} }
// Do limits checking
if (bank_start < 1) bank_start = 1;
if (b_size >= s->nstrips) {
bank_start = 1;
} else if (bank_start > ((s->nstrips - b_size) + 1)) {
// top bank is always filled if there are enough strips for at least one bank
bank_start = (uint32_t)((s->nstrips - b_size) + 1);
}
//save bank after bank limit checks
s->bank = bank_start;
if (s->feedback[0] || s->feedback[1]) {
strip_feedback (s, false);
}
bank_leds (s);
bank_dirty = false; bank_dirty = false;
tick = true; tick = true;
return 0; return 0;
} }
uint32_t
OSC::bank_limits_check (uint32_t bank, uint32_t size, uint32_t total)
{
uint32_t b_size;
if (!size) {
// no banking - bank includes all stripables
b_size = total;
} else {
b_size = size;
}
// Do limits checking
if (bank < 1) bank = 1;
if (b_size >= total) {
bank = 1;
} else if (bank > ((total - b_size) + 1)) {
// top bank is always filled if there are enough strips for at least one bank
bank = (uint32_t)((total - b_size) + 1);
}
return bank;
}
void void
OSC::bank_leds (OSCSurface* s) OSC::bank_leds (OSCSurface* s)
{ {
uint32_t bank = 0;
uint32_t size = 0;
uint32_t total = 0;
// light bankup or bankdown buttons if it is possible to bank in that direction // light bankup or bankdown buttons if it is possible to bank in that direction
lo_address addr = lo_address_new_from_url (s->remote_url.c_str()); lo_address addr = lo_address_new_from_url (s->remote_url.c_str());
if (s->feedback[4] && !s->no_clear) { if (s->linkset) {
LinkSet *set;
set = &(link_sets[s->linkset]);
bank = set->bank;
size = set->banksize;
total = s->nstrips;
if (set->not_ready) {
total = 1;
}
} else {
bank = s->bank;
size = s->bank_size;
total = s->nstrips;
}
if (size && (s->feedback[0] || s->feedback[1] || s->feedback[4])) {
lo_message reply; lo_message reply;
reply = lo_message_new (); reply = lo_message_new ();
if ((s->bank > (s->nstrips - s->bank_size)) || (s->nstrips < s->bank_size)) { if ((total <= size) || (bank > (total - size))) {
lo_message_add_int32 (reply, 0); lo_message_add_int32 (reply, 0);
} else { } else {
lo_message_add_int32 (reply, 1); lo_message_add_int32 (reply, 1);
@ -1829,7 +2066,7 @@ OSC::bank_leds (OSCSurface* s)
lo_send_message (addr, "/bank_up", reply); lo_send_message (addr, "/bank_up", reply);
lo_message_free (reply); lo_message_free (reply);
reply = lo_message_new (); reply = lo_message_new ();
if (s->bank > 1) { if (bank > 1) {
lo_message_add_int32 (reply, 1); lo_message_add_int32 (reply, 1);
} else { } else {
lo_message_add_int32 (reply, 0); lo_message_add_int32 (reply, 0);
@ -1842,12 +2079,7 @@ OSC::bank_leds (OSCSurface* s)
int int
OSC::bank_up (lo_message msg) OSC::bank_up (lo_message msg)
{ {
if (!session) { return bank_delta (1.0, msg);
return -1;
}
OSCSurface *s = get_surface(get_address (msg));
set_bank (s->bank + s->bank_size, msg);
return 0;
} }
int int
@ -1856,12 +2088,34 @@ OSC::bank_delta (float delta, lo_message msg)
if (!session) { if (!session) {
return -1; return -1;
} }
// only do deltas of -1 0 or 1
if (delta > 0) {
delta = 1;
} else if (delta < 0) {
delta = -1;
} else {
// 0 key release ignore
return 0;
}
OSCSurface *s = get_surface(get_address (msg)); OSCSurface *s = get_surface(get_address (msg));
uint32_t new_bank = s->bank + (s->bank_size * (int) delta); if (!s->bank_size) {
// bank size of 0 means use all strips no banking
return 0;
}
uint32_t old_bank = 0;
uint32_t bank_size = 0;
if (s->linkset) {
old_bank = link_sets[s->linkset].bank;
bank_size = link_sets[s->linkset].banksize;
} else {
old_bank = s->bank;
bank_size = s->bank_size;
}
uint32_t new_bank = old_bank + (bank_size * (int) delta);
if ((int)new_bank < 1) { if ((int)new_bank < 1) {
new_bank = 1; new_bank = 1;
} }
if (new_bank != s->bank) { if (new_bank != old_bank) {
set_bank (new_bank, msg); set_bank (new_bank, msg);
} }
return 0; return 0;
@ -1870,16 +2124,7 @@ OSC::bank_delta (float delta, lo_message msg)
int int
OSC::bank_down (lo_message msg) OSC::bank_down (lo_message msg)
{ {
if (!session) { return bank_delta (-1.0, msg);
return -1;
}
OSCSurface *s = get_surface(get_address (msg));
if (s->bank < s->bank_size) {
set_bank (1, msg);
} else {
set_bank (s->bank - s->bank_size, msg);
}
return 0;
} }
int int
@ -3198,7 +3443,7 @@ OSC::strip_expand (int ssid, int yn, lo_message msg)
} }
int int
OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr) OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr, bool quiet)
{ {
if (!session) { if (!session) {
return -1; return -1;
@ -3220,14 +3465,13 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
sur->select = s; sur->select = s;
s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this); s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
OSCSelectObserver* so = 0; OSCSelectObserver* so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs);
if (sur->feedback[13]) { if (sur->feedback[13]) {
if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) { if (so != 0) {
so->refresh_strip (false); delete so;
} else {
OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, sur);
sur->sel_obs = sel_fb;
} }
OSCSelectObserver* sel_fb = new OSCSelectObserver (*this, sur);
sur->sel_obs = sel_fb;
} else { } else {
if (so != 0) { if (so != 0) {
delete so; delete so;
@ -3243,7 +3487,9 @@ OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
processor_changed (addr); processor_changed (addr);
} }
strip_feedback (sur, false); if (!quiet) {
strip_feedback (sur, false);
}
return 0; return 0;
} }

View file

@ -158,6 +158,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
uint32_t aux; // aux index for this cue surface uint32_t aux; // aux index for this cue surface
Sorted sends; // list of sends for cue aux Sorted sends; // list of sends for cue aux
OSCCueObserver* cue_obs; // pointer to this surface's cue observer OSCCueObserver* cue_obs; // pointer to this surface's cue observer
uint32_t linkset; // ID of a set of surfaces used as one
uint32_t linkid; // ID of this surface within a linkset
}; };
/* /*
* feedback bits: * feedback bits:
@ -184,6 +186,22 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
typedef std::vector<OSCSurface> Surface; typedef std::vector<OSCSurface> Surface;
Surface _surface; Surface _surface;
// linked surfaces
struct LinkSet {
public:
std::vector<OSCSurface*> linked; //linked surfaces
uint32_t banksize; // linkset banksize
uint32_t bank; // linkset current bank
bool autobank; // banksize is derived from total
uint32_t not_ready; // number of 1st device, 0 = ready
std::bitset<32> strip_types; // strip_types for this linkset
Sorted strips; // list of valid strips in order for this set
};
std::map<uint32_t, LinkSet> link_sets;
// list of linksets
// GUI calls
std::string get_server_url (); std::string get_server_url ();
void set_debug_mode (OSCDebugMode m) { _debugmode = m; } void set_debug_mode (OSCDebugMode m) { _debugmode = m; }
OSCDebugMode get_debug_mode () { return _debugmode; } OSCDebugMode get_debug_mode () { return _debugmode; }
@ -260,6 +278,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
void global_feedback (OSCSurface* sur); void global_feedback (OSCSurface* sur);
void strip_feedback (OSCSurface* sur, bool new_bank_size); void strip_feedback (OSCSurface* sur, bool new_bank_size);
void surface_destroy (OSCSurface* sur); void surface_destroy (OSCSurface* sur);
uint32_t bank_limits_check (uint32_t bank, uint32_t size, uint32_t total);
void bank_leds (OSCSurface* sur); void bank_leds (OSCSurface* sur);
void send_current_value (const char* path, lo_arg** argv, int argc, lo_message msg); void send_current_value (const char* path, lo_arg** argv, int argc, lo_message msg);
@ -277,6 +296,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
int route_get_sends (lo_message msg); int route_get_sends (lo_message msg);
int route_get_receives(lo_message msg); int route_get_receives(lo_message msg);
void routes_list (lo_message msg); void routes_list (lo_message msg);
void surface_list (lo_message msg);
void transport_sample (lo_message msg); void transport_sample (lo_message msg);
void transport_speed (lo_message msg); void transport_speed (lo_message msg);
void record_enabled (lo_message msg); void record_enabled (lo_message msg);
@ -296,6 +316,10 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
boost::shared_ptr<ARDOUR::Send> cue_get_send (uint32_t id, lo_address addr); boost::shared_ptr<ARDOUR::Send> cue_get_send (uint32_t id, lo_address addr);
// end cue // end cue
// link
int parse_link (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg);
int link_check (uint32_t linkset);
int select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg); int select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg);
int surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg); int surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg);
@ -318,6 +342,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
PATH_CALLBACK_MSG(route_get_sends); PATH_CALLBACK_MSG(route_get_sends);
PATH_CALLBACK_MSG(route_get_receives); PATH_CALLBACK_MSG(route_get_receives);
PATH_CALLBACK_MSG(routes_list); PATH_CALLBACK_MSG(routes_list);
PATH_CALLBACK_MSG(surface_list);
PATH_CALLBACK_MSG(transport_sample); PATH_CALLBACK_MSG(transport_sample);
PATH_CALLBACK_MSG(transport_speed); PATH_CALLBACK_MSG(transport_speed);
PATH_CALLBACK_MSG(record_enabled); PATH_CALLBACK_MSG(record_enabled);
@ -591,7 +616,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
int route_monitor_disk (int rid, int yn, lo_message msg); int route_monitor_disk (int rid, int yn, lo_message msg);
int strip_phase (int rid, int yn, lo_message msg); int strip_phase (int rid, int yn, lo_message msg);
int strip_expand (int rid, int yn, lo_message msg); int strip_expand (int rid, int yn, lo_message msg);
int _strip_select (boost::shared_ptr<ARDOUR::Stripable> s, lo_address addr); int _strip_select (boost::shared_ptr<ARDOUR::Stripable> s, lo_address addr, bool quiet = false);
int strip_gui_select (int rid, int yn, lo_message msg); int strip_gui_select (int rid, int yn, lo_message msg);
int route_set_gain_abs (int rid, float level, lo_message msg); int route_set_gain_abs (int rid, float level, lo_message msg);
int route_set_gain_dB (int rid, float dB, lo_message msg); int route_set_gain_dB (int rid, float dB, lo_message msg);

View file

@ -20,6 +20,8 @@
#include "boost/lambda/lambda.hpp" #include "boost/lambda/lambda.hpp"
#include "pbd/control_math.h" #include "pbd/control_math.h"
#include <glibmm.h>
#include "ardour/session.h" #include "ardour/session.h"
#include "ardour/track.h" #include "ardour/track.h"
@ -78,6 +80,9 @@ void
OSCRouteObserver::refresh_strip (bool force) OSCRouteObserver::refresh_strip (bool force)
{ {
_init = true; _init = true;
if (_tick_busy) {
Glib::usleep(100); // let tick finish
}
gainmode = sur->gainmode; gainmode = sur->gainmode;
feedback = sur->feedback; feedback = sur->feedback;
in_line = feedback[2]; in_line = feedback[2];
@ -92,33 +97,32 @@ OSCRouteObserver::refresh_strip (bool force)
} }
return; return;
} }
// future if (sur->linkset) {
/*if (sur->linkset) { uint32_t not_ready = _osc.link_sets[sur->linkset].not_ready;
//to be added with linkset stuff if (not_ready) {
if (_osc.linksets[sur->linkset]->not_ready)
clear_strip (); clear_strip ();
switch (ssid) { switch (ssid) {
case 1: case 1:
_osc.text_message_with_id ("/strip/name", ssid, "Device", addr); _osc.text_message_with_id ("/strip/name", ssid, "Device", in_line, addr);
break; break;
case 2: case 2:
_osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1", not_ready), addr); _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1", not_ready), in_line, addr);
break; break;
case 3: case 3:
_osc.text_message_with_id ("/strip/name", ssid, "Missing", addr); _osc.text_message_with_id ("/strip/name", ssid, "Missing", in_line, addr);
break; break;
case 4: case 4:
_osc.text_message_with_id ("/strip/name", ssid, "from", addr); _osc.text_message_with_id ("/strip/name", ssid, "from", in_line, addr);
break; break;
case 5: case 5:
_osc.text_message_with_id ("/strip/name", ssid, "Linkset", addr); _osc.text_message_with_id ("/strip/name", ssid, "Linkset", in_line, addr);
break; break;
default: default:
break; break;
} }
return; return;
} }
}*/ }
// this has to be done first because expand may change with no strip change // this has to be done first because expand may change with no strip change
bool new_expand; bool new_expand;
@ -219,7 +223,7 @@ OSCRouteObserver::clear_strip ()
// all strip buttons should be off and faders 0 and etc. // all strip buttons should be off and faders 0 and etc.
_osc.float_message_with_id ("/strip/expand", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/expand", ssid, 0, in_line, addr);
if (sur->feedback[0]) { // buttons are separate feedback if (feedback[0]) { // buttons are separate feedback
_osc.text_message_with_id ("/strip/name", ssid, " ", in_line, addr); _osc.text_message_with_id ("/strip/name", ssid, " ", in_line, addr);
_osc.float_message_with_id ("/strip/mute", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/mute", ssid, 0, in_line, addr);
_osc.float_message_with_id ("/strip/solo", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/solo", ssid, 0, in_line, addr);
@ -230,8 +234,8 @@ OSCRouteObserver::clear_strip ()
_osc.float_message_with_id ("/strip/gui_select", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/gui_select", ssid, 0, in_line, addr);
_osc.float_message_with_id ("/strip/select", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/select", ssid, 0, in_line, addr);
} }
if (sur->feedback[1]) { // level controls if (feedback[1]) { // level controls
if (sur->gainmode) { if (gainmode) {
_osc.float_message_with_id ("/strip/fader", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/fader", ssid, 0, in_line, addr);
} else { } else {
_osc.float_message_with_id ("/strip/gain", ssid, -193, in_line, addr); _osc.float_message_with_id ("/strip/gain", ssid, -193, in_line, addr);
@ -239,16 +243,16 @@ OSCRouteObserver::clear_strip ()
_osc.float_message_with_id ("/strip/trimdB", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/trimdB", ssid, 0, in_line, addr);
_osc.float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, in_line, addr); _osc.float_message_with_id ("/strip/pan_stereo_position", ssid, 0.5, in_line, addr);
} }
if (sur->feedback[9]) { if (feedback[9]) {
_osc.float_message_with_id ("/strip/signal", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/signal", ssid, 0, in_line, addr);
} }
if (sur->feedback[7]) { if (feedback[7]) {
if (sur->gainmode) { if (gainmode) {
_osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr);
} else { } else {
_osc.float_message_with_id ("/strip/meter", ssid, -193, in_line, addr); _osc.float_message_with_id ("/strip/meter", ssid, -193, in_line, addr);
} }
}else if (sur->feedback[8]) { }else if (feedback[8]) {
_osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr); _osc.float_message_with_id ("/strip/meter", ssid, 0, in_line, addr);
} }
} }
@ -260,7 +264,8 @@ OSCRouteObserver::tick ()
if (_init) { if (_init) {
return; return;
} }
if (sur->feedback[7] || sur->feedback[8] || sur->feedback[9]) { // meters enabled _tick_busy = true;
if (feedback[7] || feedback[8] || feedback[9]) { // meters enabled
// the only meter here is master // the only meter here is master
float now_meter; float now_meter;
if (_strip->peak_meter()) { if (_strip->peak_meter()) {
@ -270,18 +275,18 @@ OSCRouteObserver::tick ()
} }
if (now_meter < -120) now_meter = -193; if (now_meter < -120) now_meter = -193;
if (_last_meter != now_meter) { if (_last_meter != now_meter) {
if (sur->feedback[7] || sur->feedback[8]) { if (feedback[7] || feedback[8]) {
if (sur->gainmode && sur->feedback[7]) { if (gainmode && feedback[7]) {
_osc.float_message_with_id ("/strip/meter", ssid, ((now_meter + 94) / 100), in_line, addr); _osc.float_message_with_id ("/strip/meter", ssid, ((now_meter + 94) / 100), in_line, addr);
} else if ((!sur->gainmode) && sur->feedback[7]) { } else if ((!gainmode) && feedback[7]) {
_osc.float_message_with_id ("/strip/meter", ssid, now_meter, in_line, addr); _osc.float_message_with_id ("/strip/meter", ssid, now_meter, in_line, addr);
} else if (sur->feedback[8]) { } else if (feedback[8]) {
uint32_t ledlvl = (uint32_t)(((now_meter + 54) / 3.75)-1); uint32_t ledlvl = (uint32_t)(((now_meter + 54) / 3.75)-1);
uint16_t ledbits = ~(0xfff<<ledlvl); uint16_t ledbits = ~(0xfff<<ledlvl);
_osc.int_message_with_id ("/strip/meter", ssid, ledbits, in_line, addr); _osc.int_message_with_id ("/strip/meter", ssid, ledbits, in_line, addr);
} }
} }
if (sur->feedback[9]) { if (feedback[9]) {
float signal; float signal;
if (now_meter < -40) { if (now_meter < -40) {
signal = 0; signal = 0;
@ -294,7 +299,7 @@ OSCRouteObserver::tick ()
_last_meter = now_meter; _last_meter = now_meter;
} }
if (sur->feedback[1]) { if (feedback[1]) {
if (gain_timeout) { if (gain_timeout) {
if (gain_timeout == 1) { if (gain_timeout == 1) {
_osc.text_message_with_id ("/strip/name", ssid, _strip->name(), in_line, addr); _osc.text_message_with_id ("/strip/name", ssid, _strip->name(), in_line, addr);
@ -314,7 +319,7 @@ OSCRouteObserver::tick ()
} }
} }
} }
_tick_busy = false;
} }
void void
@ -371,7 +376,7 @@ OSCRouteObserver::send_trim_message ()
} else { } else {
return; return;
} }
if (sur->gainmode) { if (gainmode) {
_osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (_last_trim)), in_line, addr); _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (_last_trim)), in_line, addr);
trim_timeout = 8; trim_timeout = 8;
} }
@ -389,7 +394,7 @@ OSCRouteObserver::send_gain_message ()
return; return;
} }
if (sur->gainmode) { if (gainmode) {
_osc.float_message_with_id ("/strip/fader", ssid, controllable->internal_to_interface (_last_gain), in_line, addr); _osc.float_message_with_id ("/strip/fader", ssid, controllable->internal_to_interface (_last_gain), in_line, addr);
_osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), in_line, addr); _osc.text_message_with_id ("/strip/name", ssid, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())), in_line, addr);
gain_timeout = 8; gain_timeout = 8;
@ -406,7 +411,7 @@ void
OSCRouteObserver::gain_automation () OSCRouteObserver::gain_automation ()
{ {
string path = "/strip/gain"; string path = "/strip/gain";
if (sur->gainmode) { if (gainmode) {
path = "/strip/fader"; path = "/strip/fader";
} }
send_gain_message (); send_gain_message ();

View file

@ -68,6 +68,7 @@ class OSCRouteObserver
bool _expand; bool _expand;
bool in_line; bool in_line;
ARDOUR::AutoState as; ARDOUR::AutoState as;
bool _tick_busy;
void name_changed (const PBD::PropertyChange& what_changed); void name_changed (const PBD::PropertyChange& what_changed);

View file

@ -56,6 +56,7 @@ OSCSelectObserver::OSCSelectObserver (OSC& o, ArdourSurface::OSC::OSCSurface* su
,_last_gain (-1.0) ,_last_gain (-1.0)
,_last_trim (-1.0) ,_last_trim (-1.0)
,_init (true) ,_init (true)
,eq_bands (0)
{ {
addr = lo_address_new_from_url (sur->remote_url.c_str()); addr = lo_address_new_from_url (sur->remote_url.c_str());
refresh_strip (true); refresh_strip (true);
@ -115,7 +116,6 @@ OSCSelectObserver::refresh_strip (bool force)
gainmode = sur->gainmode; gainmode = sur->gainmode;
feedback = sur->feedback; feedback = sur->feedback;
in_line = feedback[2]; in_line = feedback[2];
as = ARDOUR::Off;
send_size = 0; send_size = 0;
plug_size = 0; plug_size = 0;
_comp_redux = 1; _comp_redux = 1;
@ -814,11 +814,14 @@ OSCSelectObserver::eq_init()
} }
eq_bands = _strip->eq_band_cnt (); eq_bands = _strip->eq_band_cnt ();
if (eq_bands < 0) {
eq_bands = 0;
}
if (!eq_bands) { if (!eq_bands) {
return; return;
} }
for (uint32_t i = 0; i < eq_bands; i++) { for (int i = 0; i < eq_bands; i++) {
if (_strip->eq_band_name(i).size()) { if (_strip->eq_band_name(i).size()) {
_osc.text_message_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i), in_line, addr); _osc.text_message_with_id ("/select/eq_band_name", i + 1, _strip->eq_band_name (i), in_line, addr);
} }
@ -848,7 +851,7 @@ OSCSelectObserver::eq_end ()
_osc.float_message ("/select/eq_hpf", 0, addr); _osc.float_message ("/select/eq_hpf", 0, addr);
_osc.float_message ("/select/eq_enable", 0, addr); _osc.float_message ("/select/eq_enable", 0, addr);
for (uint32_t i = 1; i <= eq_bands; i++) { for (int i = 1; i <= eq_bands; i++) {
_osc.text_message_with_id ("/select/eq_band_name", i, " ", in_line, addr); _osc.text_message_with_id ("/select/eq_band_name", i, " ", in_line, addr);
_osc.float_message_with_id ("/select/eq_gain", i, 0, in_line, addr); _osc.float_message_with_id ("/select/eq_gain", i, 0, in_line, addr);
_osc.float_message_with_id ("/select/eq_freq", i, 0, in_line, addr); _osc.float_message_with_id ("/select/eq_freq", i, 0, in_line, addr);

View file

@ -78,7 +78,7 @@ class OSCSelectObserver
uint32_t send_size; uint32_t send_size;
uint32_t nplug_params; uint32_t nplug_params;
uint32_t plug_size; uint32_t plug_size;
uint32_t eq_bands; int eq_bands;
void name_changed (const PBD::PropertyChange& what_changed); void name_changed (const PBD::PropertyChange& what_changed);
void change_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable); void change_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable);