enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / surfaces / osc / osc_global_observer.cc
index 85a758e4dd4bbb8857b8654314e3b08cdde39082..cd7bf0866d55bef5075c33e0702389ecdfefde07 100644 (file)
@@ -26,7 +26,7 @@
 #include "osc.h"
 #include "osc_global_observer.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace PBD;
@@ -37,85 +37,91 @@ OSCGlobalObserver::OSCGlobalObserver (Session& s, lo_address a, uint32_t gm, std
        : gainmode (gm)
        ,feedback (fb)
 {
+       if (feedback[4]) {
+               addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a));
+               session = &s;
+               _last_frame = -1;
 
-       addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a));
-       session = &s;
-       _last_frame = -1;
-       // connect to all the things we want to send feed back from
+               // connect to all the things we want to send feed back from
 
-       /*
-        *      Master (todo)
-        *              Pan width
-        */
+               /*
+               *       Master (todo)
+               *               Pan width
+               */
 
-       // Master channel first
-       boost::shared_ptr<Stripable> strip = session->master_out();
+               // Master channel first
+               boost::shared_ptr<Stripable> strip = session->master_out();
 
-       boost::shared_ptr<Controllable> mute_controllable = boost::dynamic_pointer_cast<Controllable>(strip->mute_control());
-       mute_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/mute"), strip->mute_control()), OSC::instance());
-       send_change_message ("/master/mute", strip->mute_control());
+               boost::shared_ptr<Controllable> mute_controllable = boost::dynamic_pointer_cast<Controllable>(strip->mute_control());
+               mute_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/mute"), strip->mute_control()), OSC::instance());
+               send_change_message ("/master/mute", strip->mute_control());
 
-       boost::shared_ptr<Controllable> trim_controllable = boost::dynamic_pointer_cast<Controllable>(strip->trim_control());
+               boost::shared_ptr<Controllable> trim_controllable = boost::dynamic_pointer_cast<Controllable>(strip->trim_control());
                trim_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_trim_message, this, X_("/master/trimdB"), strip->trim_control()), OSC::instance());
                send_trim_message ("/master/trimdB", strip->trim_control());
 
-       boost::shared_ptr<Controllable> pan_controllable = boost::dynamic_pointer_cast<Controllable>(strip->pan_azimuth_control());
+               boost::shared_ptr<Controllable> pan_controllable = boost::dynamic_pointer_cast<Controllable>(strip->pan_azimuth_control());
                pan_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/pan_stereo_position"), strip->pan_azimuth_control()), OSC::instance());
                send_change_message ("/master/pan_stereo_position", strip->pan_azimuth_control());
 
-       boost::shared_ptr<Controllable> gain_controllable = boost::dynamic_pointer_cast<Controllable>(strip->gain_control());
-       if (gainmode) {
-               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/fader"), strip->gain_control()), OSC::instance());
-               send_gain_message ("/master/fader", strip->gain_control());
-       } else {
-               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/gain"), strip->gain_control()), OSC::instance());
-               send_gain_message ("/master/gain", strip->gain_control());
-       }
+               boost::shared_ptr<Controllable> gain_controllable = boost::dynamic_pointer_cast<Controllable>(strip->gain_control());
+               if (gainmode) {
+                       gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/fader"), strip->gain_control()), OSC::instance());
+                       send_gain_message ("/master/fader", strip->gain_control());
+               } else {
+                       gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/gain"), strip->gain_control()), OSC::instance());
+                       send_gain_message ("/master/gain", strip->gain_control());
+               }
 
-       // monitor stuff next
-       /* 
-        *      Monitor (todo)
-        *              Mute
-        *              Dim
-        *              Mono
-        *              Rude Solo
-        *              etc.
-        */
-       strip = session->monitor_out();
-
-       // Hmm, it seems the monitor mute is not at route->mute_control()
-       /*boost::shared_ptr<Controllable> mute_controllable2 = boost::dynamic_pointer_cast<Controllable>(strip->mute_control());
-       //mute_controllable = boost::dynamic_pointer_cast<Controllable>(r2->mute_control());
-       mute_controllable2->Changed.connect (monitor_mute_connection, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/monitor/mute"), strip->mute_control()), OSC::instance());
-       send_change_message ("/monitor/mute", strip->mute_control());
-       */
-       gain_controllable = boost::dynamic_pointer_cast<Controllable>(strip->gain_control());
-       if (gainmode) {
-               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/fader"), strip->gain_control()), OSC::instance());
-               send_gain_message ("/monitor/fader", strip->gain_control());
-       } else {
-               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/gain"), strip->gain_control()), OSC::instance());
-               send_gain_message ("/monitor/gain", strip->gain_control());
-       }
+               // monitor stuff next
+               /*
+               *       Monitor (todo)
+               *               Mute
+               *               Dim
+               *               Mono
+               *               Rude Solo
+               *               etc.
+               */
+               strip = session->monitor_out();
+               if (strip) {
+
+                       // Hmm, it seems the monitor mute is not at route->mute_control()
+                       /*boost::shared_ptr<Controllable> mute_controllable2 = boost::dynamic_pointer_cast<Controllable>(strip->mute_control());
+                       //mute_controllable = boost::dynamic_pointer_cast<Controllable>(r2->mute_control());
+                       mute_controllable2->Changed.connect (monitor_mute_connection, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/monitor/mute"), strip->mute_control()), OSC::instance());
+                       send_change_message ("/monitor/mute", strip->mute_control());
+                       */
+                       gain_controllable = boost::dynamic_pointer_cast<Controllable>(strip->gain_control());
+                       if (gainmode) {
+                               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/fader"), strip->gain_control()), OSC::instance());
+                               send_gain_message ("/monitor/fader", strip->gain_control());
+                       } else {
+                               gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/gain"), strip->gain_control()), OSC::instance());
+                               send_gain_message ("/monitor/gain", strip->gain_control());
+                       }
+               }
 
