summaryrefslogtreecommitdiff
path: root/libs/surfaces
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
commit70b939da4f9d4097160e32f2373a7a5ff8f4957f (patch)
tree5917e5847c75e441c9df550d5101352d18e8286f /libs/surfaces
parentee62ee07d39f51ba1b70f390dc2158c57f54a572 (diff)
first pass at internal sends. this is a very tentative work in progress, and it is possible that major changes may follow in the near future. it is certainly not complete, but the fundamental changes to Port/Buffer operation merit a commit at this point
git-svn-id: svn://localhost/ardour2/branches/3.0@4464 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces')
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc8
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h2
-rw-r--r--libs/surfaces/osc/osc.cc206
-rw-r--r--libs/surfaces/osc/osc.h46
-rw-r--r--libs/surfaces/osc/osc_controllable.cc48
-rw-r--r--libs/surfaces/osc/osc_controllable.h38
6 files changed, 188 insertions, 160 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index b29c26b0d3..18dbd28c0e 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -218,7 +218,7 @@ MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
Sorted sorted;
// fetch all routes
- boost::shared_ptr<Session::RouteList> routes = session->get_routes();
+ boost::shared_ptr<RouteList> routes = session->get_routes();
set<uint32_t> remote_ids;
// routes with remote_id 0 should never be added
@@ -227,7 +227,7 @@ MackieControlProtocol::Sorted MackieControlProtocol::get_sorted_routes()
// sort in remote_id order, and exclude master, control and hidden routes
// and any routes that are already set.
- for ( Session::RouteList::iterator it = routes->begin(); it != routes->end(); ++it )
+ for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it )
{
Route & route = **it;
if (
@@ -1460,7 +1460,7 @@ void MackieControlProtocol::notify_parameter_changed( const char * name_str )
}
// RouteList is the set of routes that have just been added
-void MackieControlProtocol::notify_route_added( ARDOUR::Session::RouteList & rl )
+void MackieControlProtocol::notify_route_added( ARDOUR::RouteList & rl )
{
// currently assigned banks are less than the full set of
// strips, so activate the new strip now.
@@ -1471,7 +1471,7 @@ void MackieControlProtocol::notify_route_added( ARDOUR::Session::RouteList & rl
// otherwise route added, but current bank needs no updating
// make sure remote id changes in the new route are handled
- typedef ARDOUR::Session::RouteList ARS;
+ typedef ARDOUR::RouteList ARS;
for ( ARS::iterator it = rl.begin(); it != rl.end(); ++it )
{
connections_back = (*it)->RemoteControlIDChanged.connect( ( mem_fun (*this, &MackieControlProtocol::notify_remote_id_changed) ) );
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 7d726e70ee..456fb49485 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -102,7 +102,7 @@ class MackieControlProtocol
/// Signal handler from Panner::Change
void notify_panner_changed( Mackie::RouteSignal *, bool force_update = true );
/// Signal handler for new routes added
- void notify_route_added( ARDOUR::Session::RouteList & );
+ void notify_route_added( ARDOUR::RouteList & );
/// Signal handler for Route::active_changed
void notify_active_changed( Mackie::RouteSignal * );
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc
index 4503993360..d8ff311486 100644
--- a/libs/surfaces/osc/osc.cc
+++ b/libs/surfaces/osc/osc.cc
@@ -43,6 +43,7 @@
#include <ardour/filesystem_paths.h>
#include "osc.h"
+#include "osc_controllable.h"
#include "i18n.h"
using namespace ARDOUR;
@@ -74,7 +75,7 @@ OSC::OSC (Session& s, uint32_t port)
/* catch up with existing routes */
- boost::shared_ptr<Session::RouteList> rl = session->get_routes ();
+ boost::shared_ptr<RouteList> rl = session->get_routes ();
route_added (*(rl.get()));
// session->RouteAdded.connect (mem_fun (*this, &OSC::route_added));
@@ -562,29 +563,23 @@ OSC::catchall (const char *path, const char *types, lo_arg **argv, int argc, lo_
lo_message reply = lo_message_new ();
- if (argc > 0) {
- int id = argv[0]->i;
- boost::shared_ptr<Route> r = session->route_by_remote_id (id);
-
- if (!r) {
- lo_message_add_string (reply, "not found");
- cerr << "no such route\n";
- } else {
-
- ListenerPair listener;
+ if (argc <= 0) {
+ lo_message_add_string (reply, "syntax error");
+ } else {
+ for (int n = 0; n < argc; ++n) {
- listener.first = r.get();
- listener.second = lo_message_get_source (msg);
-
- cerr << "add listener\n";
+ boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
- listen_to_route (listener);
-
- lo_message_add_string (reply, "0");
+ if (!r) {
+ lo_message_add_string (reply, "not found");
+ cerr << "no such route\n";
+ break;
+ } else {
+ cerr << "add listener\n";
+ listen_to_route (r, lo_message_get_source (msg));
+ lo_message_add_int32 (reply, argv[n]->i);
+ }
}
-
- } else {
- lo_message_add_string (reply, "syntax error");
}
lo_send_message (lo_message_get_source (msg), "#reply", reply);
@@ -592,17 +587,12 @@ OSC::catchall (const char *path, const char *types, lo_arg **argv, int argc, lo_
} else if (strcmp (path, "/routes/ignore") == 0) {
- if (argc > 0) {
- int id = argv[0]->i;
- boost::shared_ptr<Route> r = session->route_by_remote_id (id);
+ for (int n = 0; n < argc; ++n) {
+
+ boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
if (r) {
- ListenerPair listener;
-
- listener.first = r.get();
- listener.second = lo_message_get_source (msg);
-
- drop_listener_pair (listener);
+ end_listen (r, lo_message_get_source (msg));
}
}
}
@@ -611,55 +601,86 @@ OSC::catchall (const char *path, const char *types, lo_arg **argv, int argc, lo_
}
void
-OSC::route_added (Session::RouteList& rl)
+OSC::route_added (RouteList& rl)
{
}
void
-OSC::listen_to_route (const ListenerPair& lp)
+OSC::listen_to_route (boost::shared_ptr<Route> route, lo_address addr)
{
- Listeners::iterator x;
+ Controllables::iterator x;
bool route_exists = false;
cerr << "listen to route\n";
- /* check existing listener pairs to avoid duplicate listens */
-
- for (x = listeners.begin(); x != listeners.end(); ++x) {
-
- if ((*x)->route == lp.first) {
- route_exists = true;
+ /* avoid duplicate listens */
+
+ for (x = controllables.begin(); x != controllables.end(); ++x) {
+
+ OSCRouteControllable* rc;
- if ((*x)->addr == lp.second ) {
- return;
+ if ((rc = dynamic_cast<OSCRouteControllable*>(*x)) != 0) {
+
+ if (rc->route() == route) {
+ route_exists = true;
+
+ /* XXX NEED lo_address_equal() */
+
+ if (rc->address() == addr) {
+ return;
+ }
}
}
}
- Listener* l = new Listener (lp.first, lp.second);
-
cerr << "listener binding to signals\n";
- l->connections.push_back (lp.first->solo_changed.connect (bind (mem_fun (*this, &OSC::route_changed), RouteSolo, lp.first, lp.second)));
- l->connections.push_back (lp.first->mute_changed.connect (bind (mem_fun (*this, &OSC::route_changed), RouteMute, lp.first, lp.second)));
- l->connections.push_back (lp.first->gain_control()->Changed.connect (bind (mem_fun (*this, &OSC::route_changed_deux), RouteGain, lp.first, lp.second)));
+ OSCControllable* c;
+ string path;
+
+ path = X_("/route/solo");
+ c = new OSCRouteControllable (addr, path, route->solo_control(), route);
+ controllables.push_back (c);
+
+ path = X_("/route/mute");
+ c = new OSCRouteControllable (addr, path, route->mute_control(), route);
+ controllables.push_back (c);
+
+ path = X_("/route/gain");
+ c = new OSCRouteControllable (addr, path, route->gain_control(), route);
+ controllables.push_back (c);
+
+ cerr << "Now have " << controllables.size() << " controllables\n";
+
+ /* if there is no existing controllable related to this route, make sure we clean up
+ if it is ever deleted.
+ */
if (!route_exists) {
- l->route->GoingAway.connect (bind (mem_fun (*this, &OSC::drop_listeners_by_route), l->route));
+ route->GoingAway.connect (bind (mem_fun (*this, &OSC::drop_route), boost::weak_ptr<Route> (route)));
}
-
- listeners.push_back (l);
}
void
-OSC::drop_listeners_by_route (Route* r)
+OSC::drop_route (boost::weak_ptr<Route> wr)
{
- Listeners::iterator x;
+ boost::shared_ptr<Route> r = wr.lock ();
+
+ if (!r) {
+ return;
+ }
+
+ for (Controllables::iterator x = controllables.begin(); x != controllables.end();) {
- for (x = listeners.begin(); x != listeners.end();) {
- if ((*x)->route == r) {
- delete *x;
- x = listeners.erase (x);
+ OSCRouteControllable* rc;
+
+ if ((rc = dynamic_cast<OSCRouteControllable*>(*x)) != 0) {
+ if (rc->route() == r) {
+ delete *x;
+ x = controllables.erase (x);
+ } else {
+ ++x;
+ }
} else {
++x;
}
@@ -667,14 +688,22 @@ OSC::drop_listeners_by_route (Route* r)
}
void
-OSC::drop_listener_pair (const ListenerPair& lp)
+OSC::end_listen (boost::shared_ptr<Route> r, lo_address addr)
{
- Listeners::iterator x;
+ Controllables::iterator x;
- for (x = listeners.begin(); x != listeners.end(); ++x) {
- if ((*x)->route == lp.first && (*x)->addr == lp.second) {
- listeners.erase (x);
- return;
+ for (x = controllables.begin(); x != controllables.end(); ++x) {
+
+ OSCRouteControllable* rc;
+
+ if ((rc = dynamic_cast<OSCRouteControllable*>(*x)) != 0) {
+
+ /* XXX NEED lo_address_equal () */
+
+ if (rc->route() == r && rc->address() == addr) {
+ controllables.erase (x);
+ return;
+ }
}
}
}
@@ -692,61 +721,6 @@ OSC::session_exported( std::string path, std::string name ) {
lo_send( listener, "/session/exported", "ss", path.c_str(), name.c_str() );
}
-void
-OSC::set_send_route_changes (bool yn)
-{
- _send_route_changes = yn;
-}
-
-void
-OSC::route_changed (void* src, RouteChangeType what, Route* r, lo_address addr)
-{
- route_changed_deux (what, r, addr);
-}
-
-void
-OSC::route_changed_deux (RouteChangeType what, Route* r, lo_address addr)
-{
- if (!_send_route_changes) {
- return;
- }
-
- string prefix = _namespace_root;
- int ret;
-
- switch (what) {
-
- case OSC::RouteSolo:
- prefix += "/changed/route/solo";
- ret = lo_send (addr, prefix.c_str(), "ii", r->remote_control_id(), (int) r->soloed());
- break;
-
- case OSC::RouteMute:
- prefix += "/changed/route/mute";
- ret = lo_send (addr, prefix.c_str(), "ii", r->remote_control_id(), (int) r->muted());
- break;
-
- case OSC::RouteGain:
- prefix += "/changed/route/gain";
- ret = lo_send (addr, prefix.c_str(), "if", r->remote_control_id(), r->effective_gain());
-
- default:
- error << "OSC: unhandled route change\n";
- return;
- }
-
- if (ret < 0) {
- ListenerPair lp;
-
- lp.first = r;
- lp.second = addr;
-
- cerr << "Error sending to listener ... dropping\n";
- drop_listener_pair (lp);
- }
-
-}
-
// end "Application Hook" Handlers //
/* path callbacks */
diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h
index b2417474fc..4eebc906bb 100644
--- a/libs/surfaces/osc/osc.h
+++ b/libs/surfaces/osc/osc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Paul Davis
+ * Copyright (C) 2006-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
@@ -25,6 +25,8 @@
#include <sys/time.h>
#include <pthread.h>
+#include <boost/shared_ptr.hpp>
+
#include <lo/lo.h>
#include <sigc++/sigc++.h>
@@ -33,15 +35,17 @@
#include <ardour/session.h>
#include <control_protocol/control_protocol.h>
-namespace ARDOUR {
+class OSCControllable;
+namespace ARDOUR {
class Session;
class Route;
+}
-class OSC : public ControlProtocol
+class OSC : public ARDOUR::ControlProtocol
{
public:
- OSC (Session&, uint32_t port);
+ OSC (ARDOUR::Session&, uint32_t port);
virtual ~OSC();
XMLNode& get_state ();
@@ -53,8 +57,6 @@ class OSC : public ControlProtocol
bool get_feedback () const;
void set_namespace_root (std::string);
- bool send_route_changes () const { return _send_route_changes; }
- void set_send_route_changes (bool yn);
int start ();
int stop ();
@@ -82,21 +84,12 @@ class OSC : public ControlProtocol
void register_callbacks ();
- void route_added (ARDOUR::Session::RouteList&);
+ void route_added (ARDOUR::RouteList&);
// Handlers for "Application Hook" signals
void session_loaded (ARDOUR::Session&);
void session_exported (std::string, std::string);
- enum RouteChangeType {
- RouteSolo,
- RouteMute,
- RouteGain
- };
-
- void route_changed (void* ignored, RouteChangeType, ARDOUR::Route*, lo_address);
- void route_changed_deux (RouteChangeType, ARDOUR::Route*, lo_address);
-
// end "Application Hook" handles
std::string get_server_url ();
@@ -173,24 +166,13 @@ class OSC : public ControlProtocol
int route_set_gain_abs (int rid, float level);
int route_set_gain_dB (int rid, float dB);
- struct Listener {
- Route* route;
- lo_address addr;
- std::vector<sigc::connection> connections;
-
- Listener (Route* r, lo_address a) : route (r), addr (a) {}
- };
-
- typedef std::pair<Route*, lo_address> ListenerPair;
- typedef std::list<Listener*> Listeners;
+ void listen_to_route (boost::shared_ptr<ARDOUR::Route>, lo_address);
+ void end_listen (boost::shared_ptr<ARDOUR::Route>, lo_address);
+ void drop_route (boost::weak_ptr<ARDOUR::Route>);
- Listeners listeners;
+ typedef std::list<OSCControllable*> Controllables;
- void listen_to_route (const ListenerPair&);
- void drop_listener_pair (const ListenerPair&);
- void drop_listeners_by_route (Route*);
+ Controllables controllables;
};
-}
-
#endif // ardour_osc_h
diff --git a/libs/surfaces/osc/osc_controllable.cc b/libs/surfaces/osc/osc_controllable.cc
index 12959652b8..66e70c7e7a 100644
--- a/libs/surfaces/osc/osc_controllable.cc
+++ b/libs/surfaces/osc/osc_controllable.cc
@@ -22,16 +22,20 @@
#include <pbd/error.h>
#include <pbd/xml++.h>
+#include <ardour/route.h>
+
#include "osc_controllable.h"
using namespace sigc;
using namespace PBD;
using namespace ARDOUR;
-OSCControllable::OSCControllable (lo_address a, Controllable& c)
+OSCControllable::OSCControllable (lo_address a, const string& p, boost::shared_ptr<Controllable> c)
: controllable (c)
, addr (a)
+ , path (p)
{
+ c->Changed.connect (mem_fun (*this, &OSCControllable::send_change));
}
OSCControllable::~OSCControllable ()
@@ -42,7 +46,7 @@ OSCControllable::~OSCControllable ()
XMLNode&
OSCControllable::get_state ()
{
- XMLNode& root (controllable.get_state());
+ XMLNode& root (controllable->get_state());
return root;
}
@@ -52,3 +56,43 @@ OSCControllable::set_state (const XMLNode& node)
return 0;
}
+void
+OSCControllable::send_change ()
+{
+ lo_message msg = lo_message_new ();
+
+ lo_message_add_float (msg, (float) controllable->get_value());
+
+ /* XXX thread issues */
+
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+}
+
+/*------------------------------------------------------------*/
+
+OSCRouteControllable::OSCRouteControllable (lo_address a, const string& p,
+ boost::shared_ptr<Controllable> c, boost::shared_ptr<Route> r)
+ : OSCControllable (a, p, c)
+ , _route (r)
+{
+}
+
+OSCRouteControllable::~OSCRouteControllable ()
+{
+}
+
+void
+OSCRouteControllable::send_change ()
+{
+ lo_message msg = lo_message_new ();
+
+ lo_message_add_int32 (msg, _route->remote_control_id());
+ lo_message_add_float (msg, (float) controllable->get_value());
+
+ /* XXX thread issues */
+
+ cerr << "ORC: send " << path << " = " << controllable->get_value() << endl;
+ lo_send_message (addr, path.c_str(), msg);
+ lo_message_free (msg);
+}
diff --git a/libs/surfaces/osc/osc_controllable.h b/libs/surfaces/osc/osc_controllable.h
index 48183138ec..61261a8f1c 100644
--- a/libs/surfaces/osc/osc_controllable.h
+++ b/libs/surfaces/osc/osc_controllable.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1998-2006 Paul Davis
+ 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
@@ -21,7 +21,7 @@
#define __osc_osccontrollable_h__
#include <string>
-
+#include <boost/shared_ptr.hpp>
#include <sigc++/sigc++.h>
#include <lo/lo.h>
@@ -29,18 +29,46 @@
#include <pbd/stateful.h>
#include <ardour/types.h>
+namespace ARDOUR {
+
+class Route;
+
+}
+
class OSCControllable : public PBD::Stateful
{
public:
- OSCControllable (lo_address addr, PBD::Controllable&);
+ OSCControllable (lo_address addr, const string& path, boost::shared_ptr<PBD::Controllable>);
virtual ~OSCControllable ();
+ lo_address address() const { return addr; }
+
XMLNode& get_state ();
int set_state (const XMLNode& node);
- private:
- PBD::Controllable& controllable;
+ protected:
+ boost::shared_ptr<PBD::Controllable> controllable;
lo_address addr;
+ string path;
+
+ virtual void send_change ();
+};
+
+class OSCRouteControllable : public OSCControllable
+{
+
+ public:
+ OSCRouteControllable (lo_address addr, const string& path,
+ boost::shared_ptr<PBD::Controllable>,
+ boost::shared_ptr<ARDOUR::Route>);
+ ~OSCRouteControllable ();
+
+ boost::shared_ptr<ARDOUR::Route> route() const { return _route; }
+
+ private:
+ boost::shared_ptr<ARDOUR::Route> _route;
+
+ void send_change ();
};
#endif /* __osc_osccontrollable_h__ */