summaryrefslogtreecommitdiff
path: root/libs/surfaces
diff options
context:
space:
mode:
authorLen Ovens <len@ovenwerks.net>2017-01-09 18:56:22 -0800
committerLen Ovens <len@ovenwerks.net>2017-01-09 18:56:22 -0800
commitb073328700572ba28c0ab725f91a7f2db0f3e700 (patch)
tree00aee7a3a3b4aed6496b8eef2310d934f6c41f74 /libs/surfaces
parent86e46ae41d1e4baac10dc9d08dd4ce2b94d12216 (diff)
OSC: Add Talent individual monitor controls
Diffstat (limited to 'libs/surfaces')
-rw-r--r--libs/surfaces/osc/osc.cc326
-rw-r--r--libs/surfaces/osc/osc.h28
-rw-r--r--libs/surfaces/osc/osc_cue_observer.cc259
-rw-r--r--libs/surfaces/osc/osc_cue_observer.h69
-rw-r--r--libs/surfaces/osc/osc_select_observer.cc6
-rw-r--r--libs/surfaces/osc/wscript1
6 files changed, 682 insertions, 7 deletions
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc
index 54bc051781..39e61bece5 100644
--- a/libs/surfaces/osc/osc.cc
+++ b/libs/surfaces/osc/osc.cc
@@ -57,6 +57,7 @@
#include "osc_controllable.h"
#include "osc_route_observer.h"
#include "osc_global_observer.h"
+#include "osc_cue_observer.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
@@ -328,6 +329,7 @@ OSC::stop ()
periodic_connection.disconnect ();
session_connections.drop_connections ();
+ cueobserver_connections.drop_connections ();
// Delete any active route observers
for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) {
@@ -352,6 +354,7 @@ OSC::stop ()
++x;
}
}
+
// delete select observers
for (uint32_t it = 0; it < _surface.size(); ++it) {
OSCSurface* sur = &_surface[it];
@@ -361,6 +364,19 @@ OSC::stop ()
}
}
+// delete cue observers
+ for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end();) {
+
+ OSCCueObserver* co;
+
+ if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
+ delete *x;
+ x = cue_observers.erase (x);
+ } else {
+ ++x;
+ }
+ }
+
return 0;
}
@@ -847,7 +863,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
} else
if (!strncmp (path, "/cue/", 5)) {
- //cue_parse (path, types, argv, argc, msg)
+ cue_parse (path, types, argv, argc, msg);
ret = 0;
} else
@@ -1442,7 +1458,11 @@ OSC::_recalcbanks ()
OSCSurface* sur = &_surface[it];
// find lo_address
lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
- _set_bank (sur->bank, addr);
+ if (sur->cue) {
+ _cue_set (sur->aux, addr);
+ } else {
+ _set_bank (sur->bank, addr);
+ }
}
}
@@ -3472,6 +3492,14 @@ OSC::periodic (void)
so->tick();
}
}
+ for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end(); x++) {
+
+ OSCCueObserver* co;
+
+ if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
+ co->tick();
+ }
+ }
return true;
}
@@ -3734,3 +3762,297 @@ OSC::get_sorted_stripables(std::bitset<32> types)
return sorted;
}
+int
+OSC::cue_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
+{
+ int ret = 1; /* unhandled */
+
+ if (!strncmp (path, "/cue/aux", 8)) {
+ // set our Aux bus
+ cue_set (argv[0]->i, msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/connect", 12)) {
+ // switch to next Aux bus
+ cue_set (0, msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/next_aux", 13)) {
+ // switch to next Aux bus
+ cue_next (msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/previous_aux", 17)) {
+ // switch to previous Aux bus
+ cue_previous (msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/send/fader/", 16) && strlen (path) > 16) {
+ int id = atoi (&path[16]);
+ cue_send_fader (id, argv[0]->f, msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/send/enable/", 17) && strlen (path) > 17) {
+ int id = atoi (&path[17]);
+ cue_send_enable (id, argv[0]->f, msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/fader", 10)) {
+ cue_aux_fader (argv[0]->f, msg);
+ ret = 0;
+ }
+ else if (!strncmp (path, "/cue/mute", 9)) {
+ cue_aux_mute (argv[0]->f, msg);
+ ret = 0;
+ }
+
+ if ((ret && _debugmode == Unhandled)) {
+ debugmsg (_("Unhandled OSC cue message"), path, types, argv, argc);
+ } else if ((!ret && _debugmode == All)) {
+ debugmsg (_("OSC cue"), path, types, argv, argc);
+ }
+
+ return ret;
+}
+
+int
+OSC::cue_set (uint32_t aux, lo_message msg)
+{
+ return _cue_set (aux, get_address (msg));
+}
+
+int
+OSC::_cue_set (uint32_t aux, lo_address addr)
+{
+ OSCSurface *s = get_surface(addr);
+ s->bank_size = 0;
+ s->strip_types = 128;
+ s->feedback = 0;
+ s->gainmode = 1;
+ s->cue = true;
+ s->aux = aux;
+ s->strips = get_sorted_stripables(s->strip_types);
+
+ s->nstrips = s->strips.size();
+ // get rid of any old CueObsevers for this address
+ cueobserver_connections.drop_connections ();
+ CueObservers::iterator x;
+ for (x = cue_observers.begin(); x != cue_observers.end();) {
+
+ OSCCueObserver* co;
+
+ if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
+
+ int res = strcmp(lo_address_get_url(co->address()), lo_address_get_url(addr));
+
+ if (res == 0) {
+ delete *x;
+ x = cue_observers.erase (x);
+ } else {
+ ++x;
+ }
+ } else {
+ ++x;
+ }
+ }
+
+ // get a list of Auxes
+ for (uint32_t n = 0; n < s->nstrips; ++n) {
+ boost::shared_ptr<Stripable> stp = s->strips[n];
+ if (stp) {
+ text_message (string_compose ("/cue/name/%1", n+1), stp->name(), addr);
+ if (aux == n+1) {
+ // aux must be at least one
+ // need a signal if aux vanishes
+ stp->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::_cue_set, this, aux, addr), this);
+
+ // make a list of stripables with sends that go to this bus
+ s->sends = cue_get_sorted_stripables(stp, aux, addr);
+ // start cue observer
+ OSCCueObserver* co = new OSCCueObserver (stp, s->sends, addr);
+ cue_observers.push_back (co);
+ }
+
+ }
+ }
+
+ return 0;
+}
+
+int
+OSC::cue_next (lo_message msg)
+{
+ OSCSurface *s = get_surface(get_address (msg));
+ if (s->aux < s->nstrips) {
+ cue_set (s->aux + 1, msg);
+ } else {
+ cue_set (s->nstrips, msg);
+ }
+ return 0;
+}
+
+int
+OSC::cue_previous (lo_message msg)
+{
+ OSCSurface *s = get_surface(get_address (msg));
+ if (s->aux > 1) {
+ cue_set (s->aux - 1, msg);
+ }
+ return 0;
+}
+
+boost::shared_ptr<Send>
+OSC::cue_get_send (uint32_t id, lo_address addr)
+{
+ OSCSurface *s = get_surface(addr);
+ if (id && s->aux > 0 && id <= s->sends.size()) {
+ boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s->sends[id - 1]);
+ boost::shared_ptr<Stripable> aux = get_strip (s->aux, addr);
+ if (r && aux) {
+ return r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
+ }
+ }
+ return boost::shared_ptr<Send>();
+
+}
+
+int
+OSC::cue_aux_fader (float position, lo_message msg)
+{
+ if (!session) return -1;
+
+ OSCSurface *sur = get_surface(get_address (msg));
+ if (sur->cue) {
+ if (sur->aux) {
+ boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
+
+ if (s) {
+ float abs;
+ abs = slider_position_to_gain_with_max (position, 2.0);
+ if (s->gain_control()) {
+ s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
+ return 0;
+ }
+ }
+ }
+ }
+ return cue_float_message ("/cue/fader", 0, get_address (msg));
+}
+
+int
+OSC::cue_aux_mute (float state, lo_message msg)
+{
+ if (!session) return -1;
+
+ OSCSurface *sur = get_surface(get_address (msg));
+ if (sur->cue) {
+ if (sur->aux) {
+ boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
+
+ if (s->mute_control()) {
+ s->mute_control()->set_value (state ? 1.0 : 0.0, PBD::Controllable::NoGroup);
+ return 0;
+ }
+ }
+ }
+ return cue_float_message ("/cue/mute", 0, get_address (msg));
+}
+
+int
+OSC::cue_send_fader (uint32_t id, float val, lo_message msg)
+{
+ if (!session) {
+ return -1;
+ }
+ boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
+ float abs;
+ if (s) {
+ if (s->gain_control()) {
+ abs = slider_position_to_gain_with_max (val, 2.0);
+ s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
+ return 0;
+ }
+ }
+ return cue_float_message (string_compose ("/cue/send/fader/%1", id), 0, get_address (msg));
+}
+
+int
+OSC::cue_send_enable (uint32_t id, float state, lo_message msg)
+{
+ if (!session)
+ return -1;
+ boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
+ if (s) {
+ if (state) {
+ s->activate ();
+ } else {
+ s->deactivate ();
+ }
+ return 0;
+ }
+ return cue_float_message (string_compose ("/cue/send/enable/%1", id), 0, get_address (msg));
+}
+
+int
+OSC::cue_float_message (string path, float val, lo_address addr)
+{
+
+ lo_message reply;
+ reply = lo_message_new ();
+ lo_message_add_float (reply, (float) val);
+
+ lo_send_message (addr, path.c_str(), reply);
+ lo_message_free (reply);
+
+ return 0;
+}
+
+int
+OSC::text_message (string path, string val, lo_address addr)
+{
+
+ lo_message reply;
+ reply = lo_message_new ();
+ lo_message_add_string (reply, val.c_str());
+
+ lo_send_message (addr, path.c_str(), reply);
+ lo_message_free (reply);
+
+ return 0;
+}
+
+
+// we have to have a sorted list of stripables that have sends pointed at our aux
+// we can use the one in osc.cc to get an aux list
+OSC::Sorted
+OSC::cue_get_sorted_stripables(boost::shared_ptr<Stripable> aux, uint32_t id, lo_message msg)
+{
+ Sorted sorted;
+ cueobserver_connections.drop_connections ();
+ // fetch all stripables
+ StripableList stripables;
+
+ session->get_stripables (stripables);
+
+ // Look for stripables that have a send to aux
+ for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
+
+ boost::shared_ptr<Stripable> s = *it;
+ // we only want routes
+ boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
+ if (r) {
+ r->processors_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
+ boost::shared_ptr<Send> snd = r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
+ if (snd) { // test for send to aux
+ sorted.push_back (s);
+ s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::cue_set, this, id, msg), this);
+ }
+ }
+
+
+ }
+ sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
+
+ return sorted;
+}
+
diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h
index 444e3536a4..dbd603d247 100644
--- a/libs/surfaces/osc/osc.h
+++ b/libs/surfaces/osc/osc.h
@@ -37,6 +37,7 @@
#include "pbd/abstract_ui.h"
#include "ardour/types.h"
+#include "ardour/send.h"
#include "control_protocol/control_protocol.h"
#include "pbd/i18n.h"
@@ -45,6 +46,7 @@ class OSCControllable;
class OSCRouteObserver;
class OSCGlobalObserver;
class OSCSelectObserver;
+class OSCCueObserver;
namespace ARDOUR {
class Session;
@@ -95,8 +97,6 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
typedef std::vector<boost::shared_ptr<ARDOUR::Stripable> > Sorted;
Sorted get_sorted_stripables(std::bitset<32> types);
- // cue
- //Sorted cue_get_sorted_stripables(boost::shared_ptr<Route> aux);
// keep a surface's global setup by remote server url
struct OSCSurface {
@@ -112,6 +112,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
bool expand_enable; // use expand instead of select
OSCSelectObserver* sel_obs; // So we can sync select feedback with selected channel
Sorted strips; // list of stripables for this surface
+ bool cue; // is this a cue surface
+ uint32_t aux; // aux index for this cue surface
+ Sorted sends; // list of sends for cue aux
};
/*
* feedback bits:
@@ -215,6 +218,23 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
void transport_speed (lo_message msg);
void record_enabled (lo_message msg);
+ // cue
+ Sorted cue_get_sorted_stripables(boost::shared_ptr<ARDOUR::Stripable> aux, uint32_t id, lo_message msg);
+ int cue_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg);
+ int cue_set (uint32_t aux, lo_message msg);
+ int _cue_set (uint32_t aux, lo_address addr);
+ int cue_next (lo_message msg);
+ int cue_previous (lo_message msg);
+ int cue_send_fader (uint32_t id, float position, lo_message msg);
+ int cue_send_enable (uint32_t id, float state, lo_message msg);
+ int cue_aux_fader (float position, lo_message msg);
+ int cue_aux_mute (float state, lo_message msg);
+ void cue_set_aux (uint32_t aux, lo_message msg);
+ int cue_float_message (std::string, float value, lo_address addr);
+ int text_message (std::string path, std::string val, lo_address addr);
+ boost::shared_ptr<ARDOUR::Send> cue_get_send (uint32_t id, lo_address addr);
+ // end cue
+
#define OSC_DEBUG \
if (_debugmode == All) { \
debugmsg (dgettext(PACKAGE, "OSC"), path, types, argv, argc); \
@@ -575,6 +595,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
bool periodic (void);
sigc::connection periodic_connection;
PBD::ScopedConnectionList session_connections;
+ PBD::ScopedConnectionList cueobserver_connections;
int route_send_fail (std::string path, uint32_t ssid, float val, lo_address addr);
int sel_send_fail (std::string path, uint32_t id, float val, lo_address addr);
@@ -587,6 +608,9 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
typedef std::list<OSCGlobalObserver*> GlobalObservers;
GlobalObservers global_observers;
+ typedef std::list<OSCCueObserver*> CueObservers;
+ CueObservers cue_observers;
+
void debugmsg (const char *prefix, const char *path, const char* types, lo_arg **argv, int argc);
static OSC* _instance;
diff --git a/libs/surfaces/osc/osc_cue_observer.cc b/libs/surfaces/osc/osc_cue_observer.cc
new file mode 100644
index 0000000000..d6c6e38bfb
--- /dev/null
+++ b/libs/surfaces/osc/osc_cue_observer.cc
@@ -0,0 +1,259 @@
+/*
+ Copyright (C) 2009 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "boost/lambda/lambda.hpp"
+
+#include "ardour/track.h"
+#include "ardour/dB.h"
+#include "ardour/meter.h"
+
+#include "osc.h"
+#include "osc_cue_observer.h"
+
+#include "pbd/i18n.h"
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+using namespace ArdourSurface;
+
+OSCCueObserver::OSCCueObserver (boost::shared_ptr<Stripable> s, std::vector<boost::shared_ptr<ARDOUR::Stripable>>& snds, lo_address a)
+ : sends (snds)
+ , _strip (s)
+ , tick_enable (false)
+{
+ std::cout << "entered observer\n";
+ addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a));
+
+ _strip->PropertyChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::name_changed, this, boost::lambda::_1, 0), OSC::instance());
+ name_changed (ARDOUR::Properties::name, 0);
+
+ _strip->mute_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCCueObserver::send_change_message, this, X_("/cue/mute"), 0, _strip->mute_control()), OSC::instance());
+ send_change_message ("/cue/mute", 0, _strip->mute_control());
+
+ gain_timeout.push_back (0);
+ std::cout << "observer past gain timeout for aux\n";
+ _strip->gain_control()->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCCueObserver::send_gain_message, this, 0, _strip->gain_control()), OSC::instance());
+ send_gain_message (0, _strip->gain_control());
+
+ send_init ();
+ std::cout << "observer past send init\n";
+
+ tick_enable = true;
+ tick ();
+}
+
+OSCCueObserver::~OSCCueObserver ()
+{
+
+ strip_connections.drop_connections ();
+ send_end ();
+ // all strip buttons should be off and faders 0 and etc.
+ text_with_id ("/cue/name", 0, " ");
+ clear_strip ("/cue/mute", 0);
+ clear_strip ("/cue/fader", 0);
+ clear_strip ("/cue/signal", 0);
+
+ lo_address_free (addr);
+}
+
+void
+OSCCueObserver::tick ()
+{
+ if (!tick_enable) {
+ return;
+ }
+ float now_meter;
+ if (_strip->peak_meter()) {
+ now_meter = _strip->peak_meter()->meter_level(0, MeterMCP);
+ } else {
+ now_meter = -193;
+ }
+ if (now_meter < -120) now_meter = -193;
+ if (_last_meter != now_meter) {
+ string path = "/cue/signal";
+ lo_message msg = lo_message_new ();
+ float signal;
+ if (now_meter < -40) {
+ signal = 0;
+ } else {
+ signal = 1;
+ }
+ lo_message_add_float (msg, signal);
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+ }
+ _last_meter = now_meter;
+
+ for (uint32_t i = 0; i < gain_timeout.size(); i++) {
+ if (gain_timeout[i]) {
+ if (gain_timeout[i] == 1) {
+ name_changed (ARDOUR::Properties::name, i);
+ }
+ gain_timeout[i]--;
+ }
+ }
+
+}
+
+void
+OSCCueObserver::send_init()
+{
+ for (uint32_t i = 0; i < sends.size(); i++) {
+ boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (sends[i]);
+ boost::shared_ptr<Send> send = r->internal_send_for (boost::dynamic_pointer_cast<Route> (_strip));
+ if (r) {
+ r->processors_changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_restart, this), OSC::instance());
+ }
+
+ if (send) {
+ // send name
+ if (r) {
+ sends[i]->PropertyChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::name_changed, this, boost::lambda::_1, i + 1), OSC::instance());
+ name_changed (ARDOUR::Properties::name, i + 1);
+ }
+
+
+ if (send->gain_control()) {
+ gain_timeout.push_back (0);
+ send->gain_control()->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_gain_message, this, i + 1, send->gain_control()), OSC::instance());
+ send_gain_message (i + 1, send->gain_control());
+ }
+
+ boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (send);
+ proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCCueObserver::send_enabled_message, this, X_("/cue/send_enable"), i + 1, proc->enabled()), OSC::instance());
+ send_enabled_message (X_("/cue/send/enable"), i + 1, proc->enabled());
+ }
+ }
+
+}
+
+void
+OSCCueObserver::send_end ()
+{
+ send_connections.drop_connections ();
+ for (uint32_t i = 1; i <= sends.size(); i++) {
+ clear_strip (string_compose ("/select/send/fader/%1", i), 0);
+ clear_strip (string_compose ("/select/send/enable/%1", i), 0);
+ text_with_id (string_compose("/cue/send/name/%1", i), i, " ");
+ }
+}
+
+void
+OSCCueObserver::send_restart ()
+{
+ tick_enable = false;
+ send_end();
+ send_init();
+ tick_enable = true;
+}
+
+void
+OSCCueObserver::name_changed (const PBD::PropertyChange& what_changed, uint32_t id)
+{
+ if (!what_changed.contains (ARDOUR::Properties::name)) {
+ return;
+ }
+
+ if (!_strip) {
+ return;
+ }
+ if (id) {
+ text_with_id ("/cue/send/name", id, sends[id - 1]->name());
+ } else {
+ text_with_id ("/cue/name", 0, _strip->name());
+ }
+}
+
+void
+OSCCueObserver::send_change_message (string path, uint32_t id, boost::shared_ptr<Controllable> controllable)
+{
+ lo_message msg = lo_message_new ();
+
+ if (id) {
+ path = string_compose("%1/%2", path, id);
+ }
+ float val = controllable->get_value();
+ lo_message_add_float (msg, (float) controllable->internal_to_interface (val));
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+}
+
+void
+OSCCueObserver::text_with_id (string path, uint32_t id, string val)
+{
+ lo_message msg = lo_message_new ();
+ if (id) {
+ path = string_compose("%1/%2", path, id);
+ }
+
+ lo_message_add_string (msg, val.c_str());
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+}
+
+void
+OSCCueObserver::send_gain_message (uint32_t id, boost::shared_ptr<Controllable> controllable)
+{
+ string path = "/cue";
+ if (id) {
+ path = "/cue/send";
+ }
+
+ text_with_id (string_compose ("%1/name", path), id, string_compose ("%1%2%3", std::fixed, std::setprecision(2), accurate_coefficient_to_dB (controllable->get_value())));
+ path = string_compose ("%1/fader", path);
+ if (id) {
+ path = string_compose ("%1/%2", path, id);
+ }
+ lo_message msg = lo_message_new ();
+ lo_message_add_float (msg, gain_to_slider_position (controllable->get_value()));
+ gain_timeout[id] = 8;
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+}
+
+void
+OSCCueObserver::send_enabled_message (std::string path, uint32_t id, bool enabled)
+{
+ lo_message msg = lo_message_new ();
+
+ if (id) {
+ path = string_compose("%1/%2", path, id);
+ }
+ lo_message_add_float (msg, (float) enabled);
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+
+}
+
+void
+OSCCueObserver::clear_strip (string path, float val)
+{
+ lo_message msg = lo_message_new ();
+ lo_message_add_float (msg, val);
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+
+}
+
diff --git a/libs/surfaces/osc/osc_cue_observer.h b/libs/surfaces/osc/osc_cue_observer.h
new file mode 100644
index 0000000000..4ade6c0e91
--- /dev/null
+++ b/libs/surfaces/osc/osc_cue_observer.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2009 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __osc_osccueobserver_h__
+#define __osc_osccueobserver_h__
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <sigc++/sigc++.h>
+#include <lo/lo.h>
+
+#include "pbd/controllable.h"
+#include "pbd/stateful.h"
+#include "ardour/types.h"
+
+class OSCCueObserver
+{
+
+ public:
+ OSCCueObserver (boost::shared_ptr<ARDOUR::Stripable>, std::vector<boost::shared_ptr<ARDOUR::Stripable>>& sends, lo_address addr);
+ ~OSCCueObserver ();
+
+ boost::shared_ptr<ARDOUR::Stripable> strip () const { return _strip; }
+ lo_address address() const { return addr; };
+ void tick (void);
+ typedef std::vector<boost::shared_ptr<ARDOUR::Stripable> > Sorted;
+ Sorted sends;
+
+ private:
+
+ boost::shared_ptr<ARDOUR::Stripable> _strip;
+
+ PBD::ScopedConnectionList strip_connections;
+ PBD::ScopedConnectionList send_connections;
+
+ lo_address addr;
+ std::string path;
+ float _last_meter;
+ std::vector<uint32_t> gain_timeout;
+ bool tick_enable;
+
+ void name_changed (const PBD::PropertyChange& what_changed, uint32_t id);
+ void send_change_message (std::string path, uint32_t id, boost::shared_ptr<PBD::Controllable> controllable);
+ void text_with_id (std::string path, uint32_t id, std::string val);
+ void send_gain_message (uint32_t id, boost::shared_ptr<PBD::Controllable> controllable);
+ void send_enabled_message (std::string path, uint32_t id, bool enabled);
+ void clear_strip (std::string path, float val);
+ void send_init (void);
+ void send_end (void);
+ void send_restart (void);
+};
+
+#endif /* __osc_osccueobserver_h__ */
diff --git a/libs/surfaces/osc/osc_select_observer.cc b/libs/surfaces/osc/osc_select_observer.cc
index ab768bc814..b11d277947 100644
--- a/libs/surfaces/osc/osc_select_observer.cc
+++ b/libs/surfaces/osc/osc_select_observer.cc
@@ -243,14 +243,14 @@ OSCSelectObserver::send_init()
do {
sends = false;
if (_strip->send_level_controllable (nsends)) {
- _strip->send_level_controllable(nsends)->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_gain, this, nsends, _strip->send_level_controllable(nsends)), OSC::instance());
+ _strip->send_level_controllable(nsends)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_gain, this, nsends, _strip->send_level_controllable(nsends)), OSC::instance());
send_timeout.push_back (0);
send_gain (nsends, _strip->send_level_controllable(nsends));
sends = true;
}
if (_strip->send_enable_controllable (nsends)) {
- _strip->send_enable_controllable(nsends)->Changed.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::enable_message_with_id, this, X_("/select/send_enable"), nsends + 1, _strip->send_enable_controllable(nsends)), OSC::instance());
+ _strip->send_enable_controllable(nsends)->Changed.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::enable_message_with_id, this, X_("/select/send_enable"), nsends + 1, _strip->send_enable_controllable(nsends)), OSC::instance());
enable_message_with_id ("/select/send_enable", nsends + 1, _strip->send_enable_controllable(nsends));
sends = true;
} else if (sends) {
@@ -262,7 +262,7 @@ OSCSelectObserver::send_init()
boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(nsends));
if (snd) {
boost::shared_ptr<Processor> proc = boost::dynamic_pointer_cast<Processor> (snd);
- proc->ActiveChanged.connect (strip_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), nsends + 1, proc), OSC::instance());
+ proc->ActiveChanged.connect (send_connections, MISSING_INVALIDATOR, boost::bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), nsends + 1, proc), OSC::instance());
clear_strip_with_id ("/select/send_enable", nsends + 1, proc->enabled());
}
}
diff --git a/libs/surfaces/osc/wscript b/libs/surfaces/osc/wscript
index 6f2bbfa0a5..4d0dba6750 100644
--- a/libs/surfaces/osc/wscript
+++ b/libs/surfaces/osc/wscript
@@ -20,6 +20,7 @@ def build(bld):
osc_route_observer.cc
osc_select_observer.cc
osc_global_observer.cc
+ osc_cue_observer.cc
interface.cc
osc_gui.cc
'''