-       /*
-        *      Transport (todo)
-        *              punchin/out
-        */
-        //Transport feedback
-       session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance());
-       send_transport_state_changed ();
-       session->TransportLooped.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance());
-       session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_record_state_changed, this), OSC::instance());
-       send_record_state_changed ();
-
-       // session feedback
-       session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_session_saved, this, _1), OSC::instance());
-       send_session_saved (session->snap_name());
-
-       /*
-        *      Maybe (many) more
-        */
+               /*
+               *       Transport (todo)
+               *               punchin/out
+               */
+               //Transport feedback
+               session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance());
+               send_transport_state_changed ();
+               session->TransportLooped.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance());
+               session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_record_state_changed, this), OSC::instance());
+               send_record_state_changed ();
+
+               // session feedback
+               session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_session_saved, this, _1), OSC::instance());
+               send_session_saved (session->snap_name());
+               session->SoloActive.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::solo_active, this, _1), OSC::instance());
+               solo_active (session->soloing() || session->listening());
+
+               /*
+               *       Maybe (many) more
+               */
+       }
 }
 
 OSCGlobalObserver::~OSCGlobalObserver ()
@@ -143,12 +149,12 @@ OSCGlobalObserver::tick ()
                        os << setw(2) << setfill('0') << timecode.minutes;
                        os << ':';
                        os << setw(2) << setfill('0') << timecode.seconds;
-                       os << '.';
+                       os << ':';
                        os << setw(2) << setfill('0') << timecode.frames;
 
                        lo_message msg = lo_message_new ();
                        lo_message_add_string (msg, os.str().c_str());
-                       lo_send_message (addr, "/timecode", msg);
+                       lo_send_message (addr, "/position/smpte", msg);
                        lo_message_free (msg);
                }
                if (feedback[5]) { // Bar beat enabled
@@ -167,7 +173,40 @@ OSCGlobalObserver::tick ()
 
                        lo_message msg = lo_message_new ();
                        lo_message_add_string (msg, os.str().c_str());
-                       lo_send_message (addr, "/bar_beat", msg);
+                       lo_send_message (addr, "/position/bbt", msg);
+                       lo_message_free (msg);
+               }
+               if (feedback[11]) { // minutes/seconds enabled
+                       framepos_t left = now_frame;
+                       int hrs = (int) floor (left / (session->frame_rate() * 60.0f * 60.0f));
+                       left -= (framecnt_t) floor (hrs * session->frame_rate() * 60.0f * 60.0f);
+                       int mins = (int) floor (left / (session->frame_rate() * 60.0f));
+                       left -= (framecnt_t) floor (mins * session->frame_rate() * 60.0f);
+                       int secs = (int) floor (left / (float) session->frame_rate());
+                       left -= (framecnt_t) floor ((double)(secs * session->frame_rate()));
+                       int millisecs = floor (left * 1000.0 / (float) session->frame_rate());
+
+                       // Min/sec mode: Hours/Minutes/Seconds/msec
+                       ostringstream os;
+                       os << setw(2) << setfill('0') << hrs;
+                       os << ':';
+                       os << setw(2) << setfill('0') << mins;
+                       os << ':';
+                       os << setw(2) << setfill('0') << secs;
+                       os << '.';
+                       os << setw(3) << setfill('0') << millisecs;
+
+                       lo_message msg = lo_message_new ();
+                       lo_message_add_string (msg, os.str().c_str());
+                       lo_send_message (addr, "/position/time", msg);
+                       lo_message_free (msg);
+               }
+               if (feedback[10]) { // samples
+                       ostringstream os;
+                       os << now_frame;
+                       lo_message msg = lo_message_new ();
+                       lo_message_add_string (msg, os.str().c_str());
+                       lo_send_message (addr, "/position/samples", msg);
                        lo_message_free (msg);
                }
                _last_frame = now_frame;
@@ -335,3 +374,11 @@ OSCGlobalObserver::send_session_saved (std::string name)
 
 }
 
+void
+OSCGlobalObserver::solo_active (bool active)
+{
+       lo_message msg = lo_message_new ();
+       lo_message_add_float (msg, (float) active);
+       lo_send_message (addr, "/cancel_all_solos", msg);
+       lo_message_free (msg);
+}